Rollup merge of #69349 - spastorino:mir-not-an-experiment, r=Dylan-DPC
MIR is not an experiment anymore
At least I hope is not :stuck_out_tongue_closed_eyes:
r? @oli-obk
diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs
index b88ca8a..f8f987e 100644
--- a/src/liballoc/collections/linked_list.rs
+++ b/src/liballoc/collections/linked_list.rs
@@ -878,6 +878,52 @@
unsafe { self.split_off_after_node(split_node, at) }
}
+ /// Removes the element at the given index and returns it.
+ ///
+ /// This operation should compute in O(n) time.
+ ///
+ /// # Panics
+ /// Panics if at >= len
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(linked_list_remove)]
+ /// use std::collections::LinkedList;
+ ///
+ /// let mut d = LinkedList::new();
+ ///
+ /// d.push_front(1);
+ /// d.push_front(2);
+ /// d.push_front(3);
+ ///
+ /// assert_eq!(d.remove(1), 2);
+ /// assert_eq!(d.remove(0), 3);
+ /// assert_eq!(d.remove(0), 1);
+ /// ```
+ #[unstable(feature = "linked_list_remove", issue = "69210")]
+ pub fn remove(&mut self, at: usize) -> T {
+ let len = self.len();
+ assert!(at < len, "Cannot remove at an index outside of the list bounds");
+
+ // Below, we iterate towards the node at the given index, either from
+ // the start or the end, depending on which would be faster.
+ let offset_from_end = len - at - 1;
+ if at <= offset_from_end {
+ let mut cursor = self.cursor_front_mut();
+ for _ in 0..at {
+ cursor.move_next();
+ }
+ cursor.remove_current().unwrap()
+ } else {
+ let mut cursor = self.cursor_back_mut();
+ for _ in 0..offset_from_end {
+ cursor.move_prev();
+ }
+ cursor.remove_current().unwrap()
+ }
+ }
+
/// Creates an iterator which uses a closure to determine if an element should be removed.
///
/// If the closure returns true, then the element is removed and yielded.
diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs
index c1ae67a..ea75f89 100644
--- a/src/liballoc/tests/lib.rs
+++ b/src/liballoc/tests/lib.rs
@@ -12,6 +12,7 @@
#![feature(binary_heap_into_iter_sorted)]
#![feature(binary_heap_drain_sorted)]
#![feature(vec_remove_item)]
+#![feature(split_inclusive)]
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
diff --git a/src/liballoc/tests/slice.rs b/src/liballoc/tests/slice.rs
index 51ddb5e..3d6b4bf 100644
--- a/src/liballoc/tests/slice.rs
+++ b/src/liballoc/tests/slice.rs
@@ -852,6 +852,86 @@
}
#[test]
+fn test_splitator_inclusive() {
+ let xs = &[1, 2, 3, 4, 5];
+
+ let splits: &[&[_]] = &[&[1, 2], &[3, 4], &[5]];
+ assert_eq!(xs.split_inclusive(|x| *x % 2 == 0).collect::<Vec<_>>(), splits);
+ let splits: &[&[_]] = &[&[1], &[2, 3, 4, 5]];
+ assert_eq!(xs.split_inclusive(|x| *x == 1).collect::<Vec<_>>(), splits);
+ let splits: &[&[_]] = &[&[1, 2, 3, 4, 5]];
+ assert_eq!(xs.split_inclusive(|x| *x == 5).collect::<Vec<_>>(), splits);
+ let splits: &[&[_]] = &[&[1, 2, 3, 4, 5]];
+ assert_eq!(xs.split_inclusive(|x| *x == 10).collect::<Vec<_>>(), splits);
+ let splits: &[&[_]] = &[&[1], &[2], &[3], &[4], &[5]];
+ assert_eq!(xs.split_inclusive(|_| true).collect::<Vec<&[i32]>>(), splits);
+
+ let xs: &[i32] = &[];
+ let splits: &[&[i32]] = &[&[]];
+ assert_eq!(xs.split_inclusive(|x| *x == 5).collect::<Vec<&[i32]>>(), splits);
+}
+
+#[test]
+fn test_splitator_inclusive_reverse() {
+ let xs = &[1, 2, 3, 4, 5];
+
+ let splits: &[&[_]] = &[&[5], &[3, 4], &[1, 2]];
+ assert_eq!(xs.split_inclusive(|x| *x % 2 == 0).rev().collect::<Vec<_>>(), splits);
+ let splits: &[&[_]] = &[&[2, 3, 4, 5], &[1]];
+ assert_eq!(xs.split_inclusive(|x| *x == 1).rev().collect::<Vec<_>>(), splits);
+ let splits: &[&[_]] = &[&[1, 2, 3, 4, 5]];
+ assert_eq!(xs.split_inclusive(|x| *x == 5).rev().collect::<Vec<_>>(), splits);
+ let splits: &[&[_]] = &[&[1, 2, 3, 4, 5]];
+ assert_eq!(xs.split_inclusive(|x| *x == 10).rev().collect::<Vec<_>>(), splits);
+ let splits: &[&[_]] = &[&[5], &[4], &[3], &[2], &[1]];
+ assert_eq!(xs.split_inclusive(|_| true).rev().collect::<Vec<_>>(), splits);
+
+ let xs: &[i32] = &[];
+ let splits: &[&[i32]] = &[&[]];
+ assert_eq!(xs.split_inclusive(|x| *x == 5).rev().collect::<Vec<_>>(), splits);
+}
+
+#[test]
+fn test_splitator_mut_inclusive() {
+ let xs = &mut [1, 2, 3, 4, 5];
+
+ let splits: &[&[_]] = &[&[1, 2], &[3, 4], &[5]];
+ assert_eq!(xs.split_inclusive_mut(|x| *x % 2 == 0).collect::<Vec<_>>(), splits);
+ let splits: &[&[_]] = &[&[1], &[2, 3, 4, 5]];
+ assert_eq!(xs.split_inclusive_mut(|x| *x == 1).collect::<Vec<_>>(), splits);
+ let splits: &[&[_]] = &[&[1, 2, 3, 4, 5]];
+ assert_eq!(xs.split_inclusive_mut(|x| *x == 5).collect::<Vec<_>>(), splits);
+ let splits: &[&[_]] = &[&[1, 2, 3, 4, 5]];
+ assert_eq!(xs.split_inclusive_mut(|x| *x == 10).collect::<Vec<_>>(), splits);
+ let splits: &[&[_]] = &[&[1], &[2], &[3], &[4], &[5]];
+ assert_eq!(xs.split_inclusive_mut(|_| true).collect::<Vec<_>>(), splits);
+
+ let xs: &mut [i32] = &mut [];
+ let splits: &[&[i32]] = &[&[]];
+ assert_eq!(xs.split_inclusive_mut(|x| *x == 5).collect::<Vec<_>>(), splits);
+}
+
+#[test]
+fn test_splitator_mut_inclusive_reverse() {
+ let xs = &mut [1, 2, 3, 4, 5];
+
+ let splits: &[&[_]] = &[&[5], &[3, 4], &[1, 2]];
+ assert_eq!(xs.split_inclusive_mut(|x| *x % 2 == 0).rev().collect::<Vec<_>>(), splits);
+ let splits: &[&[_]] = &[&[2, 3, 4, 5], &[1]];
+ assert_eq!(xs.split_inclusive_mut(|x| *x == 1).rev().collect::<Vec<_>>(), splits);
+ let splits: &[&[_]] = &[&[1, 2, 3, 4, 5]];
+ assert_eq!(xs.split_inclusive_mut(|x| *x == 5).rev().collect::<Vec<_>>(), splits);
+ let splits: &[&[_]] = &[&[1, 2, 3, 4, 5]];
+ assert_eq!(xs.split_inclusive_mut(|x| *x == 10).rev().collect::<Vec<_>>(), splits);
+ let splits: &[&[_]] = &[&[5], &[4], &[3], &[2], &[1]];
+ assert_eq!(xs.split_inclusive_mut(|_| true).rev().collect::<Vec<_>>(), splits);
+
+ let xs: &mut [i32] = &mut [];
+ let splits: &[&[i32]] = &[&[]];
+ assert_eq!(xs.split_inclusive_mut(|x| *x == 5).rev().collect::<Vec<_>>(), splits);
+}
+
+#[test]
fn test_splitnator() {
let xs = &[1, 2, 3, 4, 5];
diff --git a/src/liballoc/tests/str.rs b/src/liballoc/tests/str.rs
index d3c7261..b703df6 100644
--- a/src/liballoc/tests/str.rs
+++ b/src/liballoc/tests/str.rs
@@ -1248,6 +1248,49 @@
}
#[test]
+fn test_split_char_iterator_inclusive() {
+ let data = "\nMäry häd ä little lämb\nLittle lämb\n";
+
+ let split: Vec<&str> = data.split_inclusive('\n').collect();
+ assert_eq!(split, ["\n", "Märy häd ä little lämb\n", "Little lämb\n"]);
+
+ let uppercase_separated = "SheePSharKTurtlECaT";
+ let mut first_char = true;
+ let split: Vec<&str> = uppercase_separated
+ .split_inclusive(|c: char| {
+ let split = !first_char && c.is_uppercase();
+ first_char = split;
+ split
+ })
+ .collect();
+ assert_eq!(split, ["SheeP", "SharK", "TurtlE", "CaT"]);
+}
+
+#[test]
+fn test_split_char_iterator_inclusive_rev() {
+ let data = "\nMäry häd ä little lämb\nLittle lämb\n";
+
+ let split: Vec<&str> = data.split_inclusive('\n').rev().collect();
+ assert_eq!(split, ["Little lämb\n", "Märy häd ä little lämb\n", "\n"]);
+
+ // Note that the predicate is stateful and thus dependent
+ // on the iteration order.
+ // (A different predicate is needed for reverse iterator vs normal iterator.)
+ // Not sure if anything can be done though.
+ let uppercase_separated = "SheePSharKTurtlECaT";
+ let mut term_char = true;
+ let split: Vec<&str> = uppercase_separated
+ .split_inclusive(|c: char| {
+ let split = term_char && c.is_uppercase();
+ term_char = c.is_uppercase();
+ split
+ })
+ .rev()
+ .collect();
+ assert_eq!(split, ["CaT", "TurtlE", "SharK", "SheeP"]);
+}
+
+#[test]
fn test_rsplit() {
let data = "\nMäry häd ä little lämb\nLittle lämb\n";
diff --git a/src/libcore/hash/sip.rs b/src/libcore/hash/sip.rs
index 7ebe01e..c4fbd9d 100644
--- a/src/libcore/hash/sip.rs
+++ b/src/libcore/hash/sip.rs
@@ -121,7 +121,9 @@
}};
}
-/// Loads an u64 using up to 7 bytes of a byte slice.
+/// Loads a u64 using up to 7 bytes of a byte slice. It looks clumsy but the
+/// `copy_nonoverlapping` calls that occur (via `load_int_le!`) all have fixed
+/// sizes and avoid calling `memcpy`, which is good for speed.
///
/// Unsafe because: unchecked indexing at start..start+len
#[inline]
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index 12647fa..bca96b7 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -73,11 +73,14 @@
#![feature(const_ascii_ctype_on_intrinsics)]
#![feature(const_alloc_layout)]
#![feature(const_if_match)]
+#![feature(const_loop)]
#![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_int_pow)]
+#![feature(constctlz)]
#![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 471ab96..43c5f7c 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -8,9 +8,18 @@
use crate::fmt;
use crate::intrinsics;
use crate::mem;
-use crate::ops;
use crate::str::FromStr;
+// Used because the `?` operator is not allowed in a const context.
+macro_rules! try_opt {
+ ($e:expr) => {
+ match $e {
+ Some(x) => x,
+ None => return None,
+ }
+ };
+}
+
macro_rules! impl_nonzero_fmt {
( #[$stability: meta] ( $( $Trait: ident ),+ ) for $Ty: ident ) => {
$(
@@ -993,26 +1002,27 @@
```"),
#[stable(feature = "no_panic_pow", since = "1.34.0")]
+ #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
- pub fn checked_pow(self, mut exp: u32) -> Option<Self> {
+ pub const fn checked_pow(self, mut exp: u32) -> Option<Self> {
let mut base = self;
let mut acc: Self = 1;
while exp > 1 {
if (exp & 1) == 1 {
- acc = acc.checked_mul(base)?;
+ acc = try_opt!(acc.checked_mul(base));
}
exp /= 2;
- base = base.checked_mul(base)?;
+ base = try_opt!(base.checked_mul(base));
}
// Deal with the final bit of the exponent separately, since
// squaring the base afterwards is not necessary and may cause a
// needless overflow.
if exp == 1 {
- acc = acc.checked_mul(base)?;
+ acc = try_opt!(acc.checked_mul(base));
}
Some(acc)
@@ -1180,10 +1190,11 @@
$EndFeature, "
```"),
#[stable(feature = "no_panic_pow", since = "1.34.0")]
+ #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
- pub fn saturating_pow(self, exp: u32) -> Self {
+ pub const fn saturating_pow(self, exp: u32) -> Self {
match self.checked_pow(exp) {
Some(x) => x,
None if self < 0 && exp % 2 == 1 => Self::min_value(),
@@ -1523,10 +1534,11 @@
$EndFeature, "
```"),
#[stable(feature = "no_panic_pow", since = "1.34.0")]
+ #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
- pub fn wrapping_pow(self, mut exp: u32) -> Self {
+ pub const fn wrapping_pow(self, mut exp: u32) -> Self {
let mut base = self;
let mut acc: Self = 1;
@@ -1900,10 +1912,11 @@
$EndFeature, "
```"),
#[stable(feature = "no_panic_pow", since = "1.34.0")]
+ #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
- pub fn overflowing_pow(self, mut exp: u32) -> (Self, bool) {
+ pub const fn overflowing_pow(self, mut exp: u32) -> (Self, bool) {
let mut base = self;
let mut acc: Self = 1;
let mut overflown = false;
@@ -1949,11 +1962,12 @@
$EndFeature, "
```"),
#[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
#[rustc_inherit_overflow_checks]
- pub fn pow(self, mut exp: u32) -> Self {
+ pub const fn pow(self, mut exp: u32) -> Self {
let mut base = self;
let mut acc = 1;
@@ -3119,26 +3133,27 @@
assert_eq!(", stringify!($SelfT), "::max_value().checked_pow(2), None);", $EndFeature, "
```"),
#[stable(feature = "no_panic_pow", since = "1.34.0")]
+ #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
- pub fn checked_pow(self, mut exp: u32) -> Option<Self> {
+ pub const fn checked_pow(self, mut exp: u32) -> Option<Self> {
let mut base = self;
let mut acc: Self = 1;
while exp > 1 {
if (exp & 1) == 1 {
- acc = acc.checked_mul(base)?;
+ acc = try_opt!(acc.checked_mul(base));
}
exp /= 2;
- base = base.checked_mul(base)?;
+ base = try_opt!(base.checked_mul(base));
}
// Deal with the final bit of the exponent separately, since
// squaring the base afterwards is not necessary and may cause a
// needless overflow.
if exp == 1 {
- acc = acc.checked_mul(base)?;
+ acc = try_opt!(acc.checked_mul(base));
}
Some(acc)
@@ -3234,10 +3249,11 @@
$EndFeature, "
```"),
#[stable(feature = "no_panic_pow", since = "1.34.0")]
+ #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
- pub fn saturating_pow(self, exp: u32) -> Self {
+ pub const fn saturating_pow(self, exp: u32) -> Self {
match self.checked_pow(exp) {
Some(x) => x,
None => Self::max_value(),
@@ -3527,10 +3543,11 @@
assert_eq!(3u8.wrapping_pow(6), 217);", $EndFeature, "
```"),
#[stable(feature = "no_panic_pow", since = "1.34.0")]
+ #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
- pub fn wrapping_pow(self, mut exp: u32) -> Self {
+ pub const fn wrapping_pow(self, mut exp: u32) -> Self {
let mut base = self;
let mut acc: Self = 1;
@@ -3853,10 +3870,11 @@
assert_eq!(3u8.overflowing_pow(6), (217, true));", $EndFeature, "
```"),
#[stable(feature = "no_panic_pow", since = "1.34.0")]
+ #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
- pub fn overflowing_pow(self, mut exp: u32) -> (Self, bool) {
+ pub const fn overflowing_pow(self, mut exp: u32) -> (Self, bool) {
let mut base = self;
let mut acc: Self = 1;
let mut overflown = false;
@@ -3899,11 +3917,12 @@
", $Feature, "assert_eq!(2", stringify!($SelfT), ".pow(5), 32);", $EndFeature, "
```"),
#[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
#[rustc_inherit_overflow_checks]
- pub fn pow(self, mut exp: u32) -> Self {
+ pub const fn pow(self, mut exp: u32) -> Self {
let mut base = self;
let mut acc = 1;
@@ -4014,7 +4033,8 @@
// overflow cases it instead ends up returning the maximum value
// of the type, and can return 0 for 0.
#[inline]
- fn one_less_than_next_power_of_two(self) -> Self {
+ #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
+ const fn one_less_than_next_power_of_two(self) -> Self {
if self <= 1 { return 0; }
let p = self - 1;
@@ -4042,10 +4062,11 @@
assert_eq!(3", stringify!($SelfT), ".next_power_of_two(), 4);", $EndFeature, "
```"),
#[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
#[inline]
- pub fn next_power_of_two(self) -> Self {
- // Call the trait to get overflow checks
- ops::Add::add(self.one_less_than_next_power_of_two(), 1)
+ #[rustc_inherit_overflow_checks]
+ pub const fn next_power_of_two(self) -> Self {
+ self.one_less_than_next_power_of_two() + 1
}
}
@@ -4067,7 +4088,8 @@
```"),
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
- pub fn checked_next_power_of_two(self) -> Option<Self> {
+ #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
+ pub const fn checked_next_power_of_two(self) -> Option<Self> {
self.one_less_than_next_power_of_two().checked_add(1)
}
}
@@ -4091,7 +4113,8 @@
```"),
#[unstable(feature = "wrapping_next_power_of_two", issue = "32463",
reason = "needs decision on wrapping behaviour")]
- pub fn wrapping_next_power_of_two(self) -> Self {
+ #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
+ pub const fn wrapping_next_power_of_two(self) -> Self {
self.one_less_than_next_power_of_two().wrapping_add(1)
}
}
@@ -4301,8 +4324,9 @@
/// assert!(!non_ascii.is_ascii());
/// ```
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
+ #[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.43.0")]
#[inline]
- pub fn is_ascii(&self) -> bool {
+ pub const fn is_ascii(&self) -> bool {
*self & 128 == 0
}
diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs
index e79a775..7c65f59 100644
--- a/src/libcore/slice/mod.rs
+++ b/src/libcore/slice/mod.rs
@@ -1156,6 +1156,69 @@
}
/// Returns an iterator over subslices separated by elements that match
+ /// `pred`. The matched element is contained in the end of the previous
+ /// subslice as a terminator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(split_inclusive)]
+ /// let slice = [10, 40, 33, 20];
+ /// let mut iter = slice.split_inclusive(|num| num % 3 == 0);
+ ///
+ /// assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
+ /// assert_eq!(iter.next().unwrap(), &[20]);
+ /// assert!(iter.next().is_none());
+ /// ```
+ ///
+ /// If the last element of the slice is matched,
+ /// that element will be considered the terminator of the preceding slice.
+ /// That slice will be the last item returned by the iterator.
+ ///
+ /// ```
+ /// #![feature(split_inclusive)]
+ /// let slice = [3, 10, 40, 33];
+ /// let mut iter = slice.split_inclusive(|num| num % 3 == 0);
+ ///
+ /// assert_eq!(iter.next().unwrap(), &[3]);
+ /// assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
+ /// assert!(iter.next().is_none());
+ /// ```
+ #[unstable(feature = "split_inclusive", issue = "none")]
+ #[inline]
+ pub fn split_inclusive<F>(&self, pred: F) -> SplitInclusive<'_, T, F>
+ where
+ F: FnMut(&T) -> bool,
+ {
+ SplitInclusive { v: self, pred, finished: false }
+ }
+
+ /// Returns an iterator over mutable subslices separated by elements that
+ /// match `pred`. The matched element is contained in the previous
+ /// subslice as a terminator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(split_inclusive)]
+ /// let mut v = [10, 40, 30, 20, 60, 50];
+ ///
+ /// for group in v.split_inclusive_mut(|num| *num % 3 == 0) {
+ /// let terminator_idx = group.len()-1;
+ /// group[terminator_idx] = 1;
+ /// }
+ /// assert_eq!(v, [10, 40, 1, 20, 1, 1]);
+ /// ```
+ #[unstable(feature = "split_inclusive", issue = "none")]
+ #[inline]
+ pub fn split_inclusive_mut<F>(&mut self, pred: F) -> SplitInclusiveMut<'_, T, F>
+ where
+ F: FnMut(&T) -> bool,
+ {
+ SplitInclusiveMut { v: self, pred, finished: false }
+ }
+
+ /// Returns an iterator over subslices separated by elements that match
/// `pred`, starting at the end of the slice and working backwards.
/// The matched element is not contained in the subslices.
///
@@ -3675,7 +3738,106 @@
#[stable(feature = "fused", since = "1.26.0")]
impl<T, P> FusedIterator for Split<'_, T, P> where P: FnMut(&T) -> bool {}
-/// An iterator over the subslices of the vector which are separated
+/// An iterator over subslices separated by elements that match a predicate
+/// function. Unlike `Split`, it contains the matched part as a terminator
+/// of the subslice.
+///
+/// This struct is created by the [`split_inclusive`] method on [slices].
+///
+/// [`split_inclusive`]: ../../std/primitive.slice.html#method.split_inclusive
+/// [slices]: ../../std/primitive.slice.html
+#[unstable(feature = "split_inclusive", issue = "none")]
+pub struct SplitInclusive<'a, T: 'a, P>
+where
+ P: FnMut(&T) -> bool,
+{
+ v: &'a [T],
+ pred: P,
+ finished: bool,
+}
+
+#[unstable(feature = "split_inclusive", issue = "none")]
+impl<T: fmt::Debug, P> fmt::Debug for SplitInclusive<'_, T, P>
+where
+ P: FnMut(&T) -> bool,
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("SplitInclusive")
+ .field("v", &self.v)
+ .field("finished", &self.finished)
+ .finish()
+ }
+}
+
+// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
+#[unstable(feature = "split_inclusive", issue = "none")]
+impl<T, P> Clone for SplitInclusive<'_, T, P>
+where
+ P: Clone + FnMut(&T) -> bool,
+{
+ fn clone(&self) -> Self {
+ SplitInclusive { v: self.v, pred: self.pred.clone(), finished: self.finished }
+ }
+}
+
+#[unstable(feature = "split_inclusive", issue = "none")]
+impl<'a, T, P> Iterator for SplitInclusive<'a, T, P>
+where
+ P: FnMut(&T) -> bool,
+{
+ type Item = &'a [T];
+
+ #[inline]
+ fn next(&mut self) -> Option<&'a [T]> {
+ if self.finished {
+ return None;
+ }
+
+ let idx =
+ self.v.iter().position(|x| (self.pred)(x)).map(|idx| idx + 1).unwrap_or(self.v.len());
+ if idx == self.v.len() {
+ self.finished = true;
+ }
+ let ret = Some(&self.v[..idx]);
+ self.v = &self.v[idx..];
+ ret
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ if self.finished { (0, Some(0)) } else { (1, Some(self.v.len() + 1)) }
+ }
+}
+
+#[unstable(feature = "split_inclusive", issue = "none")]
+impl<'a, T, P> DoubleEndedIterator for SplitInclusive<'a, T, P>
+where
+ P: FnMut(&T) -> bool,
+{
+ #[inline]
+ fn next_back(&mut self) -> Option<&'a [T]> {
+ if self.finished {
+ return None;
+ }
+
+ // The last index of self.v is already checked and found to match
+ // by the last iteration, so we start searching a new match
+ // one index to the left.
+ let remainder = if self.v.len() == 0 { &[] } else { &self.v[..(self.v.len() - 1)] };
+ let idx = remainder.iter().rposition(|x| (self.pred)(x)).map(|idx| idx + 1).unwrap_or(0);
+ if idx == 0 {
+ self.finished = true;
+ }
+ let ret = Some(&self.v[idx..]);
+ self.v = &self.v[..idx];
+ ret
+ }
+}
+
+#[unstable(feature = "split_inclusive", issue = "none")]
+impl<T, P> FusedIterator for SplitInclusive<'_, T, P> where P: FnMut(&T) -> bool {}
+
+/// An iterator over the mutable subslices of the vector which are separated
/// by elements that match `pred`.
///
/// This struct is created by the [`split_mut`] method on [slices].
@@ -3789,6 +3951,114 @@
#[stable(feature = "fused", since = "1.26.0")]
impl<T, P> FusedIterator for SplitMut<'_, T, P> where P: FnMut(&T) -> bool {}
+/// An iterator over the mutable subslices of the vector which are separated
+/// by elements that match `pred`. Unlike `SplitMut`, it contains the matched
+/// parts in the ends of the subslices.
+///
+/// This struct is created by the [`split_inclusive_mut`] method on [slices].
+///
+/// [`split_inclusive_mut`]: ../../std/primitive.slice.html#method.split_inclusive_mut
+/// [slices]: ../../std/primitive.slice.html
+#[unstable(feature = "split_inclusive", issue = "none")]
+pub struct SplitInclusiveMut<'a, T: 'a, P>
+where
+ P: FnMut(&T) -> bool,
+{
+ v: &'a mut [T],
+ pred: P,
+ finished: bool,
+}
+
+#[unstable(feature = "split_inclusive", issue = "none")]
+impl<T: fmt::Debug, P> fmt::Debug for SplitInclusiveMut<'_, T, P>
+where
+ P: FnMut(&T) -> bool,
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("SplitInclusiveMut")
+ .field("v", &self.v)
+ .field("finished", &self.finished)
+ .finish()
+ }
+}
+
+#[unstable(feature = "split_inclusive", issue = "none")]
+impl<'a, T, P> Iterator for SplitInclusiveMut<'a, T, P>
+where
+ P: FnMut(&T) -> bool,
+{
+ type Item = &'a mut [T];
+
+ #[inline]
+ fn next(&mut self) -> Option<&'a mut [T]> {
+ if self.finished {
+ return None;
+ }
+
+ let idx_opt = {
+ // work around borrowck limitations
+ let pred = &mut self.pred;
+ self.v.iter().position(|x| (*pred)(x))
+ };
+ let idx = idx_opt.map(|idx| idx + 1).unwrap_or(self.v.len());
+ if idx == self.v.len() {
+ self.finished = true;
+ }
+ let tmp = mem::replace(&mut self.v, &mut []);
+ let (head, tail) = tmp.split_at_mut(idx);
+ self.v = tail;
+ Some(head)
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ if self.finished {
+ (0, Some(0))
+ } else {
+ // if the predicate doesn't match anything, we yield one slice
+ // if it matches every element, we yield len+1 empty slices.
+ (1, Some(self.v.len() + 1))
+ }
+ }
+}
+
+#[unstable(feature = "split_inclusive", issue = "none")]
+impl<'a, T, P> DoubleEndedIterator for SplitInclusiveMut<'a, T, P>
+where
+ P: FnMut(&T) -> bool,
+{
+ #[inline]
+ fn next_back(&mut self) -> Option<&'a mut [T]> {
+ if self.finished {
+ return None;
+ }
+
+ let idx_opt = if self.v.len() == 0 {
+ None
+ } else {
+ // work around borrowck limitations
+ let pred = &mut self.pred;
+
+ // The last index of self.v is already checked and found to match
+ // by the last iteration, so we start searching a new match
+ // one index to the left.
+ let remainder = &self.v[..(self.v.len() - 1)];
+ remainder.iter().rposition(|x| (*pred)(x))
+ };
+ let idx = idx_opt.map(|idx| idx + 1).unwrap_or(0);
+ if idx == 0 {
+ self.finished = true;
+ }
+ let tmp = mem::replace(&mut self.v, &mut []);
+ let (head, tail) = tmp.split_at_mut(idx);
+ self.v = head;
+ Some(tail)
+ }
+}
+
+#[unstable(feature = "split_inclusive", issue = "none")]
+impl<T, P> FusedIterator for SplitInclusiveMut<'_, T, P> where P: FnMut(&T) -> bool {}
+
/// An iterator over subslices separated by elements that match a predicate
/// function, starting from the end of the slice.
///
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index 7c4acb0..668b3ff 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -1133,6 +1133,26 @@
}
#[inline]
+ fn next_inclusive(&mut self) -> Option<&'a str> {
+ if self.finished {
+ return None;
+ }
+
+ let haystack = self.matcher.haystack();
+ match self.matcher.next_match() {
+ // SAFETY: `Searcher` guarantees that `b` lies on unicode boundary,
+ // and self.start is either the start of the original string,
+ // or `b` was assigned to it, so it also lies on unicode boundary.
+ Some((_, b)) => unsafe {
+ let elt = haystack.get_unchecked(self.start..b);
+ self.start = b;
+ Some(elt)
+ },
+ None => self.get_end(),
+ }
+ }
+
+ #[inline]
fn next_back(&mut self) -> Option<&'a str>
where
P::Searcher: ReverseSearcher<'a>,
@@ -1168,6 +1188,49 @@
},
}
}
+
+ #[inline]
+ fn next_back_inclusive(&mut self) -> Option<&'a str>
+ where
+ P::Searcher: ReverseSearcher<'a>,
+ {
+ if self.finished {
+ return None;
+ }
+
+ if !self.allow_trailing_empty {
+ self.allow_trailing_empty = true;
+ match self.next_back_inclusive() {
+ Some(elt) if !elt.is_empty() => return Some(elt),
+ _ => {
+ if self.finished {
+ return None;
+ }
+ }
+ }
+ }
+
+ let haystack = self.matcher.haystack();
+ match self.matcher.next_match_back() {
+ // SAFETY: `Searcher` guarantees that `b` lies on unicode boundary,
+ // and self.end is either the end of the original string,
+ // or `b` was assigned to it, so it also lies on unicode boundary.
+ Some((_, b)) => unsafe {
+ let elt = haystack.get_unchecked(b..self.end);
+ self.end = b;
+ Some(elt)
+ },
+ // SAFETY: self.start is either the start of the original string,
+ // or start of a substring that represents the part of the string that hasn't
+ // iterated yet. Either way, it is guaranteed to lie on unicode boundary.
+ // self.end is either the end of the original string,
+ // or `b` was assigned to it, so it also lies on unicode boundary.
+ None => unsafe {
+ self.finished = true;
+ Some(haystack.get_unchecked(self.start..self.end))
+ },
+ }
+ }
}
generate_pattern_iterators! {
@@ -3213,6 +3276,42 @@
})
}
+ /// An iterator over substrings of this string slice, separated by
+ /// characters matched by a pattern. Differs from the iterator produced by
+ /// `split` in that `split_inclusive` leaves the matched part as the
+ /// terminator of the substring.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(split_inclusive)]
+ /// let v: Vec<&str> = "Mary had a little lamb\nlittle lamb\nlittle lamb."
+ /// .split_inclusive('\n').collect();
+ /// assert_eq!(v, ["Mary had a little lamb\n", "little lamb\n", "little lamb."]);
+ /// ```
+ ///
+ /// If the last element of the string is matched,
+ /// that element will be considered the terminator of the preceding substring.
+ /// That substring will be the last item returned by the iterator.
+ ///
+ /// ```
+ /// #![feature(split_inclusive)]
+ /// let v: Vec<&str> = "Mary had a little lamb\nlittle lamb\nlittle lamb.\n"
+ /// .split_inclusive('\n').collect();
+ /// assert_eq!(v, ["Mary had a little lamb\n", "little lamb\n", "little lamb.\n"]);
+ /// ```
+ #[unstable(feature = "split_inclusive", issue = "none")]
+ #[inline]
+ pub fn split_inclusive<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitInclusive<'a, P> {
+ SplitInclusive(SplitInternal {
+ start: 0,
+ end: self.len(),
+ matcher: pat.into_searcher(self),
+ allow_trailing_empty: false,
+ finished: false,
+ })
+ }
+
/// An iterator over substrings of the given string slice, separated by
/// characters matched by a pattern and yielded in reverse order.
///
@@ -4406,6 +4505,19 @@
inner: Map<Filter<SliceSplit<'a, u8, IsAsciiWhitespace>, BytesIsNotEmpty>, UnsafeBytesToStr>,
}
+/// An iterator over the substrings of a string,
+/// terminated by a substring matching to a predicate function
+/// Unlike `Split`, it contains the matched part as a terminator
+/// of the subslice.
+///
+/// This struct is created by the [`split_inclusive`] method on [`str`].
+/// See its documentation for more.
+///
+/// [`split_inclusive`]: ../../std/primitive.str.html#method.split_inclusive
+/// [`str`]: ../../std/primitive.str.html
+#[unstable(feature = "split_inclusive", issue = "none")]
+pub struct SplitInclusive<'a, P: Pattern<'a>>(SplitInternal<'a, P>);
+
impl_fn_for_zst! {
#[derive(Clone)]
struct IsWhitespace impl Fn = |c: char| -> bool {
@@ -4496,6 +4608,44 @@
#[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
impl FusedIterator for SplitAsciiWhitespace<'_> {}
+#[unstable(feature = "split_inclusive", issue = "none")]
+impl<'a, P: Pattern<'a>> Iterator for SplitInclusive<'a, P> {
+ type Item = &'a str;
+
+ #[inline]
+ fn next(&mut self) -> Option<&'a str> {
+ self.0.next_inclusive()
+ }
+}
+
+#[unstable(feature = "split_inclusive", issue = "none")]
+impl<'a, P: Pattern<'a, Searcher: fmt::Debug>> fmt::Debug for SplitInclusive<'a, P> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("SplitInclusive").field("0", &self.0).finish()
+ }
+}
+
+// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
+#[unstable(feature = "split_inclusive", issue = "none")]
+impl<'a, P: Pattern<'a, Searcher: Clone>> Clone for SplitInclusive<'a, P> {
+ fn clone(&self) -> Self {
+ SplitInclusive(self.0.clone())
+ }
+}
+
+#[unstable(feature = "split_inclusive", issue = "none")]
+impl<'a, P: Pattern<'a, Searcher: ReverseSearcher<'a>>> DoubleEndedIterator
+ for SplitInclusive<'a, P>
+{
+ #[inline]
+ fn next_back(&mut self) -> Option<&'a str> {
+ self.0.next_back_inclusive()
+ }
+}
+
+#[unstable(feature = "split_inclusive", issue = "none")]
+impl<'a, P: Pattern<'a>> FusedIterator for SplitInclusive<'a, P> {}
+
/// An iterator of [`u16`] over the string encoded as UTF-16.
///
/// [`u16`]: ../../std/primitive.u16.html
diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs
index f5c83fe..ca55d41 100644
--- a/src/librustc/arena.rs
+++ b/src/librustc/arena.rs
@@ -48,6 +48,7 @@
[] item_local_set: rustc_hir::ItemLocalSet,
[decode] mir_const_qualif: rustc_index::bit_set::BitSet<rustc::mir::Local>,
[] trait_impls_of: rustc::ty::trait_def::TraitImpls,
+ [] associated_items: rustc::ty::AssociatedItems,
[] dropck_outlives:
rustc::infer::canonical::Canonical<'tcx,
rustc::infer::canonical::QueryResponse<'tcx,
diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs
index f0879bd..c62f9a0 100644
--- a/src/librustc/mir/interpret/mod.rs
+++ b/src/librustc/mir/interpret/mod.rs
@@ -148,6 +148,10 @@
/// Error type for `tcx.lit_to_const`.
#[derive(Copy, Clone, Debug, Eq, PartialEq, HashStable)]
pub enum LitToConstError {
+ /// The literal's inferred type did not match the expected `ty` in the input.
+ /// This is used for graceful error handling (`delay_span_bug`) in
+ /// type checking (`AstConv::ast_const_to_const`).
+ TypeError,
UnparseableFloat,
Reported,
}
diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs
index 8330bbe..409c981 100644
--- a/src/librustc/mir/visit.rs
+++ b/src/librustc/mir/visit.rs
@@ -519,12 +519,12 @@
resume_arg,
drop: _,
} => {
+ self.visit_operand(value, source_location);
self.visit_place(
resume_arg,
PlaceContext::MutatingUse(MutatingUseContext::Store),
source_location,
);
- self.visit_operand(value, source_location);
}
}
diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
index 3cee10f..02c51a2 100644
--- a/src/librustc/query/mod.rs
+++ b/src/librustc/query/mod.rs
@@ -333,7 +333,7 @@
query associated_item(_: DefId) -> ty::AssocItem {}
/// Collects the associated items defined on a trait or impl.
- query associated_items(key: DefId) -> &'tcx [ty::AssocItem] {
+ query associated_items(key: DefId) -> &'tcx ty::AssociatedItems {
desc { |tcx| "collecting associated items of {}", tcx.def_path_str(key) }
}
@@ -661,7 +661,7 @@
desc { |tcx| "building specialization graph of trait `{}`", tcx.def_path_str(key) }
cache_on_disk_if { true }
}
- query is_object_safe(key: DefId) -> bool {
+ query object_safety_violations(key: DefId) -> Vec<traits::ObjectSafetyViolation> {
desc { |tcx| "determine object safety of trait `{}`", tcx.def_path_str(key) }
}
diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs
index c000aa7..de2ec53 100644
--- a/src/librustc/traits/mod.rs
+++ b/src/librustc/traits/mod.rs
@@ -16,8 +16,10 @@
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_span::{Span, DUMMY_SP};
+use smallvec::SmallVec;
use syntax::ast;
+use std::borrow::Cow;
use std::fmt::Debug;
use std::rc::Rc;
@@ -737,3 +739,133 @@
tcx: TyCtxt<'tcx>,
) -> Option<Self::LiftedLiteral>;
}
+
+#[derive(Clone, Debug, PartialEq, Eq, Hash, HashStable)]
+pub enum ObjectSafetyViolation {
+ /// `Self: Sized` declared on the trait.
+ SizedSelf(SmallVec<[Span; 1]>),
+
+ /// Supertrait reference references `Self` an in illegal location
+ /// (e.g., `trait Foo : Bar<Self>`).
+ SupertraitSelf(SmallVec<[Span; 1]>),
+
+ /// Method has something illegal.
+ Method(ast::Name, MethodViolationCode, Span),
+
+ /// Associated const.
+ AssocConst(ast::Name, Span),
+}
+
+impl ObjectSafetyViolation {
+ pub fn error_msg(&self) -> Cow<'static, str> {
+ match *self {
+ ObjectSafetyViolation::SizedSelf(_) => "it requires `Self: Sized`".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()
+ }
+ ObjectSafetyViolation::Method(
+ name,
+ 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,
+ _,
+ ) => {
+ 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(name, DUMMY_SP) => {
+ format!("it contains associated `const` `{}`", name).into()
+ }
+ ObjectSafetyViolation::AssocConst(..) => "it contains this associated `const`".into(),
+ }
+ }
+
+ pub fn solution(&self) -> Option<(String, Option<(String, Span)>)> {
+ Some(match *self {
+ ObjectSafetyViolation::SizedSelf(_) | ObjectSafetyViolation::SupertraitSelf(_) => {
+ return None;
+ }
+ 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,
+ span,
+ ) => (
+ format!("consider changing method `{}`'s `self` parameter to be `&self`", name)
+ .into(),
+ Some(("&Self".to_string(), span)),
+ ),
+ ObjectSafetyViolation::AssocConst(name, _)
+ | ObjectSafetyViolation::Method(name, ..) => {
+ (format!("consider moving `{}` to another trait", name), None)
+ }
+ })
+ }
+
+ 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 {
+ ObjectSafetyViolation::SupertraitSelf(spans)
+ | ObjectSafetyViolation::SizedSelf(spans) => spans.clone(),
+ ObjectSafetyViolation::AssocConst(_, span)
+ | ObjectSafetyViolation::Method(_, _, span)
+ if *span != DUMMY_SP =>
+ {
+ smallvec![*span]
+ }
+ _ => smallvec![],
+ }
+ }
+}
+
+/// Reasons a method might not be object-safe.
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)]
+pub enum MethodViolationCode {
+ /// e.g., `fn foo()`
+ StaticMethod(Option<(&'static str, Span)>),
+
+ /// e.g., `fn foo(&self, x: Self)`
+ ReferencesSelfInput(usize),
+
+ /// e.g., `fn foo(&self) -> Self`
+ ReferencesSelfOutput,
+
+ /// e.g., `fn foo(&self) where Self: Clone`
+ WhereClauseReferencesSelf,
+
+ /// e.g., `fn foo<A>()`
+ Generic,
+
+ /// the method's receiver (`self` argument) can't be dispatched on
+ UndispatchableReceiver,
+}
diff --git a/src/librustc/traits/specialization_graph.rs b/src/librustc/traits/specialization_graph.rs
index 36a8436..ee813bf 100644
--- a/src/librustc/traits/specialization_graph.rs
+++ b/src/librustc/traits/specialization_graph.rs
@@ -81,8 +81,8 @@
}
/// Iterate over the items defined directly by the given (impl or trait) node.
- pub fn items(&self, tcx: TyCtxt<'tcx>) -> &'tcx [ty::AssocItem] {
- tcx.associated_items(self.def_id())
+ pub fn items(&self, tcx: TyCtxt<'tcx>) -> impl 'tcx + Iterator<Item = &'tcx ty::AssocItem> {
+ tcx.associated_items(self.def_id()).in_definition_order()
}
/// Finds an associated item defined in this node.
@@ -99,7 +99,7 @@
use crate::ty::AssocKind::*;
tcx.associated_items(self.def_id())
- .iter()
+ .filter_by_name_unhygienic(trait_item_name.name)
.find(move |impl_item| {
match (trait_item_kind, impl_item.kind) {
| (Const, Const)
diff --git a/src/librustc/ty/adjustment.rs b/src/librustc/ty/adjustment.rs
index f4006a1..851bffc 100644
--- a/src/librustc/ty/adjustment.rs
+++ b/src/librustc/ty/adjustment.rs
@@ -122,7 +122,7 @@
};
let method_def_id = tcx
.associated_items(trait_def_id.unwrap())
- .iter()
+ .in_definition_order()
.find(|m| m.kind == ty::AssocKind::Method)
.unwrap()
.def_id;
diff --git a/src/librustc/ty/codec.rs b/src/librustc/ty/codec.rs
index df1602b..c305999 100644
--- a/src/librustc/ty/codec.rs
+++ b/src/librustc/ty/codec.rs
@@ -301,6 +301,7 @@
macro_rules! __impl_decoder_methods {
($($name:ident -> $ty:ty;)*) => {
$(
+ #[inline]
fn $name(&mut self) -> Result<$ty, Self::Error> {
self.opaque.$name()
}
diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs
index 332fd0b..0ec30bc 100644
--- a/src/librustc/ty/instance.rs
+++ b/src/librustc/ty/instance.rs
@@ -337,7 +337,7 @@
let fn_once = tcx.lang_items().fn_once_trait().unwrap();
let call_once = tcx
.associated_items(fn_once)
- .iter()
+ .in_definition_order()
.find(|it| it.kind == ty::AssocKind::Method)
.unwrap()
.def_id;
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index a4b4e1d..a195c94 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -30,10 +30,11 @@
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::fx::FxIndexMap;
+use rustc_data_structures::sorted_map::SortedIndexMultiMap;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::sync::{self, par_iter, Lrc, ParallelIterator};
use rustc_hir as hir;
-use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
+use rustc_hir::def::{CtorKind, CtorOf, DefKind, Namespace, Res};
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc_hir::{Constness, GlobMap, Node, TraitMap};
use rustc_index::vec::{Idx, IndexVec};
@@ -216,6 +217,13 @@
ty::AssocKind::Const => "associated constant",
}
}
+
+ pub fn namespace(&self) -> Namespace {
+ match *self {
+ ty::AssocKind::OpaqueTy | ty::AssocKind::Type => Namespace::TypeNS,
+ ty::AssocKind::Const | ty::AssocKind::Method => Namespace::ValueNS,
+ }
+ }
}
impl AssocItem {
@@ -257,6 +265,81 @@
}
}
+/// A list of `ty::AssocItem`s in definition order that allows for efficient lookup by name.
+///
+/// When doing lookup by name, we try to postpone hygienic comparison for as long as possible since
+/// it is relatively expensive. Instead, items are indexed by `Symbol` and hygienic comparison is
+/// done only on items with the same name.
+#[derive(Debug, Clone, PartialEq, HashStable)]
+pub struct AssociatedItems {
+ items: SortedIndexMultiMap<u32, Symbol, ty::AssocItem>,
+}
+
+impl AssociatedItems {
+ /// Constructs an `AssociatedItems` map from a series of `ty::AssocItem`s in definition order.
+ pub fn new(items_in_def_order: impl IntoIterator<Item = ty::AssocItem>) -> Self {
+ let items = items_in_def_order.into_iter().map(|item| (item.ident.name, item)).collect();
+ AssociatedItems { items }
+ }
+
+ /// Returns a slice of associated items in the order they were defined.
+ ///
+ /// New code should avoid relying on definition order. If you need a particular associated item
+ /// for a known trait, make that trait a lang item instead of indexing this array.
+ pub fn in_definition_order(&self) -> impl '_ + Iterator<Item = &ty::AssocItem> {
+ self.items.iter().map(|(_, v)| v)
+ }
+
+ /// Returns an iterator over all associated items with the given name, ignoring hygiene.
+ pub fn filter_by_name_unhygienic(
+ &self,
+ name: Symbol,
+ ) -> impl '_ + Iterator<Item = &ty::AssocItem> {
+ self.items.get_by_key(&name)
+ }
+
+ /// Returns an iterator over all associated items with the given name.
+ ///
+ /// Multiple items may have the same name if they are in different `Namespace`s. For example,
+ /// an associated type can have the same name as a method. Use one of the `find_by_name_and_*`
+ /// methods below if you know which item you are looking for.
+ pub fn filter_by_name(
+ &'a self,
+ tcx: TyCtxt<'a>,
+ ident: Ident,
+ parent_def_id: DefId,
+ ) -> impl 'a + Iterator<Item = &'a ty::AssocItem> {
+ self.filter_by_name_unhygienic(ident.name)
+ .filter(move |item| tcx.hygienic_eq(ident, item.ident, parent_def_id))
+ }
+
+ /// Returns the associated item with the given name and `AssocKind`, if one exists.
+ pub fn find_by_name_and_kind(
+ &self,
+ tcx: TyCtxt<'_>,
+ ident: Ident,
+ kind: AssocKind,
+ parent_def_id: DefId,
+ ) -> Option<&ty::AssocItem> {
+ self.filter_by_name_unhygienic(ident.name)
+ .filter(|item| item.kind == kind)
+ .find(|item| tcx.hygienic_eq(ident, item.ident, parent_def_id))
+ }
+
+ /// Returns the associated item with the given name in the given `Namespace`, if one exists.
+ pub fn find_by_name_and_namespace(
+ &self,
+ tcx: TyCtxt<'_>,
+ ident: Ident,
+ ns: Namespace,
+ parent_def_id: DefId,
+ ) -> Option<&ty::AssocItem> {
+ self.filter_by_name_unhygienic(ident.name)
+ .filter(|item| item.kind.namespace() == ns)
+ .find(|item| tcx.hygienic_eq(ident, item.ident, parent_def_id))
+ }
+}
+
#[derive(Clone, Debug, PartialEq, Eq, Copy, RustcEncodable, RustcDecodable, HashStable)]
pub enum Visibility {
/// Visible everywhere (including in other crates).
@@ -2731,14 +2814,14 @@
.for_each(|&body_id| f(self.hir().body_owner_def_id(body_id)));
}
- pub fn provided_trait_methods(self, id: DefId) -> impl Iterator<Item = &'tcx AssocItem> {
+ pub fn provided_trait_methods(self, id: DefId) -> impl 'tcx + Iterator<Item = &'tcx AssocItem> {
self.associated_items(id)
- .iter()
+ .in_definition_order()
.filter(|item| item.kind == AssocKind::Method && item.defaultness.has_value())
}
pub fn trait_relevant_for_never(self, did: DefId) -> bool {
- self.associated_items(did).iter().any(|item| item.relevant_for_never())
+ self.associated_items(did).in_definition_order().any(|item| item.relevant_for_never())
}
pub fn opt_item_name(self, def_id: DefId) -> Option<Ident> {
@@ -2998,6 +3081,10 @@
};
(ident, scope)
}
+
+ pub fn is_object_safe(self, key: DefId) -> bool {
+ self.object_safety_violations(key).is_empty()
+ }
}
#[derive(Clone, HashStable)]
diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs
index b92081f..0fb5f66 100644
--- a/src/librustc/ty/query/on_disk_cache.rs
+++ b/src/librustc/ty/query/on_disk_cache.rs
@@ -943,6 +943,7 @@
macro_rules! encoder_methods {
($($name:ident($ty:ty);)*) => {
+ #[inline]
$(fn $name(&mut self, value: $ty) -> Result<(), Self::Error> {
self.encoder.$name(value)
})*
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index 9cf61eb..c3698f4 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -1066,11 +1066,7 @@
) -> ProjectionTy<'tcx> {
let item_def_id = tcx
.associated_items(trait_ref.def_id)
- .iter()
- .find(|item| {
- item.kind == ty::AssocKind::Type
- && tcx.hygienic_eq(item_name, item.ident, trait_ref.def_id)
- })
+ .find_by_name_and_kind(tcx, item_name, ty::AssocKind::Type, trait_ref.def_id)
.unwrap()
.def_id;
diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs
index cb43f74..eec6893 100644
--- a/src/librustc/ty/util.rs
+++ b/src/librustc/ty/util.rs
@@ -357,7 +357,7 @@
let mut dtor_did = None;
let ty = self.type_of(adt_did);
self.for_each_relevant_impl(drop_trait, ty, |impl_did| {
- if let Some(item) = self.associated_items(impl_did).first() {
+ if let Some(item) = self.associated_items(impl_did).in_definition_order().nth(0) {
if validate(self, impl_did).is_ok() {
dtor_did = Some(item.def_id);
}
diff --git a/src/librustc_data_structures/sip128.rs b/src/librustc_data_structures/sip128.rs
index 430f2f4..af0e9f7 100644
--- a/src/librustc_data_structures/sip128.rs
+++ b/src/librustc_data_structures/sip128.rs
@@ -51,17 +51,48 @@
}};
}
-/// Loads up to 8 bytes from a byte-slice into a little-endian u64.
-#[inline]
-fn u8to64_le(buf: &[u8], start: usize, len: usize) -> u64 {
- assert!(len <= 8 && start + len <= buf.len());
+/// Loads an integer of the desired type from a byte stream, in LE order. Uses
+/// `copy_nonoverlapping` to let the compiler generate the most efficient way
+/// to load it from a possibly unaligned address.
+///
+/// Unsafe because: unchecked indexing at i..i+size_of(int_ty)
+macro_rules! load_int_le {
+ ($buf:expr, $i:expr, $int_ty:ident) => {{
+ debug_assert!($i + mem::size_of::<$int_ty>() <= $buf.len());
+ let mut data = 0 as $int_ty;
+ ptr::copy_nonoverlapping(
+ $buf.get_unchecked($i),
+ &mut data as *mut _ as *mut u8,
+ mem::size_of::<$int_ty>(),
+ );
+ data.to_le()
+ }};
+}
- let mut out = 0u64;
- unsafe {
- let out_ptr = &mut out as *mut _ as *mut u8;
- ptr::copy_nonoverlapping(buf.as_ptr().offset(start as isize), out_ptr, len);
+/// Loads a u64 using up to 7 bytes of a byte slice. It looks clumsy but the
+/// `copy_nonoverlapping` calls that occur (via `load_int_le!`) all have fixed
+/// sizes and avoid calling `memcpy`, which is good for speed.
+///
+/// Unsafe because: unchecked indexing at start..start+len
+#[inline]
+unsafe fn u8to64_le(buf: &[u8], start: usize, len: usize) -> u64 {
+ debug_assert!(len < 8);
+ let mut i = 0; // current byte index (from LSB) in the output u64
+ let mut out = 0;
+ if i + 3 < len {
+ out = load_int_le!(buf, start + i, u32) as u64;
+ i += 4;
}
- out.to_le()
+ if i + 1 < len {
+ out |= (load_int_le!(buf, start + i, u16) as u64) << (i * 8);
+ i += 2
+ }
+ if i < len {
+ out |= (*buf.get_unchecked(start + i) as u64) << (i * 8);
+ i += 1;
+ }
+ debug_assert_eq!(i, len);
+ out
}
impl SipHasher128 {
@@ -243,7 +274,7 @@
if self.ntail != 0 {
needed = 8 - self.ntail;
- self.tail |= u8to64_le(msg, 0, cmp::min(length, needed)) << (8 * self.ntail);
+ self.tail |= unsafe { u8to64_le(msg, 0, cmp::min(length, needed)) } << 8 * self.ntail;
if length < needed {
self.ntail += length;
return;
@@ -261,7 +292,7 @@
let mut i = needed;
while i < len - left {
- let mi = u8to64_le(msg, i, 8);
+ let mi = unsafe { load_int_le!(msg, i, u64) };
self.state.v3 ^= mi;
Sip24Rounds::c_rounds(&mut self.state);
@@ -270,7 +301,7 @@
i += 8;
}
- self.tail = u8to64_le(msg, i, left);
+ self.tail = unsafe { u8to64_le(msg, i, left) };
self.ntail = left;
}
diff --git a/src/librustc_data_structures/sorted_map.rs b/src/librustc_data_structures/sorted_map.rs
index 08706aa..8c42b74 100644
--- a/src/librustc_data_structures/sorted_map.rs
+++ b/src/librustc_data_structures/sorted_map.rs
@@ -4,6 +4,10 @@
use std::mem;
use std::ops::{Bound, Index, IndexMut, RangeBounds};
+mod index_map;
+
+pub use index_map::SortedIndexMultiMap;
+
/// `SortedMap` is a data structure with similar characteristics as BTreeMap but
/// slightly different trade-offs: lookup, insertion, and removal are O(log(N))
/// and elements can be iterated in order cheaply.
diff --git a/src/librustc_data_structures/sorted_map/index_map.rs b/src/librustc_data_structures/sorted_map/index_map.rs
new file mode 100644
index 0000000..b7005cc
--- /dev/null
+++ b/src/librustc_data_structures/sorted_map/index_map.rs
@@ -0,0 +1,218 @@
+//! A variant of `SortedMap` that preserves insertion order.
+
+use std::borrow::Borrow;
+use std::hash::{Hash, Hasher};
+use std::iter::FromIterator;
+
+use crate::stable_hasher::{HashStable, StableHasher};
+use rustc_index::vec::{Idx, IndexVec};
+
+/// An indexed multi-map that preserves insertion order while permitting both `O(log n)` lookup of
+/// an item by key and `O(1)` lookup by index.
+///
+/// This data structure is a hybrid of an [`IndexVec`] and a [`SortedMap`]. Like `IndexVec`,
+/// `SortedIndexMultiMap` assigns a typed index to each item while preserving insertion order.
+/// Like `SortedMap`, `SortedIndexMultiMap` has efficient lookup of items by key. However, this
+/// is accomplished by sorting an array of item indices instead of the items themselves.
+///
+/// Unlike `SortedMap`, this data structure can hold multiple equivalent items at once, so the
+/// `get_by_key` method and its variants return an iterator instead of an `Option`. Equivalent
+/// items will be yielded in insertion order.
+///
+/// Unlike a general-purpose map like `BTreeSet` or `HashSet`, `SortedMap` and
+/// `SortedIndexMultiMap` require `O(n)` time to insert a single item. This is because we may need
+/// to insert into the middle of the sorted array. Users should avoid mutating this data structure
+/// in-place.
+///
+/// [`IndexVec`]: ../../rustc_index/vec/struct.IndexVec.html
+/// [`SortedMap`]: ../sorted_map/struct.SortedMap.html
+#[derive(Clone, Debug)]
+pub struct SortedIndexMultiMap<I: Idx, K, V> {
+ /// The elements of the map in insertion order.
+ items: IndexVec<I, (K, V)>,
+
+ /// Indices of the items in the set, sorted by the item's key.
+ idx_sorted_by_item_key: Vec<I>,
+}
+
+impl<I: Idx, K: Ord, V> SortedIndexMultiMap<I, K, V> {
+ pub fn new() -> Self {
+ SortedIndexMultiMap { items: IndexVec::new(), idx_sorted_by_item_key: Vec::new() }
+ }
+
+ pub fn len(&self) -> usize {
+ self.items.len()
+ }
+
+ pub fn is_empty(&self) -> bool {
+ self.items.is_empty()
+ }
+
+ /// Returns an iterator over the items in the map in insertion order.
+ pub fn into_iter(self) -> impl DoubleEndedIterator<Item = (K, V)> {
+ self.items.into_iter()
+ }
+
+ /// Returns an iterator over the items in the map in insertion order along with their indices.
+ pub fn into_iter_enumerated(self) -> impl DoubleEndedIterator<Item = (I, (K, V))> {
+ self.items.into_iter_enumerated()
+ }
+
+ /// Returns an iterator over the items in the map in insertion order.
+ pub fn iter(&self) -> impl '_ + DoubleEndedIterator<Item = (&K, &V)> {
+ self.items.iter().map(|(ref k, ref v)| (k, v))
+ }
+
+ /// Returns an iterator over the items in the map in insertion order along with their indices.
+ pub fn iter_enumerated(&self) -> impl '_ + DoubleEndedIterator<Item = (I, (&K, &V))> {
+ self.items.iter_enumerated().map(|(i, (ref k, ref v))| (i, (k, v)))
+ }
+
+ /// Returns the item in the map with the given index.
+ pub fn get(&self, idx: I) -> Option<&(K, V)> {
+ self.items.get(idx)
+ }
+
+ /// Returns an iterator over the items in the map that are equal to `key`.
+ ///
+ /// If there are multiple items that are equivalent to `key`, they will be yielded in
+ /// insertion order.
+ pub fn get_by_key<Q: 'a>(&'a self, key: &Q) -> impl 'a + Iterator<Item = &'a V>
+ where
+ Q: Ord + ?Sized,
+ K: Borrow<Q>,
+ {
+ self.get_by_key_enumerated(key).map(|(_, v)| v)
+ }
+
+ /// Returns an iterator over the items in the map that are equal to `key` along with their
+ /// indices.
+ ///
+ /// If there are multiple items that are equivalent to `key`, they will be yielded in
+ /// insertion order.
+ pub fn get_by_key_enumerated<Q>(&self, key: &Q) -> impl '_ + Iterator<Item = (I, &V)>
+ where
+ Q: Ord + ?Sized,
+ K: Borrow<Q>,
+ {
+ // FIXME: This should be in the standard library as `equal_range`. See rust-lang/rfcs#2184.
+ match self.binary_search_idx(key) {
+ Err(_) => self.idxs_to_items_enumerated(&[]),
+
+ Ok(idx) => {
+ let start = self.find_lower_bound(key, idx);
+ let end = self.find_upper_bound(key, idx);
+ self.idxs_to_items_enumerated(&self.idx_sorted_by_item_key[start..end])
+ }
+ }
+ }
+
+ fn binary_search_idx<Q>(&self, key: &Q) -> Result<usize, usize>
+ where
+ Q: Ord + ?Sized,
+ K: Borrow<Q>,
+ {
+ self.idx_sorted_by_item_key.binary_search_by(|&idx| self.items[idx].0.borrow().cmp(key))
+ }
+
+ /// Returns the index into the `idx_sorted_by_item_key` array of the first item equal to
+ /// `key`.
+ ///
+ /// `initial` must be an index into that same array for an item that is equal to `key`.
+ fn find_lower_bound<Q>(&self, key: &Q, initial: usize) -> usize
+ where
+ Q: Ord + ?Sized,
+ K: Borrow<Q>,
+ {
+ debug_assert!(self.items[self.idx_sorted_by_item_key[initial]].0.borrow() == key);
+
+ // FIXME: At present, this uses linear search, meaning lookup is only `O(log n)` if duplicate
+ // entries are rare. It would be better to start with a linear search for the common case but
+ // fall back to an exponential search if many duplicates are found. This applies to
+ // `upper_bound` as well.
+ let mut start = initial;
+ while start != 0 && self.items[self.idx_sorted_by_item_key[start - 1]].0.borrow() == key {
+ start -= 1;
+ }
+
+ start
+ }
+
+ /// Returns the index into the `idx_sorted_by_item_key` array of the first item greater than
+ /// `key`, or `self.len()` if no such item exists.
+ ///
+ /// `initial` must be an index into that same array for an item that is equal to `key`.
+ fn find_upper_bound<Q>(&self, key: &Q, initial: usize) -> usize
+ where
+ Q: Ord + ?Sized,
+ K: Borrow<Q>,
+ {
+ debug_assert!(self.items[self.idx_sorted_by_item_key[initial]].0.borrow() == key);
+
+ // See the FIXME for `find_lower_bound`.
+ let mut end = initial + 1;
+ let len = self.items.len();
+ while end < len && self.items[self.idx_sorted_by_item_key[end]].0.borrow() == key {
+ end += 1;
+ }
+
+ end
+ }
+
+ fn idxs_to_items_enumerated(&'a self, idxs: &'a [I]) -> impl 'a + Iterator<Item = (I, &'a V)> {
+ idxs.iter().map(move |&idx| (idx, &self.items[idx].1))
+ }
+}
+
+impl<I: Idx, K: Eq, V: Eq> Eq for SortedIndexMultiMap<I, K, V> {}
+impl<I: Idx, K: PartialEq, V: PartialEq> PartialEq for SortedIndexMultiMap<I, K, V> {
+ fn eq(&self, other: &Self) -> bool {
+ // No need to compare the sorted index. If the items are the same, the index will be too.
+ self.items == other.items
+ }
+}
+
+impl<I: Idx, K, V> Hash for SortedIndexMultiMap<I, K, V>
+where
+ K: Hash,
+ V: Hash,
+{
+ fn hash<H: Hasher>(&self, hasher: &mut H) {
+ self.items.hash(hasher)
+ }
+}
+impl<I: Idx, K, V, C> HashStable<C> for SortedIndexMultiMap<I, K, V>
+where
+ K: HashStable<C>,
+ V: HashStable<C>,
+{
+ fn hash_stable(&self, ctx: &mut C, hasher: &mut StableHasher) {
+ self.items.hash_stable(ctx, hasher)
+ }
+}
+
+impl<I: Idx, K: Ord, V> FromIterator<(K, V)> for SortedIndexMultiMap<I, K, V> {
+ fn from_iter<J>(iter: J) -> Self
+ where
+ J: IntoIterator<Item = (K, V)>,
+ {
+ let items = IndexVec::from_iter(iter);
+ let mut idx_sorted_by_item_key: Vec<_> = items.indices().collect();
+
+ // `sort_by_key` is stable, so insertion order is preserved for duplicate items.
+ idx_sorted_by_item_key.sort_by_key(|&idx| &items[idx].0);
+
+ SortedIndexMultiMap { items, idx_sorted_by_item_key }
+ }
+}
+
+impl<I: Idx, K, V> std::ops::Index<I> for SortedIndexMultiMap<I, K, V> {
+ type Output = V;
+
+ fn index(&self, idx: I) -> &Self::Output {
+ &self.items[idx].1
+ }
+}
+
+#[cfg(tests)]
+mod tests;
diff --git a/src/librustc_data_structures/sorted_map/tests.rs b/src/librustc_data_structures/sorted_map/tests.rs
index 692e1deb..7d91e1f 100644
--- a/src/librustc_data_structures/sorted_map/tests.rs
+++ b/src/librustc_data_structures/sorted_map/tests.rs
@@ -1,4 +1,30 @@
-use super::SortedMap;
+use super::{SortedIndexMultiMap, SortedMap};
+
+#[test]
+fn test_sorted_index_multi_map() {
+ let entries: Vec<_> = vec![(2, 0), (1, 0), (2, 1), (3, 0), (2, 2)];
+ let set: SortedIndexMultiMap<usize, _, _> = entries.iter().copied().collect();
+
+ // Insertion order is preserved.
+ assert!(entries.iter().map(|(ref k, ref v)| (k, v)).eq(set.iter()));
+
+ // Indexing
+ for (i, expect) in entries.iter().enumerate() {
+ assert_eq!(set[i], expect.1);
+ }
+
+ // `get_by_key` works.
+ assert_eq!(set.get_by_key(&3).copied().collect::<Vec<_>>(), vec![0]);
+ assert!(set.get_by_key(&4).next().is_none());
+
+ // `get_by_key` returns items in insertion order.
+ let twos: Vec<_> = set.get_by_key_enumerated(&2).collect();
+ let idxs: Vec<usize> = twos.iter().map(|(i, _)| *i).collect();
+ let values: Vec<usize> = twos.iter().map(|(_, &v)| v).collect();
+
+ assert_eq!(idxs, vec![0, 2, 4]);
+ assert_eq!(values, vec![0, 1, 2]);
+}
#[test]
fn test_insert_and_iter() {
diff --git a/src/librustc_error_codes/error_codes/E0317.md b/src/librustc_error_codes/error_codes/E0317.md
index e31a2b5..230911c 100644
--- a/src/librustc_error_codes/error_codes/E0317.md
+++ b/src/librustc_error_codes/error_codes/E0317.md
@@ -1,14 +1,30 @@
-This error occurs when an `if` expression without an `else` block is used in a
-context where a type other than `()` is expected, for example a `let`
-expression:
+An `if` expression is missing an `else` block.
+
+Erroneous code example:
```compile_fail,E0317
-fn main() {
- let x = 5;
- let a = if x == 5 { 1 };
-}
+let x = 5;
+let a = if x == 5 {
+ 1
+};
```
+This error occurs when an `if` expression without an `else` block is used in a
+context where a type other than `()` is expected. In the previous code example,
+the `let` expression was expecting a value but since there was no `else`, no
+value was returned.
+
An `if` expression without an `else` block has the type `()`, so this is a type
error. To resolve it, add an `else` block having the same type as the `if`
block.
+
+So to fix the previous code example:
+
+```
+let x = 5;
+let a = if x == 5 {
+ 1
+} else {
+ 2
+};
+```
diff --git a/src/librustc_error_codes/error_codes/E0321.md b/src/librustc_error_codes/error_codes/E0321.md
index 49cec94..bfcdabf 100644
--- a/src/librustc_error_codes/error_codes/E0321.md
+++ b/src/librustc_error_codes/error_codes/E0321.md
@@ -1,5 +1,7 @@
A cross-crate opt-out trait was implemented on something which wasn't a struct
-or enum type. Erroneous code example:
+or enum type.
+
+Erroneous code example:
```compile_fail,E0321
#![feature(optin_builtin_traits)]
diff --git a/src/librustc_error_codes/error_codes/E0322.md b/src/librustc_error_codes/error_codes/E0322.md
index d2ee426..ccef868 100644
--- a/src/librustc_error_codes/error_codes/E0322.md
+++ b/src/librustc_error_codes/error_codes/E0322.md
@@ -1,3 +1,13 @@
+The `Sized` trait was implemented explicitly.
+
+Erroneous code example:
+
+```compile_fail,E0322
+struct Foo;
+
+impl Sized for Foo {} // error!
+```
+
The `Sized` trait is a special trait built-in to the compiler for types with a
constant size known at compile-time. This trait is automatically implemented
for types as needed by the compiler, and it is currently disallowed to
diff --git a/src/librustc_error_codes/error_codes/E0323.md b/src/librustc_error_codes/error_codes/E0323.md
index 6d34c35..0bf42d1 100644
--- a/src/librustc_error_codes/error_codes/E0323.md
+++ b/src/librustc_error_codes/error_codes/E0323.md
@@ -1,4 +1,5 @@
An associated const was implemented when another trait item was expected.
+
Erroneous code example:
```compile_fail,E0323
diff --git a/src/librustc_error_codes/error_codes/E0324.md b/src/librustc_error_codes/error_codes/E0324.md
index b8c9e59..1442cb7 100644
--- a/src/librustc_error_codes/error_codes/E0324.md
+++ b/src/librustc_error_codes/error_codes/E0324.md
@@ -1,5 +1,6 @@
-A method was implemented when another trait item was expected. Erroneous
-code example:
+A method was implemented when another trait item was expected.
+
+Erroneous code example:
```compile_fail,E0324
struct Bar;
diff --git a/src/librustc_error_codes/error_codes/E0325.md b/src/librustc_error_codes/error_codes/E0325.md
index f685b92..656fd1e 100644
--- a/src/librustc_error_codes/error_codes/E0325.md
+++ b/src/librustc_error_codes/error_codes/E0325.md
@@ -1,4 +1,5 @@
An associated type was implemented when another trait item was expected.
+
Erroneous code example:
```compile_fail,E0325
diff --git a/src/librustc_error_codes/error_codes/E0326.md b/src/librustc_error_codes/error_codes/E0326.md
index 0702d00..3d35781 100644
--- a/src/librustc_error_codes/error_codes/E0326.md
+++ b/src/librustc_error_codes/error_codes/E0326.md
@@ -1,7 +1,6 @@
-The types of any associated constants in a trait implementation must match the
-types in the trait definition. This error indicates that there was a mismatch.
+An implementation of a trait doesn't match the type contraint.
-Here's an example of this error:
+Erroneous code example:
```compile_fail,E0326
trait Foo {
@@ -14,3 +13,6 @@
const BAR: u32 = 5; // error, expected bool, found u32
}
```
+
+The types of any associated constants in a trait implementation must match the
+types in the trait definition.
diff --git a/src/librustc_hir/hir.rs b/src/librustc_hir/hir.rs
index 56a8e2c..8496a6e 100644
--- a/src/librustc_hir/hir.rs
+++ b/src/librustc_hir/hir.rs
@@ -1,4 +1,4 @@
-use crate::def::{DefKind, Res};
+use crate::def::{DefKind, Namespace, Res};
use crate::def_id::DefId;
crate use crate::hir_id::HirId;
use crate::itemlikevisit;
@@ -1897,6 +1897,15 @@
OpaqueTy(GenericBounds<'hir>),
}
+impl ImplItemKind<'_> {
+ pub fn namespace(&self) -> Namespace {
+ match self {
+ ImplItemKind::OpaqueTy(..) | ImplItemKind::TyAlias(..) => Namespace::TypeNS,
+ ImplItemKind::Const(..) | ImplItemKind::Method(..) => Namespace::ValueNS,
+ }
+ }
+}
+
// The name of the associated type for `Fn` return types.
pub const FN_OUTPUT_NAME: Symbol = sym::Output;
diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs
index c5e7486..1fa57f1 100644
--- a/src/librustc_incremental/persist/dirty_clean.rs
+++ b/src/librustc_incremental/persist/dirty_clean.rs
@@ -78,7 +78,7 @@
const BASE_TRAIT_DEF: &[&str] = &[
label_strs::associated_item_def_ids,
label_strs::generics_of,
- label_strs::is_object_safe,
+ label_strs::object_safety_violations,
label_strs::predicates_of,
label_strs::specialization_graph_of,
label_strs::trait_def,
diff --git a/src/librustc_infer/infer/error_reporting/mod.rs b/src/librustc_infer/infer/error_reporting/mod.rs
index 77119b8..359b417 100644
--- a/src/librustc_infer/infer/error_reporting/mod.rs
+++ b/src/librustc_infer/infer/error_reporting/mod.rs
@@ -52,7 +52,6 @@
use crate::infer::opaque_types;
use crate::infer::{self, SuppressRegionErrors};
use crate::traits::error_reporting::report_object_safety_error;
-use crate::traits::object_safety_violations;
use crate::traits::{
IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode,
};
@@ -1618,7 +1617,7 @@
let failure_code = trace.cause.as_failure_code(terr);
let mut diag = match failure_code {
FailureCode::Error0038(did) => {
- let violations = object_safety_violations(self.tcx, did);
+ let violations = self.tcx.object_safety_violations(did);
report_object_safety_error(self.tcx, span, did, violations)
}
FailureCode::Error0317(failure_str) => {
@@ -1781,14 +1780,7 @@
bound_kind: GenericKind<'tcx>,
sub: S,
) {
- let consider = format!(
- "consider adding an explicit lifetime bound {}",
- if type_param_span.map(|(_, _, is_impl_trait)| is_impl_trait).unwrap_or(false) {
- format!(" `{}` to `{}`...", sub, bound_kind)
- } else {
- format!("`{}: {}`...", bound_kind, sub)
- },
- );
+ let msg = "consider adding an explicit lifetime bound";
if let Some((sp, has_lifetimes, is_impl_trait)) = type_param_span {
let suggestion = if is_impl_trait {
format!("{} + {}", bound_kind, sub)
@@ -1796,13 +1788,22 @@
let tail = if has_lifetimes { " + " } else { "" };
format!("{}: {}{}", bound_kind, sub, tail)
};
- err.span_suggestion_short(
+ err.span_suggestion(
sp,
- &consider,
+ &format!("{}...", msg),
suggestion,
Applicability::MaybeIncorrect, // Issue #41966
);
} else {
+ let consider = format!(
+ "{} {}...",
+ msg,
+ if type_param_span.map(|(_, _, is_impl_trait)| is_impl_trait).unwrap_or(false) {
+ format!(" `{}` to `{}`", sub, bound_kind)
+ } else {
+ format!("`{}: {}`", bound_kind, sub)
+ },
+ );
err.help(&consider);
}
}
diff --git a/src/librustc_infer/traits/error_reporting/mod.rs b/src/librustc_infer/traits/error_reporting/mod.rs
index 4bc8ffc..2fc7c17 100644
--- a/src/librustc_infer/traits/error_reporting/mod.rs
+++ b/src/librustc_infer/traits/error_reporting/mod.rs
@@ -12,7 +12,6 @@
use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode};
use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use crate::infer::{self, InferCtxt, TyCtxtInferExt};
-use crate::traits::object_safety_violations;
use rustc::mir::interpret::ErrorHandled;
use rustc::session::DiagnosticMessageId;
use rustc::ty::error::ExpectedFound;
@@ -748,7 +747,7 @@
}
ty::Predicate::ObjectSafe(trait_def_id) => {
- let violations = object_safety_violations(self.tcx, trait_def_id);
+ let violations = self.tcx.object_safety_violations(trait_def_id);
report_object_safety_error(self.tcx, span, trait_def_id, violations)
}
@@ -912,7 +911,7 @@
}
TraitNotObjectSafe(did) => {
- let violations = object_safety_violations(self.tcx, did);
+ let violations = self.tcx.object_safety_violations(did);
report_object_safety_error(self.tcx, span, did, violations)
}
diff --git a/src/librustc_infer/traits/error_reporting/suggestions.rs b/src/librustc_infer/traits/error_reporting/suggestions.rs
index 50ae7c4..f1206dd 100644
--- a/src/librustc_infer/traits/error_reporting/suggestions.rs
+++ b/src/librustc_infer/traits/error_reporting/suggestions.rs
@@ -5,7 +5,6 @@
use crate::infer::InferCtxt;
use crate::traits::error_reporting::suggest_constraining_type_param;
-use crate::traits::object_safety::object_safety_violations;
use rustc::ty::TypeckTables;
use rustc::ty::{self, AdtKind, DefIdTree, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness};
@@ -587,7 +586,7 @@
// If the `dyn Trait` is not object safe, do not suggest `Box<dyn Trait>`.
predicates
.principal_def_id()
- .map_or(true, |def_id| object_safety_violations(self.tcx, def_id).is_empty())
+ .map_or(true, |def_id| self.tcx.object_safety_violations(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.
diff --git a/src/librustc_infer/traits/mod.rs b/src/librustc_infer/traits/mod.rs
index 06c6d65..fcaab09 100644
--- a/src/librustc_infer/traits/mod.rs
+++ b/src/librustc_infer/traits/mod.rs
@@ -47,7 +47,6 @@
pub use self::fulfill::{FulfillmentContext, PendingPredicateObligation};
pub use self::object_safety::astconv_object_safety_violations;
pub use self::object_safety::is_vtable_safe_method;
-pub use self::object_safety::object_safety_violations;
pub use self::object_safety::MethodViolationCode;
pub use self::object_safety::ObjectSafetyViolation;
pub use self::on_unimplemented::{OnUnimplementedDirective, OnUnimplementedNote};
@@ -537,7 +536,7 @@
tcx.arena.alloc_from_iter(supertraits(tcx, trait_ref).flat_map(move |trait_ref| {
let trait_methods = tcx
.associated_items(trait_ref.def_id())
- .iter()
+ .in_definition_order()
.filter(|item| item.kind == ty::AssocKind::Method);
// Now list each method's DefId and InternalSubsts (for within its trait).
@@ -636,8 +635,8 @@
}
pub fn provide(providers: &mut ty::query::Providers<'_>) {
+ object_safety::provide(providers);
*providers = ty::query::Providers {
- is_object_safe: object_safety::is_object_safe_provider,
specialization_graph_of: specialize::specialization_graph_provider,
specializes: specialize::specializes,
codegen_fulfill_obligation: codegen::codegen_fulfill_obligation,
diff --git a/src/librustc_infer/traits/object_safety.rs b/src/librustc_infer/traits/object_safety.rs
index d36d66e..f5bab7c 100644
--- a/src/librustc_infer/traits/object_safety.rs
+++ b/src/librustc_infer/traits/object_safety.rs
@@ -19,142 +19,12 @@
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, SmallVec};
-use syntax::ast;
+use rustc_span::Span;
+use smallvec::SmallVec;
-use std::borrow::Cow;
-use std::iter::{self};
+use std::iter;
-#[derive(Clone, Debug, PartialEq, Eq, Hash)]
-pub enum ObjectSafetyViolation {
- /// `Self: Sized` declared on the trait.
- SizedSelf(SmallVec<[Span; 1]>),
-
- /// Supertrait reference references `Self` an in illegal location
- /// (e.g., `trait Foo : Bar<Self>`).
- SupertraitSelf(SmallVec<[Span; 1]>),
-
- /// Method has something illegal.
- Method(ast::Name, MethodViolationCode, Span),
-
- /// Associated const.
- AssocConst(ast::Name, Span),
-}
-
-impl ObjectSafetyViolation {
- pub fn error_msg(&self) -> Cow<'static, str> {
- match *self {
- ObjectSafetyViolation::SizedSelf(_) => "it requires `Self: Sized`".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()
- }
- ObjectSafetyViolation::Method(
- name,
- 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,
- _,
- ) => {
- 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(name, DUMMY_SP) => {
- format!("it contains associated `const` `{}`", name).into()
- }
- ObjectSafetyViolation::AssocConst(..) => "it contains this associated `const`".into(),
- }
- }
-
- pub fn solution(&self) -> Option<(String, Option<(String, Span)>)> {
- Some(match *self {
- ObjectSafetyViolation::SizedSelf(_) | ObjectSafetyViolation::SupertraitSelf(_) => {
- return None;
- }
- 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,
- span,
- ) => (
- format!("consider changing method `{}`'s `self` parameter to be `&self`", name)
- .into(),
- Some(("&Self".to_string(), span)),
- ),
- ObjectSafetyViolation::AssocConst(name, _)
- | ObjectSafetyViolation::Method(name, ..) => {
- (format!("consider moving `{}` to another trait", name), None)
- }
- })
- }
-
- 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 {
- ObjectSafetyViolation::SupertraitSelf(spans)
- | ObjectSafetyViolation::SizedSelf(spans) => spans.clone(),
- ObjectSafetyViolation::AssocConst(_, span)
- | ObjectSafetyViolation::Method(_, _, span)
- if *span != DUMMY_SP =>
- {
- smallvec![*span]
- }
- _ => smallvec![],
- }
- }
-}
-
-/// Reasons a method might not be object-safe.
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
-pub enum MethodViolationCode {
- /// e.g., `fn foo()`
- StaticMethod(Option<(&'static str, Span)>),
-
- /// e.g., `fn foo(&self, x: Self)`
- ReferencesSelfInput(usize),
-
- /// e.g., `fn foo(&self) -> Self`
- ReferencesSelfOutput,
-
- /// e.g., `fn foo(&self) where Self: Clone`
- WhereClauseReferencesSelf,
-
- /// e.g., `fn foo<A>()`
- Generic,
-
- /// the method's receiver (`self` argument) can't be dispatched on
- UndispatchableReceiver,
-}
+pub use crate::traits::{MethodViolationCode, ObjectSafetyViolation};
/// Returns the object safety violations that affect
/// astconv -- currently, `Self` in supertraits. This is needed
@@ -176,10 +46,7 @@
violations
}
-pub fn object_safety_violations(
- tcx: TyCtxt<'_>,
- trait_def_id: DefId,
-) -> Vec<ObjectSafetyViolation> {
+fn object_safety_violations(tcx: TyCtxt<'_>, trait_def_id: DefId) -> Vec<ObjectSafetyViolation> {
debug_assert!(tcx.generics_of(trait_def_id).has_self);
debug!("object_safety_violations: {:?}", trait_def_id);
@@ -213,7 +80,7 @@
// Check methods for violations.
let mut violations: Vec<_> = tcx
.associated_items(trait_def_id)
- .iter()
+ .in_definition_order()
.filter(|item| item.kind == ty::AssocKind::Method)
.filter_map(|item| {
object_safety_violation_for_method(tcx, trait_def_id, &item)
@@ -289,7 +156,7 @@
violations.extend(
tcx.associated_items(trait_def_id)
- .iter()
+ .in_definition_order()
.filter(|item| item.kind == ty::AssocKind::Const)
.map(|item| ObjectSafetyViolation::AssocConst(item.ident.name, item.ident.span)),
);
@@ -646,7 +513,7 @@
let mut associated_types = traits::supertraits(tcx, ty::Binder::dummy(trait_ref))
.flat_map(|super_trait_ref| {
tcx.associated_items(super_trait_ref.def_id())
- .iter()
+ .in_definition_order()
.map(move |item| (super_trait_ref, item))
})
.filter(|(_, item)| item.kind == ty::AssocKind::Type)
@@ -905,6 +772,6 @@
error
}
-pub(super) fn is_object_safe_provider(tcx: TyCtxt<'_>, trait_def_id: DefId) -> bool {
- object_safety_violations(tcx, trait_def_id).is_empty()
+pub fn provide(providers: &mut ty::query::Providers<'_>) {
+ *providers = ty::query::Providers { object_safety_violations, ..*providers };
}
diff --git a/src/librustc_infer/traits/util.rs b/src/librustc_infer/traits/util.rs
index c1612a3..1dca01b 100644
--- a/src/librustc_infer/traits/util.rs
+++ b/src/librustc_infer/traits/util.rs
@@ -586,7 +586,7 @@
let mut entries = 0;
// Count number of methods and add them to the total offset.
// Skip over associated types and constants.
- for trait_item in tcx.associated_items(trait_ref.def_id()) {
+ for trait_item in tcx.associated_items(trait_ref.def_id()).in_definition_order() {
if trait_item.kind == ty::AssocKind::Method {
entries += 1;
}
@@ -606,7 +606,7 @@
// add them to the total offset.
// Skip over associated types and constants.
let mut entries = object.vtable_base;
- for trait_item in tcx.associated_items(object.upcast_trait_ref.def_id()) {
+ for trait_item in tcx.associated_items(object.upcast_trait_ref.def_id()).in_definition_order() {
if trait_item.def_id == method_def_id {
// The item with the ID we were given really ought to be a method.
assert_eq!(trait_item.kind, ty::AssocKind::Method);
diff --git a/src/librustc_infer/traits/wf.rs b/src/librustc_infer/traits/wf.rs
index 89a271d..993eb41 100644
--- a/src/librustc_infer/traits/wf.rs
+++ b/src/librustc_infer/traits/wf.rs
@@ -318,7 +318,10 @@
};
if let Elaborate::All = elaborate {
- let trait_assoc_items = tcx.associated_items(trait_ref.def_id);
+ // FIXME: Make `extend_cause_with_original_assoc_item_obligation` take an iterator
+ // instead of a slice.
+ let trait_assoc_items: Vec<_> =
+ tcx.associated_items(trait_ref.def_id).in_definition_order().copied().collect();
let predicates = obligations.iter().map(|obligation| obligation.predicate).collect();
let implied_obligations = traits::elaborate_predicates(tcx, predicates);
@@ -327,7 +330,7 @@
extend_cause_with_original_assoc_item_obligation(
&mut cause,
&pred,
- trait_assoc_items,
+ &*trait_assoc_items,
);
traits::Obligation::new(cause, param_env, pred)
});
diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs
index 2204e10..0e7625d 100644
--- a/src/librustc_lint/lib.rs
+++ b/src/librustc_lint/lib.rs
@@ -305,6 +305,7 @@
store.register_renamed("unstable_name_collision", "unstable_name_collisions");
store.register_renamed("unused_doc_comment", "unused_doc_comments");
store.register_renamed("async_idents", "keyword_idents");
+ store.register_renamed("exceeding_bitshifts", "arithmetic_overflow");
store.register_removed("unknown_features", "replaced by an error");
store.register_removed("unsigned_negation", "replaced by negate_unsigned feature gate");
store.register_removed("negate_unsigned", "cast a signed value instead");
diff --git a/src/librustc_mir/borrow_check/type_check/mod.rs b/src/librustc_mir/borrow_check/type_check/mod.rs
index c924862..f4e1bce 100644
--- a/src/librustc_mir/borrow_check/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/type_check/mod.rs
@@ -313,6 +313,7 @@
);
}
} else {
+ let tcx = self.tcx();
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>,
@@ -362,10 +363,23 @@
);
}
}
- }
- if let ty::FnDef(def_id, substs) = constant.literal.ty.kind {
- let tcx = self.tcx();
+ } else if let Some(static_def_id) = constant.check_static_ptr(tcx) {
+ let unnormalized_ty = tcx.type_of(static_def_id);
+ let locations = location.to_locations();
+ let normalized_ty = self.cx.normalize(unnormalized_ty, locations);
+ let literal_ty = constant.literal.ty.builtin_deref(true).unwrap().ty;
+ if let Err(terr) = self.cx.eq_types(
+ normalized_ty,
+ literal_ty,
+ locations,
+ ConstraintCategory::Boring,
+ ) {
+ span_mirbug!(self, constant, "bad static type {:?} ({:?})", constant, terr);
+ }
+ }
+
+ if let ty::FnDef(def_id, substs) = constant.literal.ty.kind {
let instantiated_predicates = tcx.predicates_of(def_id).instantiate(tcx, substs);
self.cx.normalize_and_prove_instantiated_predicates(
instantiated_predicates,
@@ -470,33 +484,6 @@
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 {
- 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,
- );
- }
- }
-
for elem in place.projection.iter() {
if place_ty.variant_index.is_none() {
if place_ty.ty.references_error() {
@@ -507,6 +494,31 @@
place_ty = self.sanitize_projection(place_ty, elem, place, location)
}
+ if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context {
+ 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,
+ );
+ }
+
place_ty
}
diff --git a/src/librustc_mir/dataflow/impls/storage_liveness.rs b/src/librustc_mir/dataflow/impls/storage_liveness.rs
index 7508d71..659b668 100644
--- a/src/librustc_mir/dataflow/impls/storage_liveness.rs
+++ b/src/librustc_mir/dataflow/impls/storage_liveness.rs
@@ -118,18 +118,25 @@
self.borrowed_locals.borrow().analysis().statement_effect(sets, stmt, loc);
// If a place is assigned to in a statement, it needs storage for that statement.
- match stmt.kind {
- StatementKind::StorageDead(l) => sets.kill(l),
- StatementKind::Assign(box (ref place, _))
- | StatementKind::SetDiscriminant { box ref place, .. } => {
+ match &stmt.kind {
+ StatementKind::StorageDead(l) => sets.kill(*l),
+ StatementKind::Assign(box (place, _))
+ | StatementKind::SetDiscriminant { box place, .. } => {
sets.gen(place.local);
}
- StatementKind::InlineAsm(box InlineAsm { ref outputs, .. }) => {
+ StatementKind::InlineAsm(box InlineAsm { outputs, .. }) => {
for place in &**outputs {
sets.gen(place.local);
}
}
- _ => (),
+
+ // Nothing to do for these. Match exhaustively so this fails to compile when new
+ // variants are added.
+ StatementKind::AscribeUserType(..)
+ | StatementKind::FakeRead(..)
+ | StatementKind::Nop
+ | StatementKind::Retag(..)
+ | StatementKind::StorageLive(..) => {}
}
}
@@ -145,23 +152,58 @@
// If a place is borrowed in a terminator, it needs storage for that terminator.
self.borrowed_locals.borrow().analysis().terminator_effect(sets, terminator, loc);
- if let TerminatorKind::Call { destination: Some((place, _)), .. } = terminator.kind {
- sets.gen(place.local);
+ match &terminator.kind {
+ TerminatorKind::Call { destination: Some((Place { local, .. }, _)), .. }
+ | TerminatorKind::Yield { resume_arg: Place { local, .. }, .. } => {
+ sets.gen(*local);
+ }
+
+ // Nothing to do for these. Match exhaustively so this fails to compile when new
+ // variants are added.
+ TerminatorKind::Call { destination: None, .. }
+ | TerminatorKind::Abort
+ | TerminatorKind::Assert { .. }
+ | TerminatorKind::Drop { .. }
+ | TerminatorKind::DropAndReplace { .. }
+ | TerminatorKind::FalseEdges { .. }
+ | TerminatorKind::FalseUnwind { .. }
+ | TerminatorKind::GeneratorDrop
+ | TerminatorKind::Goto { .. }
+ | TerminatorKind::Resume
+ | TerminatorKind::Return
+ | TerminatorKind::SwitchInt { .. }
+ | TerminatorKind::Unreachable => {}
}
}
fn terminator_effect(&self, sets: &mut GenKillSet<Local>, loc: Location) {
- // For call terminators the destination requires storage for the call
- // and after the call returns successfully, but not after a panic.
- // Since `propagate_call_unwind` doesn't exist, we have to kill the
- // destination here, and then gen it again in `propagate_call_return`.
- if let TerminatorKind::Call { destination: Some((ref place, _)), .. } =
- self.body[loc.block].terminator().kind
- {
- if let Some(local) = place.as_local() {
- sets.kill(local);
+ match &self.body[loc.block].terminator().kind {
+ // For call terminators the destination requires storage for the call
+ // and after the call returns successfully, but not after a panic.
+ // Since `propagate_call_unwind` doesn't exist, we have to kill the
+ // destination here, and then gen it again in `propagate_call_return`.
+ TerminatorKind::Call { destination: Some((Place { local, .. }, _)), .. } => {
+ sets.kill(*local);
}
+
+ // Nothing to do for these. Match exhaustively so this fails to compile when new
+ // variants are added.
+ TerminatorKind::Call { destination: None, .. }
+ | TerminatorKind::Yield { .. }
+ | TerminatorKind::Abort
+ | TerminatorKind::Assert { .. }
+ | TerminatorKind::Drop { .. }
+ | TerminatorKind::DropAndReplace { .. }
+ | TerminatorKind::FalseEdges { .. }
+ | TerminatorKind::FalseUnwind { .. }
+ | TerminatorKind::GeneratorDrop
+ | TerminatorKind::Goto { .. }
+ | TerminatorKind::Resume
+ | TerminatorKind::Return
+ | TerminatorKind::SwitchInt { .. }
+ | TerminatorKind::Unreachable => {}
}
+
self.check_for_move(sets, loc);
}
diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/src/librustc_mir/dataflow/move_paths/builder.rs
index 6f8caca..57aa5de 100644
--- a/src/librustc_mir/dataflow/move_paths/builder.rs
+++ b/src/librustc_mir/dataflow/move_paths/builder.rs
@@ -381,9 +381,9 @@
}
TerminatorKind::Yield { ref value, resume_arg: ref place, .. } => {
+ self.gather_operand(value);
self.create_move_path(place);
self.gather_init(place.as_ref(), InitKind::Deep);
- self.gather_operand(value);
}
TerminatorKind::Drop { ref location, target: _, unwind: _ } => {
diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs
index 0bcdf9a..1df389d 100644
--- a/src/librustc_mir/interpret/memory.rs
+++ b/src/librustc_mir/interpret/memory.rs
@@ -560,7 +560,7 @@
// # Function pointers
// (both global from `alloc_map` and local from `extra_fn_ptr_map`)
- if let Ok(_) = self.get_fn_alloc(id) {
+ if let Some(_) = self.get_fn_alloc(id) {
return if let AllocCheck::Dereferenceable = liveness {
// The caller requested no function pointers.
throw_unsup!(DerefFunctionPointer)
@@ -602,14 +602,14 @@
}
}
- fn get_fn_alloc(&self, id: AllocId) -> InterpResult<'tcx, FnVal<'tcx, M::ExtraFnVal>> {
+ fn get_fn_alloc(&self, id: AllocId) -> Option<FnVal<'tcx, M::ExtraFnVal>> {
trace!("reading fn ptr: {}", id);
if let Some(extra) = self.extra_fn_ptr_map.get(&id) {
- Ok(FnVal::Other(*extra))
+ Some(FnVal::Other(*extra))
} else {
match self.tcx.alloc_map.lock().get(id) {
- Some(GlobalAlloc::Function(instance)) => Ok(FnVal::Instance(instance)),
- _ => throw_unsup!(ExecuteMemory),
+ Some(GlobalAlloc::Function(instance)) => Some(FnVal::Instance(instance)),
+ _ => None,
}
}
}
@@ -622,7 +622,7 @@
if ptr.offset.bytes() != 0 {
throw_unsup!(InvalidFunctionPointer)
}
- self.get_fn_alloc(ptr.alloc_id)
+ self.get_fn_alloc(ptr.alloc_id).ok_or_else(|| err_unsup!(ExecuteMemory).into())
}
pub fn mark_immutable(&mut self, id: AllocId) -> InterpResult<'tcx> {
diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs
index bfd30ff..1f7db28 100644
--- a/src/librustc_mir/shim.rs
+++ b/src/librustc_mir/shim.rs
@@ -68,7 +68,7 @@
let fn_mut = tcx.lang_items().fn_mut_trait().unwrap();
let call_mut = tcx
.associated_items(fn_mut)
- .iter()
+ .in_definition_order()
.find(|it| it.kind == ty::AssocKind::Method)
.unwrap()
.def_id;
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index 91d134f..9e05133 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -4,7 +4,8 @@
use std::borrow::Cow;
use std::cell::Cell;
-use rustc::mir::interpret::{InterpError, InterpResult, Scalar};
+use rustc::lint;
+use rustc::mir::interpret::{InterpResult, Scalar};
use rustc::mir::visit::{
MutVisitor, MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor,
};
@@ -292,7 +293,6 @@
struct ConstPropagator<'mir, 'tcx> {
ecx: InterpCx<'mir, 'tcx, ConstPropMachine>,
tcx: TyCtxt<'tcx>,
- source: MirSource<'tcx>,
can_const_prop: IndexVec<Local, ConstPropMode>,
param_env: ParamEnv<'tcx>,
// FIXME(eddyb) avoid cloning these two fields more than once,
@@ -372,7 +372,6 @@
ConstPropagator {
ecx,
tcx,
- source,
param_env,
can_const_prop,
// FIXME(eddyb) avoid cloning these two fields more than once,
@@ -501,19 +500,20 @@
}
}
- fn report_panic_as_lint(&self, source_info: SourceInfo, panic: AssertKind<u64>) -> Option<()> {
- // Somewhat convoluted way to re-use the CTFE error reporting code.
+ fn report_assert_as_lint(
+ &self,
+ lint: &'static lint::Lint,
+ source_info: SourceInfo,
+ message: &'static str,
+ panic: AssertKind<u64>,
+ ) -> Option<()> {
let lint_root = self.lint_root(source_info)?;
- let error = InterpError::MachineStop(Box::new(format!("{:?}", panic)));
- let mut diagnostic = error_to_const_error(&self.ecx, error.into());
- diagnostic.span = source_info.span; // fix the span
- diagnostic.report_as_lint(
- self.tcx.at(source_info.span),
- "this expression will panic at runtime",
- lint_root,
- None,
- );
- None
+ self.tcx.struct_span_lint_hir(lint, lint_root, source_info.span, |lint| {
+ let mut err = lint.build(message);
+ err.span_label(source_info.span, format!("{:?}", panic));
+ err.emit()
+ });
+ return None;
}
fn check_unary_op(
@@ -530,7 +530,12 @@
// `AssertKind` only has an `OverflowNeg` variant, so make sure that is
// appropriate to use.
assert_eq!(op, UnOp::Neg, "Neg is the only UnOp that can overflow");
- self.report_panic_as_lint(source_info, AssertKind::OverflowNeg)?;
+ self.report_assert_as_lint(
+ lint::builtin::ARITHMETIC_OVERFLOW,
+ source_info,
+ "this arithmetic operation will overflow",
+ AssertKind::OverflowNeg,
+ )?;
}
Some(())
@@ -542,27 +547,24 @@
left: &Operand<'tcx>,
right: &Operand<'tcx>,
source_info: SourceInfo,
- place_layout: TyLayout<'tcx>,
) -> Option<()> {
let r =
self.use_ecx(|this| this.ecx.read_immediate(this.ecx.eval_operand(right, None)?))?;
// Check for exceeding shifts *even if* we cannot evaluate the LHS.
if op == BinOp::Shr || op == BinOp::Shl {
- let left_bits = place_layout.size.bits();
+ // We need the type of the LHS. We cannot use `place_layout` as that is the type
+ // of the result, which for checked binops is not the same!
+ let left_ty = left.ty(&self.local_decls, self.tcx);
+ let left_size_bits = self.ecx.layout_of(left_ty).ok()?.size.bits();
let right_size = r.layout.size;
let r_bits = r.to_scalar().and_then(|r| r.to_bits(right_size));
- if r_bits.map_or(false, |b| b >= left_bits as u128) {
- let lint_root = self.lint_root(source_info)?;
- self.tcx.struct_span_lint_hir(
- ::rustc::lint::builtin::EXCEEDING_BITSHIFTS,
- lint_root,
- source_info.span,
- |lint| {
- let dir = if op == BinOp::Shr { "right" } else { "left" };
- lint.build(&format!("attempt to shift {} with overflow", dir)).emit()
- },
- );
- return None;
+ if r_bits.map_or(false, |b| b >= left_size_bits as u128) {
+ self.report_assert_as_lint(
+ lint::builtin::ARITHMETIC_OVERFLOW,
+ source_info,
+ "this arithmetic operation will overflow",
+ AssertKind::Overflow(op),
+ )?;
}
}
@@ -572,7 +574,12 @@
let (_res, overflow, _ty) = this.ecx.overflowing_binary_op(op, l, r)?;
Ok(overflow)
})? {
- self.report_panic_as_lint(source_info, AssertKind::Overflow(op))?;
+ self.report_assert_as_lint(
+ lint::builtin::ARITHMETIC_OVERFLOW,
+ source_info,
+ "this arithmetic operation will overflow",
+ AssertKind::Overflow(op),
+ )?;
}
Some(())
@@ -595,8 +602,6 @@
return None;
}
- let overflow_check = self.tcx.sess.overflow_checks();
-
// Perform any special handling for specific Rvalue types.
// Generally, checks here fall into one of two categories:
// 1. Additional checking to provide useful lints to the user
@@ -606,20 +611,25 @@
// - In this case, we'll return `None` from this function to stop evaluation.
match rvalue {
// Additional checking: give lints to the user if an overflow would occur.
- // If `overflow_check` is set, running const-prop on the `Assert` terminators
- // will already generate the appropriate messages.
- Rvalue::UnaryOp(op, arg) if !overflow_check => {
+ // We do this here and not in the `Assert` terminator as that terminator is
+ // only sometimes emitted (overflow checks can be disabled), but we want to always
+ // lint.
+ Rvalue::UnaryOp(op, arg) => {
trace!("checking UnaryOp(op = {:?}, arg = {:?})", op, arg);
self.check_unary_op(*op, arg, source_info)?;
}
-
- // Additional checking: check for overflows on integer binary operations and report
- // them to the user as lints.
- // If `overflow_check` is set, running const-prop on the `Assert` terminators
- // will already generate the appropriate messages.
- Rvalue::BinaryOp(op, left, right) if !overflow_check => {
+ Rvalue::BinaryOp(op, left, right) => {
trace!("checking BinaryOp(op = {:?}, left = {:?}, right = {:?})", op, left, right);
- self.check_binary_op(*op, left, right, source_info, place_layout)?;
+ self.check_binary_op(*op, left, right, source_info)?;
+ }
+ Rvalue::CheckedBinaryOp(op, left, right) => {
+ trace!(
+ "checking CheckedBinaryOp(op = {:?}, left = {:?}, right = {:?})",
+ op,
+ left,
+ right
+ );
+ self.check_binary_op(*op, left, right, source_info)?;
}
// Do not try creating references (#67862)
@@ -898,54 +908,39 @@
}
Operand::Constant(_) => {}
}
- let span = terminator.source_info.span;
- let hir_id = self
- .tcx
- .hir()
- .as_local_hir_id(self.source.def_id())
- .expect("some part of a failing const eval must be local");
- self.tcx.struct_span_lint_hir(
- ::rustc::lint::builtin::CONST_ERR,
- hir_id,
- span,
- |lint| {
- let msg = match msg {
- AssertKind::Overflow(_)
- | AssertKind::OverflowNeg
- | AssertKind::DivisionByZero
- | AssertKind::RemainderByZero => msg.description().to_owned(),
- AssertKind::BoundsCheck { ref len, ref index } => {
- let len = self
- .eval_operand(len, source_info)
- .expect("len must be const");
- let len = match self.ecx.read_scalar(len) {
- Ok(ScalarMaybeUndef::Scalar(Scalar::Raw {
- data,
- ..
- })) => data,
- other => bug!("const len not primitive: {:?}", other),
- };
- let index = self
- .eval_operand(index, source_info)
- .expect("index must be const");
- let index = match self.ecx.read_scalar(index) {
- Ok(ScalarMaybeUndef::Scalar(Scalar::Raw {
- data,
- ..
- })) => data,
- other => bug!("const index not primitive: {:?}", other),
- };
- format!(
- "index out of bounds: \
- the len is {} but the index is {}",
- len, index,
- )
- }
- // Need proper const propagator for these
- _ => return,
- };
- lint.build(&msg).emit()
- },
+ let msg = match msg {
+ AssertKind::DivisionByZero => AssertKind::DivisionByZero,
+ AssertKind::RemainderByZero => AssertKind::RemainderByZero,
+ AssertKind::BoundsCheck { ref len, ref index } => {
+ let len =
+ self.eval_operand(len, source_info).expect("len must be const");
+ let len = self
+ .ecx
+ .read_scalar(len)
+ .unwrap()
+ .to_machine_usize(&self.tcx)
+ .unwrap();
+ let index = self
+ .eval_operand(index, source_info)
+ .expect("index must be const");
+ let index = self
+ .ecx
+ .read_scalar(index)
+ .unwrap()
+ .to_machine_usize(&self.tcx)
+ .unwrap();
+ AssertKind::BoundsCheck { len, index }
+ }
+ // Overflow is are already covered by checks on the binary operators.
+ AssertKind::Overflow(_) | AssertKind::OverflowNeg => return,
+ // Need proper const propagator for these.
+ _ => return,
+ };
+ self.report_assert_as_lint(
+ lint::builtin::UNCONDITIONAL_PANIC,
+ source_info,
+ "this operation will panic at runtime",
+ msg,
);
} else {
if self.should_const_prop(value) {
diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs
index b3dc87d..3621ca6 100644
--- a/src/librustc_mir/transform/generator.rs
+++ b/src/librustc_mir/transform/generator.rs
@@ -186,18 +186,24 @@
Local::new(1)
}
-/// Generator have not been resumed yet
+/// Generator has not been resumed yet.
const UNRESUMED: usize = GeneratorSubsts::UNRESUMED;
-/// Generator has returned / is completed
+/// Generator has returned / is completed.
const RETURNED: usize = GeneratorSubsts::RETURNED;
-/// Generator has been poisoned
+/// Generator has panicked and is poisoned.
const POISONED: usize = GeneratorSubsts::POISONED;
+/// A `yield` point in the generator.
struct SuspensionPoint<'tcx> {
+ /// State discriminant used when suspending or resuming at this point.
state: usize,
+ /// The block to jump to after resumption.
resume: BasicBlock,
+ /// Where to move the resume argument after resumption.
resume_arg: Place<'tcx>,
+ /// Which block to jump to if the generator is dropped in this state.
drop: Option<BasicBlock>,
+ /// Set of locals that have live storage while at this suspension point.
storage_liveness: liveness::LiveVarSet,
}
@@ -325,6 +331,15 @@
// Yield
let state = 3 + self.suspension_points.len();
+ // The resume arg target location might itself be remapped if its base local is
+ // live across a yield.
+ let resume_arg =
+ if let Some(&(ty, variant, idx)) = self.remap.get(&resume_arg.local) {
+ self.make_field(variant, idx, ty)
+ } else {
+ resume_arg
+ };
+
self.suspension_points.push(SuspensionPoint {
state,
resume,
diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs
index 091ae1b..fab64e3 100644
--- a/src/librustc_mir/util/elaborate_drops.rs
+++ b/src/librustc_mir/util/elaborate_drops.rs
@@ -539,7 +539,7 @@
debug!("destructor_call_block({:?}, {:?})", self, succ);
let tcx = self.tcx();
let drop_trait = tcx.lang_items().drop_trait().unwrap();
- let drop_fn = tcx.associated_items(drop_trait)[0];
+ let drop_fn = tcx.associated_items(drop_trait).in_definition_order().nth(0).unwrap();
let ty = self.place_ty(self.place);
let substs = tcx.mk_substs_trait(ty, &[]);
diff --git a/src/librustc_mir_build/hair/constant.rs b/src/librustc_mir_build/hair/constant.rs
index e594e1e..e9dd785 100644
--- a/src/librustc_mir_build/hair/constant.rs
+++ b/src/librustc_mir_build/hair/constant.rs
@@ -1,7 +1,7 @@
use rustc::mir::interpret::{
truncate, Allocation, ConstValue, LitToConstError, LitToConstInput, Scalar,
};
-use rustc::ty::{self, layout::Size, ParamEnv, TyCtxt};
+use rustc::ty::{self, layout::Size, ParamEnv, TyCtxt, TyS};
use rustc_span::symbol::Symbol;
use syntax::ast;
@@ -20,50 +20,35 @@
Ok(ConstValue::Scalar(Scalar::from_uint(result, width)))
};
- let lit = match *lit {
- ast::LitKind::Str(ref s, _) => {
+ let lit = match (lit, &ty.kind) {
+ (ast::LitKind::Str(s, _), ty::Ref(_, TyS { kind: ty::Str, .. }, _)) => {
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() }
}
- 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<u8>);
- 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)
- }
+ (ast::LitKind::ByteStr(data), ty::Ref(_, TyS { kind: ty::Slice(_), .. }, _)) => {
+ let allocation = Allocation::from_byte_aligned_bytes(data as &Vec<u8>);
+ let allocation = tcx.intern_const_alloc(allocation);
+ ConstValue::Slice { data: allocation, start: 0, end: data.len() }
}
- 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)?
+ (ast::LitKind::ByteStr(data), ty::Ref(_, TyS { kind: ty::Array(_, _), .. }, _)) => {
+ let id = tcx.allocate_bytes(data);
+ ConstValue::Scalar(Scalar::Ptr(id.into()))
}
- 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)?
+ (ast::LitKind::Byte(n), ty::Uint(ast::UintTy::U8)) => {
+ ConstValue::Scalar(Scalar::from_uint(*n, Size::from_bytes(1)))
}
- 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),
+ (ast::LitKind::Int(n, _), ty::Uint(_)) | (ast::LitKind::Int(n, _), ty::Int(_)) => {
+ trunc(if neg { (*n as i128).overflowing_neg().0 as u128 } else { *n })?
+ }
+ (ast::LitKind::Float(n, _), ty::Float(fty)) => {
+ parse_float(*n, *fty, neg).map_err(|_| LitToConstError::UnparseableFloat)?
+ }
+ (ast::LitKind::Bool(b), ty::Bool) => ConstValue::Scalar(Scalar::from_bool(*b)),
+ (ast::LitKind::Char(c), ty::Char) => ConstValue::Scalar(Scalar::from_char(*c)),
+ (ast::LitKind::Err(_), _) => return Err(LitToConstError::Reported),
+ _ => return Err(LitToConstError::TypeError),
};
Ok(ty::Const::from_value(tcx, lit, ty))
}
diff --git a/src/librustc_mir_build/hair/cx/mod.rs b/src/librustc_mir_build/hair/cx/mod.rs
index ee62af7..f486073 100644
--- a/src/librustc_mir_build/hair/cx/mod.rs
+++ b/src/librustc_mir_build/hair/cx/mod.rs
@@ -148,6 +148,7 @@
// create a dummy value and continue compiling
Const::from_bits(self.tcx, 0, self.param_env.and(ty))
}
+ Err(LitToConstError::TypeError) => bug!("const_eval_literal: had type error"),
}
}
@@ -167,17 +168,19 @@
params: &[GenericArg<'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);
- return ty::Const::zero_sized(self.tcx, method_ty);
- }
- }
- bug!("found no method `{}` in `{:?}`", method_name, trait_def_id);
+ // The unhygienic comparison here is acceptable because this is only
+ // used on known traits.
+ let item = self
+ .tcx
+ .associated_items(trait_def_id)
+ .filter_by_name_unhygienic(method_name)
+ .find(|item| item.kind == ty::AssocKind::Method)
+ .expect("trait method not found");
+
+ let method_ty = self.tcx.type_of(item.def_id);
+ let method_ty = method_ty.subst(self.tcx, substs);
+ ty::Const::zero_sized(self.tcx, method_ty)
}
crate fn all_fields(&mut self, adt_def: &ty::AdtDef, variant_index: VariantIdx) -> Vec<Field> {
diff --git a/src/librustc_mir_build/hair/pattern/check_match.rs b/src/librustc_mir_build/hair/pattern/check_match.rs
index 651f2f7..3dfe826 100644
--- a/src/librustc_mir_build/hair/pattern/check_match.rs
+++ b/src/librustc_mir_build/hair/pattern/check_match.rs
@@ -659,7 +659,7 @@
});
if !conflicts_ref.is_empty() {
let occurs_because = format!(
- "move occurs because `{}` has type `{}` which does implement the `Copy` trait",
+ "move occurs because `{}` has type `{}` which does not implement the `Copy` trait",
name,
tables.node_type(pat.hir_id),
);
diff --git a/src/librustc_mir_build/hair/pattern/mod.rs b/src/librustc_mir_build/hair/pattern/mod.rs
index 9101174..6979a98 100644
--- a/src/librustc_mir_build/hair/pattern/mod.rs
+++ b/src/librustc_mir_build/hair/pattern/mod.rs
@@ -846,6 +846,7 @@
PatKind::Wild
}
Err(LitToConstError::Reported) => PatKind::Wild,
+ Err(LitToConstError::TypeError) => bug!("lower_lit: had type error"),
}
}
}
diff --git a/src/librustc_passes/region.rs b/src/librustc_passes/region.rs
index e79ca5c..d0f49fd 100644
--- a/src/librustc_passes/region.rs
+++ b/src/librustc_passes/region.rs
@@ -4,7 +4,7 @@
//! For more information about how MIR-based region-checking works,
//! see the [rustc guide].
//!
-//! [rustc guide]: https://rust-lang.github.io/rustc-guide/mir/borrowck.html
+//! [rustc guide]: https://rust-lang.github.io/rustc-guide/borrow_check.html
use rustc::hir::map::Map;
use rustc::middle::region::*;
diff --git a/src/librustc_passes/stability.rs b/src/librustc_passes/stability.rs
index d9296de..0c7f64f 100644
--- a/src/librustc_passes/stability.rs
+++ b/src/librustc_passes/stability.rs
@@ -523,8 +523,8 @@
let trait_item_def_id = self
.tcx
.associated_items(trait_did)
- .iter()
- .find(|item| item.ident.name == impl_item.ident.name)
+ .filter_by_name_unhygienic(impl_item.ident.name)
+ .next()
.map(|item| item.def_id);
if let Some(def_id) = trait_item_def_id {
// Pass `None` to skip deprecation warnings.
diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs
index 6a34e47..6e7ecf9 100644
--- a/src/librustc_save_analysis/lib.rs
+++ b/src/librustc_save_analysis/lib.rs
@@ -408,7 +408,6 @@
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;
let mut docs = String::new();
let mut attrs = vec![];
let hir_id = self.tcx.hir().node_to_hir_id(id);
@@ -417,15 +416,18 @@
attrs = item.attrs.to_vec();
}
+ let mut decl_id = None;
if let Some(def_id) = trait_id {
// A method in a trait impl.
qualname.push_str(" as ");
qualname.push_str(&self.tcx.def_path_str(def_id));
- self.tcx
+
+ decl_id = self
+ .tcx
.associated_items(def_id)
- .iter()
- .find(|item| item.ident.name == ident.name)
- .map(|item| decl_id = Some(item.def_id));
+ .filter_by_name_unhygienic(ident.name)
+ .next()
+ .map(|item| item.def_id);
}
qualname.push_str(">");
@@ -716,12 +718,11 @@
Res::Def(HirDefKind::Method, decl_id) => {
let def_id = if decl_id.is_local() {
let ti = self.tcx.associated_item(decl_id);
+
self.tcx
.associated_items(ti.container.id())
- .iter()
- .find(|item| {
- item.ident.name == ti.ident.name && item.defaultness.has_value()
- })
+ .filter_by_name_unhygienic(ti.ident.name)
+ .find(|item| item.defaultness.has_value())
.map(|item| item.def_id)
} else {
None
diff --git a/src/librustc_session/lint/builtin.rs b/src/librustc_session/lint/builtin.rs
index 5a360b4..603ed46 100644
--- a/src/librustc_session/lint/builtin.rs
+++ b/src/librustc_session/lint/builtin.rs
@@ -41,9 +41,15 @@
}
declare_lint! {
- pub EXCEEDING_BITSHIFTS,
+ pub ARITHMETIC_OVERFLOW,
Deny,
- "shift exceeds the type's number of bits"
+ "arithmetic operation overflows"
+}
+
+declare_lint! {
+ pub UNCONDITIONAL_PANIC,
+ Deny,
+ "operation will cause a panic at runtime"
}
declare_lint! {
@@ -495,7 +501,8 @@
/// that are used by other parts of the compiler.
HardwiredLints => [
ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
- EXCEEDING_BITSHIFTS,
+ ARITHMETIC_OVERFLOW,
+ UNCONDITIONAL_PANIC,
UNUSED_IMPORTS,
UNUSED_EXTERN_CRATES,
UNUSED_QUALIFICATIONS,
diff --git a/src/librustc_span/lib.rs b/src/librustc_span/lib.rs
index 8f00b76..f9f3a90 100644
--- a/src/librustc_span/lib.rs
+++ b/src/librustc_span/lib.rs
@@ -1075,7 +1075,7 @@
unmapped_path: FileName,
mut src: String,
start_pos: BytePos,
- ) -> Result<SourceFile, OffsetOverflowError> {
+ ) -> Self {
let normalized_pos = normalize_src(&mut src, start_pos);
let src_hash = {
@@ -1089,14 +1089,12 @@
hasher.finish::<u128>()
};
let end_pos = start_pos.to_usize() + src.len();
- if end_pos > u32::max_value() as usize {
- return Err(OffsetOverflowError);
- }
+ assert!(end_pos <= u32::max_value() as usize);
let (lines, multibyte_chars, non_narrow_chars) =
analyze_source_file::analyze_source_file(&src[..], start_pos);
- Ok(SourceFile {
+ SourceFile {
name,
name_was_remapped,
unmapped_path: Some(unmapped_path),
@@ -1111,7 +1109,7 @@
non_narrow_chars,
normalized_pos,
name_hash,
- })
+ }
}
/// Returns the `BytePos` of the beginning of the current line.
diff --git a/src/librustc_span/source_map.rs b/src/librustc_span/source_map.rs
index 45c4d6d..31d397f 100644
--- a/src/librustc_span/source_map.rs
+++ b/src/librustc_span/source_map.rs
@@ -12,10 +12,12 @@
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stable_hasher::StableHasher;
-use rustc_data_structures::sync::{Lock, LockGuard, Lrc, MappedLockGuard};
+use rustc_data_structures::sync::{AtomicU32, Lock, LockGuard, Lrc, MappedLockGuard};
use std::cmp;
+use std::convert::TryFrom;
use std::hash::Hash;
use std::path::{Path, PathBuf};
+use std::sync::atomic::Ordering;
use log::debug;
use std::env;
@@ -131,6 +133,9 @@
}
pub struct SourceMap {
+ /// The address space below this value is currently used by the files in the source map.
+ used_address_space: AtomicU32,
+
files: Lock<SourceMapFiles>,
file_loader: Box<dyn FileLoader + Sync + Send>,
// This is used to apply the file path remapping as specified via
@@ -140,14 +145,24 @@
impl SourceMap {
pub fn new(path_mapping: FilePathMapping) -> SourceMap {
- SourceMap { files: Default::default(), file_loader: Box::new(RealFileLoader), path_mapping }
+ SourceMap {
+ used_address_space: AtomicU32::new(0),
+ files: Default::default(),
+ file_loader: Box::new(RealFileLoader),
+ path_mapping,
+ }
}
pub fn with_file_loader(
file_loader: Box<dyn FileLoader + Sync + Send>,
path_mapping: FilePathMapping,
) -> SourceMap {
- SourceMap { files: Default::default(), file_loader, path_mapping }
+ SourceMap {
+ used_address_space: AtomicU32::new(0),
+ files: Default::default(),
+ file_loader,
+ path_mapping,
+ }
}
pub fn path_mapping(&self) -> &FilePathMapping {
@@ -194,12 +209,25 @@
self.files.borrow().stable_id_to_source_file.get(&stable_id).map(|sf| sf.clone())
}
- fn next_start_pos(&self) -> usize {
- match self.files.borrow().source_files.last() {
- None => 0,
- // Add one so there is some space between files. This lets us distinguish
- // positions in the `SourceMap`, even in the presence of zero-length files.
- Some(last) => last.end_pos.to_usize() + 1,
+ fn allocate_address_space(&self, size: usize) -> Result<usize, OffsetOverflowError> {
+ let size = u32::try_from(size).map_err(|_| OffsetOverflowError)?;
+
+ loop {
+ let current = self.used_address_space.load(Ordering::Relaxed);
+ let next = current
+ .checked_add(size)
+ // Add one so there is some space between files. This lets us distinguish
+ // positions in the `SourceMap`, even in the presence of zero-length files.
+ .and_then(|next| next.checked_add(1))
+ .ok_or(OffsetOverflowError)?;
+
+ if self
+ .used_address_space
+ .compare_exchange(current, next, Ordering::Relaxed, Ordering::Relaxed)
+ .is_ok()
+ {
+ return Ok(usize::try_from(current).unwrap());
+ }
}
}
@@ -218,8 +246,6 @@
filename: FileName,
src: String,
) -> Result<Lrc<SourceFile>, OffsetOverflowError> {
- let start_pos = self.next_start_pos();
-
// The path is used to determine the directory for loading submodules and
// include files, so it must be before remapping.
// Note that filename may not be a valid path, eg it may be `<anon>` etc,
@@ -241,13 +267,15 @@
let lrc_sf = match self.source_file_by_stable_id(file_id) {
Some(lrc_sf) => lrc_sf,
None => {
+ let start_pos = self.allocate_address_space(src.len())?;
+
let source_file = Lrc::new(SourceFile::new(
filename,
was_remapped,
unmapped_path,
src,
Pos::from_usize(start_pos),
- )?);
+ ));
let mut files = self.files.borrow_mut();
@@ -277,7 +305,9 @@
mut file_local_non_narrow_chars: Vec<NonNarrowChar>,
mut file_local_normalized_pos: Vec<NormalizedPos>,
) -> Lrc<SourceFile> {
- let start_pos = self.next_start_pos();
+ let start_pos = self
+ .allocate_address_space(source_len)
+ .expect("not enough address space for imported source file");
let end_pos = Pos::from_usize(start_pos + source_len);
let start_pos = Pos::from_usize(start_pos);
diff --git a/src/librustc_ty/ty.rs b/src/librustc_ty/ty.rs
index f9b2ee3..d466bbc 100644
--- a/src/librustc_ty/ty.rs
+++ b/src/librustc_ty/ty.rs
@@ -210,10 +210,9 @@
}
}
-fn associated_items<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx [ty::AssocItem] {
- tcx.arena.alloc_from_iter(
- tcx.associated_item_def_ids(def_id).iter().map(|did| tcx.associated_item(*did)),
- )
+fn associated_items<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::AssociatedItems {
+ let items = tcx.associated_item_def_ids(def_id).iter().map(|did| tcx.associated_item(*did));
+ tcx.arena.alloc(ty::AssociatedItems::new(items))
}
fn def_span(tcx: TyCtxt<'_>, def_id: DefId) -> Span {
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 69970fa..78c05a5 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -9,7 +9,6 @@
use crate::lint;
use crate::middle::lang_items::SizedTraitLangItem;
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 rustc::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
@@ -20,7 +19,7 @@
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::{CtorOf, DefKind, Namespace, Res};
use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::Visitor;
use rustc_hir::print;
@@ -1109,10 +1108,10 @@
trait_def_id: DefId,
assoc_name: ast::Ident,
) -> bool {
- self.tcx().associated_items(trait_def_id).iter().any(|item| {
- item.kind == ty::AssocKind::Type
- && self.tcx().hygienic_eq(assoc_name, item.ident, trait_def_id)
- })
+ self.tcx()
+ .associated_items(trait_def_id)
+ .find_by_name_and_kind(self.tcx(), assoc_name, ty::AssocKind::Type, trait_def_id)
+ .is_some()
}
// Returns `true` if a bounds list includes `?Sized`.
@@ -1345,9 +1344,12 @@
let (assoc_ident, def_scope) =
tcx.adjust_ident_and_get_scope(binding.item_name, candidate.def_id(), hir_ref_id);
+
+ // We have already adjusted the item name above, so compare with `ident.modern()` instead
+ // of calling `filter_by_name_and_kind`.
let assoc_ty = tcx
.associated_items(candidate.def_id())
- .iter()
+ .filter_by_name_unhygienic(assoc_ident.name)
.find(|i| i.kind == ty::AssocKind::Type && i.ident.modern() == assoc_ident)
.expect("missing associated type");
@@ -1513,7 +1515,7 @@
ty::Predicate::Trait(pred, _) => {
associated_types.entry(span).or_default().extend(
tcx.associated_items(pred.def_id())
- .iter()
+ .in_definition_order()
.filter(|item| item.kind == ty::AssocKind::Type)
.map(|item| item.def_id),
);
@@ -1968,14 +1970,11 @@
let mut where_bounds = vec![];
for bound in bounds {
+ let bound_id = bound.def_id();
let bound_span = self
.tcx()
- .associated_items(bound.def_id())
- .iter()
- .find(|item| {
- item.kind == ty::AssocKind::Type
- && self.tcx().hygienic_eq(assoc_name, item.ident, bound.def_id())
- })
+ .associated_items(bound_id)
+ .find_by_name_and_kind(self.tcx(), assoc_name, ty::AssocKind::Type, bound_id)
.and_then(|item| self.tcx().hir().span_if_local(item.def_id));
if let Some(bound_span) = bound_span {
@@ -2053,7 +2052,7 @@
);
let all_candidate_names: Vec<_> = all_candidates()
- .map(|r| self.tcx().associated_items(r.def_id()))
+ .map(|r| self.tcx().associated_items(r.def_id()).in_definition_order())
.flatten()
.filter_map(
|item| if item.kind == ty::AssocKind::Type { Some(item.ident.name) } else { None },
@@ -2199,10 +2198,13 @@
let trait_did = bound.def_id();
let (assoc_ident, def_scope) =
tcx.adjust_ident_and_get_scope(assoc_ident, trait_did, hir_ref_id);
+
+ // We have already adjusted the item name above, so compare with `ident.modern()` instead
+ // of calling `filter_by_name_and_kind`.
let item = tcx
.associated_items(trait_did)
- .iter()
- .find(|i| Namespace::from(i.kind) == Namespace::Type && i.ident.modern() == assoc_ident)
+ .in_definition_order()
+ .find(|i| i.kind.namespace() == Namespace::TypeNS && i.ident.modern() == assoc_ident)
.expect("missing associated type");
let ty = self.projected_ty_from_poly_trait_ref(span, item.def_id, assoc_segment, bound);
@@ -2740,6 +2742,8 @@
// mir.
if let Ok(c) = tcx.at(expr.span).lit_to_const(lit_input) {
return c;
+ } else {
+ tcx.sess.delay_span_bug(expr.span, "ast_const_to_const: couldn't lit_to_const");
}
}
diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs
index 18f6a78..a67ceb8 100644
--- a/src/librustc_typeck/check/cast.rs
+++ b/src/librustc_typeck/check/cast.rs
@@ -45,7 +45,6 @@
use rustc_hir as hir;
use rustc_infer::traits;
use rustc_infer::traits::error_reporting::report_object_safety_error;
-use rustc_infer::traits::object_safety_violations;
use rustc_span::Span;
use syntax::ast;
@@ -517,7 +516,7 @@
}
fn report_object_unsafe_cast(&self, fcx: &FnCtxt<'a, 'tcx>, did: DefId) {
- let violations = object_safety_violations(fcx.tcx, did);
+ let violations = fcx.tcx.object_safety_violations(did);
let mut err = report_object_safety_error(fcx.tcx, self.cast_span, did, violations);
err.note(&format!("required by cast to type '{}'", fcx.ty_to_string(self.cast_ty)));
err.emit();
diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs
index e17c65f..816de5d 100644
--- a/src/librustc_typeck/check/closure.rs
+++ b/src/librustc_typeck/check/closure.rs
@@ -248,7 +248,8 @@
if is_gen {
// Check that we deduce the signature from the `<_ as std::ops::Generator>::Return`
// associated item and not yield.
- let return_assoc_item = self.tcx.associated_items(gen_trait)[1].def_id;
+ let return_assoc_item =
+ self.tcx.associated_items(gen_trait).in_definition_order().nth(1).unwrap().def_id;
if return_assoc_item != projection.projection_def_id() {
debug!("deduce_sig_from_projection: not return assoc item of generator");
return None;
@@ -673,7 +674,8 @@
// The `Future` trait has only one associted item, `Output`,
// so check that this is what we see.
- let output_assoc_item = self.tcx.associated_items(future_trait)[0].def_id;
+ let output_assoc_item =
+ self.tcx.associated_items(future_trait).in_definition_order().nth(0).unwrap().def_id;
if output_assoc_item != predicate.projection_ty.item_def_id {
span_bug!(
cause_span,
diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs
index c327a79..3720b74 100644
--- a/src/librustc_typeck/check/coercion.rs
+++ b/src/librustc_typeck/check/coercion.rs
@@ -66,7 +66,6 @@
use rustc_hir::def_id::DefId;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::infer::{Coercion, InferOk, InferResult};
-use rustc_infer::traits::object_safety_violations;
use rustc_infer::traits::{self, ObligationCause, ObligationCauseCode};
use rustc_span::symbol::sym;
use rustc_span::{self, Span};
@@ -1404,7 +1403,7 @@
// 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()
+ fcx.tcx.object_safety_violations(def_id).is_empty()
})
})
}
diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs
index bf74ab6..63ebf61 100644
--- a/src/librustc_typeck/check/demand.rs
+++ b/src/librustc_typeck/check/demand.rs
@@ -539,7 +539,7 @@
let item_def_id = self
.tcx
.associated_items(deref_trait)
- .iter()
+ .in_definition_order()
.find(|item| item.kind == ty::AssocKind::Type)
.unwrap()
.def_id;
diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs
index 1856157..de82464 100644
--- a/src/librustc_typeck/check/method/mod.rs
+++ b/src/librustc_typeck/check/method/mod.rs
@@ -11,7 +11,6 @@
pub use self::MethodError::*;
use crate::check::FnCtxt;
-use crate::namespace::Namespace;
use rustc::ty::subst::Subst;
use rustc::ty::subst::{InternalSubsts, SubstsRef};
use rustc::ty::GenericParamDefKind;
@@ -19,7 +18,7 @@
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::{CtorOf, DefKind, Namespace};
use rustc_hir::def_id::DefId;
use rustc_infer::infer::{self, InferOk};
use rustc_infer::traits;
@@ -342,7 +341,7 @@
// Trait must have a method named `m_name` and it should not have
// type parameters or early-bound regions.
let tcx = self.tcx;
- let method_item = match self.associated_item(trait_def_id, m_name, Namespace::Value) {
+ let method_item = match self.associated_item(trait_def_id, m_name, Namespace::ValueNS) {
Some(method_item) => method_item,
None => {
tcx.sess.delay_span_bug(
@@ -484,11 +483,7 @@
) -> Option<ty::AssocItem> {
self.tcx
.associated_items(def_id)
- .iter()
- .find(|item| {
- Namespace::from(item.kind) == ns
- && self.tcx.hygienic_eq(item_name, item.ident, def_id)
- })
+ .find_by_name_and_namespace(self.tcx, item_name, ns, def_id)
.copied()
}
}
diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs
index 346406f..ea90aef 100644
--- a/src/librustc_typeck/check/method/probe.rs
+++ b/src/librustc_typeck/check/method/probe.rs
@@ -7,7 +7,6 @@
use crate::check::FnCtxt;
use crate::hir::def::DefKind;
use crate::hir::def_id::DefId;
-use crate::namespace::Namespace;
use rustc::lint;
use rustc::middle::stability;
@@ -22,6 +21,7 @@
use rustc_data_structures::sync::Lrc;
use rustc_errors::struct_span_err;
use rustc_hir as hir;
+use rustc_hir::def::Namespace;
use rustc_infer::infer::canonical::OriginalQueryValues;
use rustc_infer::infer::canonical::{Canonical, QueryResponse};
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
@@ -1696,20 +1696,20 @@
let max_dist = max(name.as_str().len(), 3) / 3;
self.tcx
.associated_items(def_id)
- .iter()
+ .in_definition_order()
.filter(|x| {
let dist = lev_distance(&*name.as_str(), &x.ident.as_str());
- Namespace::from(x.kind) == Namespace::Value && dist > 0 && dist <= max_dist
+ x.kind.namespace() == Namespace::ValueNS && dist > 0 && dist <= max_dist
})
.copied()
.collect()
} else {
self.fcx
- .associated_item(def_id, name, Namespace::Value)
+ .associated_item(def_id, name, Namespace::ValueNS)
.map_or(Vec::new(), |x| vec![x])
}
} else {
- self.tcx.associated_items(def_id).to_vec()
+ self.tcx.associated_items(def_id).in_definition_order().copied().collect()
}
}
}
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 83f063a..ea83b40 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -3,7 +3,6 @@
use crate::check::FnCtxt;
use crate::middle::lang_items::FnOnceTraitLangItem;
-use crate::namespace::Namespace;
use rustc::hir::map as hir_map;
use rustc::hir::map::Map;
use rustc::ty::print::with_crate_prefix;
@@ -11,7 +10,7 @@
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::{DefKind, Namespace, Res};
use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc_hir::intravisit;
use rustc_hir::{ExprKind, Node, QPath};
@@ -97,13 +96,13 @@
// Provide the best span we can. Use the item, if local to crate, else
// the impl, if local to crate (item may be defaulted), else nothing.
let item = match self
- .associated_item(impl_did, item_name, Namespace::Value)
+ .associated_item(impl_did, item_name, Namespace::ValueNS)
.or_else(|| {
let impl_trait_ref = self.tcx.impl_trait_ref(impl_did)?;
self.associated_item(
impl_trait_ref.def_id,
item_name,
- Namespace::Value,
+ Namespace::ValueNS,
)
}) {
Some(item) => item,
@@ -185,7 +184,7 @@
}
CandidateSource::TraitSource(trait_did) => {
let item =
- match self.associated_item(trait_did, item_name, Namespace::Value) {
+ match self.associated_item(trait_did, item_name, Namespace::ValueNS) {
Some(item) => item,
None => continue,
};
@@ -264,7 +263,7 @@
// be used exists at all, and the type is an ambiguous numeric type
// ({integer}/{float}).
let mut candidates = all_traits(self.tcx).into_iter().filter_map(|info| {
- self.associated_item(info.def_id, item_name, Namespace::Value)
+ self.associated_item(info.def_id, item_name, Namespace::ValueNS)
});
if let (true, false, SelfSource::MethodCall(expr), Some(_)) = (
actual.is_numeric(),
@@ -779,7 +778,7 @@
// here).
(type_is_local || info.def_id.is_local())
&& self
- .associated_item(info.def_id, item_name, Namespace::Value)
+ .associated_item(info.def_id, item_name, Namespace::ValueNS)
.filter(|item| {
// We only want to suggest public or local traits (#45781).
item.vis == ty::Visibility::Public || info.def_id.is_local()
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index f714514..4f6eb20 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -89,7 +89,6 @@
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::middle::region;
@@ -1972,19 +1971,16 @@
// Check existing impl methods to see if they are both present in trait
// and compatible with trait signature
for impl_item in impl_items() {
+ let namespace = impl_item.kind.namespace();
let ty_impl_item = tcx.associated_item(tcx.hir().local_def_id(impl_item.hir_id));
let ty_trait_item = tcx
.associated_items(impl_trait_ref.def_id)
- .iter()
- .find(|ac| {
- Namespace::from(&impl_item.kind) == Namespace::from(ac.kind)
- && tcx.hygienic_eq(ty_impl_item.ident, ac.ident, impl_trait_ref.def_id)
- })
+ .find_by_name_and_namespace(tcx, ty_impl_item.ident, namespace, impl_trait_ref.def_id)
.or_else(|| {
// Not compatible, but needed for the error message
tcx.associated_items(impl_trait_ref.def_id)
- .iter()
- .find(|ac| tcx.hygienic_eq(ty_impl_item.ident, ac.ident, impl_trait_ref.def_id))
+ .filter_by_name(tcx, ty_impl_item.ident, impl_trait_ref.def_id)
+ .next()
});
// Check that impl definition matches trait definition
@@ -2088,7 +2084,7 @@
let mut missing_items = Vec::new();
let mut invalidated_items = Vec::new();
let associated_type_overridden = overridden_associated_type.is_some();
- for trait_item in tcx.associated_items(impl_trait_ref.def_id) {
+ for trait_item in tcx.associated_items(impl_trait_ref.def_id).in_definition_order() {
let is_implemented = trait_def
.ancestors(tcx, impl_id)
.leaf_def(tcx, trait_item.ident, trait_item.kind)
@@ -3843,17 +3839,58 @@
error_code: &str,
c_variadic: bool,
sugg_unit: bool| {
+ let (span, start_span, args) = match &expr.kind {
+ hir::ExprKind::Call(hir::Expr { span, .. }, args) => (*span, *span, &args[..]),
+ hir::ExprKind::MethodCall(path_segment, span, args) => (
+ *span,
+ // `sp` doesn't point at the whole `foo.bar()`, only at `bar`.
+ path_segment
+ .args
+ .and_then(|args| args.args.iter().last())
+ // Account for `foo.bar::<T>()`.
+ .map(|arg| {
+ // Skip the closing `>`.
+ tcx.sess
+ .source_map()
+ .next_point(tcx.sess.source_map().next_point(arg.span()))
+ })
+ .unwrap_or(*span),
+ &args[1..], // Skip the receiver.
+ ),
+ k => span_bug!(sp, "checking argument types on a non-call: `{:?}`", k),
+ };
+ let arg_spans = if args.is_empty() {
+ // foo()
+ // ^^^-- supplied 0 arguments
+ // |
+ // expected 2 arguments
+ vec![tcx.sess.source_map().next_point(start_span).with_hi(sp.hi())]
+ } else {
+ // foo(1, 2, 3)
+ // ^^^ - - - supplied 3 arguments
+ // |
+ // expected 2 arguments
+ args.iter().map(|arg| arg.span).collect::<Vec<Span>>()
+ };
+
let mut err = tcx.sess.struct_span_err_with_code(
- sp,
+ span,
&format!(
"this function takes {}{} but {} {} supplied",
if c_variadic { "at least " } else { "" },
- potentially_plural_count(expected_count, "parameter"),
- potentially_plural_count(arg_count, "parameter"),
+ potentially_plural_count(expected_count, "argument"),
+ potentially_plural_count(arg_count, "argument"),
if arg_count == 1 { "was" } else { "were" }
),
DiagnosticId::Error(error_code.to_owned()),
);
+ let label = format!("supplied {}", potentially_plural_count(arg_count, "argument"));
+ for (i, span) in arg_spans.into_iter().enumerate() {
+ err.span_label(
+ span,
+ if arg_count == 0 || i + 1 == arg_count { &label } else { "" },
+ );
+ }
if let Some(def_s) = def_span.map(|sp| tcx.sess.source_map().def_span(sp)) {
err.span_label(def_s, "defined here");
@@ -3870,11 +3907,11 @@
);
} else {
err.span_label(
- sp,
+ span,
format!(
"expected {}{}",
if c_variadic { "at least " } else { "" },
- potentially_plural_count(expected_count, "parameter")
+ potentially_plural_count(expected_count, "argument")
),
);
}
@@ -5224,7 +5261,13 @@
// Check for `Future` implementations by constructing a predicate to
// prove: `<T as Future>::Output == U`
let future_trait = self.tcx.lang_items().future_trait().unwrap();
- let item_def_id = self.tcx.associated_items(future_trait)[0].def_id;
+ let item_def_id = self
+ .tcx
+ .associated_items(future_trait)
+ .in_definition_order()
+ .nth(0)
+ .unwrap()
+ .def_id;
let predicate =
ty::Predicate::Projection(ty::Binder::bind(ty::ProjectionPredicate {
// `<T as Future>::Output`
@@ -5622,8 +5665,7 @@
self.tcx.sess.span_err(
span,
- "this function can only be invoked \
- directly, not through a function pointer",
+ "this function can only be invoked directly, not through a function pointer",
);
}
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index 4ffc3bf..12e6087 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/src/librustc_typeck/check/wfcheck.rs
@@ -223,7 +223,7 @@
_ => {}
}
if !trait_should_be_self.is_empty() {
- if rustc_infer::traits::object_safety_violations(tcx, trait_def_id).is_empty() {
+ if tcx.object_safety_violations(trait_def_id).is_empty() {
return;
}
let sugg = trait_should_be_self.iter().map(|span| (*span, "Self".to_string())).collect();
diff --git a/src/librustc_typeck/coherence/inherent_impls_overlap.rs b/src/librustc_typeck/coherence/inherent_impls_overlap.rs
index 2a0d19b..fcded27 100644
--- a/src/librustc_typeck/coherence/inherent_impls_overlap.rs
+++ b/src/librustc_typeck/coherence/inherent_impls_overlap.rs
@@ -1,5 +1,4 @@
-use crate::namespace::Namespace;
-use rustc::ty::{AssocItem, TyCtxt};
+use rustc::ty::TyCtxt;
use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
@@ -23,18 +22,18 @@
let impl_items1 = self.tcx.associated_items(impl1);
let impl_items2 = self.tcx.associated_items(impl2);
- for item1 in &impl_items1[..] {
- for item2 in &impl_items2[..] {
- // Avoid costly `.modern()` calls as much as possible by doing them as late as we
- // can. Compare raw symbols first.
- if item1.ident.name == item2.ident.name
- && Namespace::from(item1.kind) == Namespace::from(item2.kind)
- {
+ for item1 in impl_items1.in_definition_order() {
+ let collision = impl_items2
+ .filter_by_name_unhygienic(item1.ident.name)
+ .find(|item2| {
// Symbols and namespace match, compare hygienically.
- if item1.ident.modern() == item2.ident.modern() {
- return true;
- }
- }
+ item1.kind.namespace() == item2.kind.namespace()
+ && item1.ident.modern() == item2.ident.modern()
+ })
+ .is_some();
+
+ if collision {
+ return true;
}
}
@@ -47,43 +46,43 @@
impl2: DefId,
overlap: traits::OverlapResult<'_>,
) {
- let name_and_namespace =
- |assoc: &AssocItem| (assoc.ident.modern(), Namespace::from(assoc.kind));
-
let impl_items1 = self.tcx.associated_items(impl1);
let impl_items2 = self.tcx.associated_items(impl2);
- for item1 in &impl_items1[..] {
- let (name, namespace) = name_and_namespace(item1);
+ for item1 in impl_items1.in_definition_order() {
+ let collision = impl_items2.filter_by_name_unhygienic(item1.ident.name).find(|item2| {
+ // Symbols and namespace match, compare hygienically.
+ item1.kind.namespace() == item2.kind.namespace()
+ && item1.ident.modern() == item2.ident.modern()
+ });
- for item2 in &impl_items2[..] {
- if (name, namespace) == name_and_namespace(item2) {
- let mut err = struct_span_err!(
- self.tcx.sess,
- self.tcx.span_of_impl(item1.def_id).unwrap(),
- E0592,
- "duplicate definitions with name `{}`",
- name
- );
- err.span_label(
- self.tcx.span_of_impl(item1.def_id).unwrap(),
- format!("duplicate definitions for `{}`", name),
- );
- err.span_label(
- self.tcx.span_of_impl(item2.def_id).unwrap(),
- format!("other definition for `{}`", name),
- );
+ if let Some(item2) = collision {
+ let name = item1.ident.modern();
+ let mut err = struct_span_err!(
+ self.tcx.sess,
+ self.tcx.span_of_impl(item1.def_id).unwrap(),
+ E0592,
+ "duplicate definitions with name `{}`",
+ name
+ );
+ err.span_label(
+ self.tcx.span_of_impl(item1.def_id).unwrap(),
+ format!("duplicate definitions for `{}`", name),
+ );
+ err.span_label(
+ self.tcx.span_of_impl(item2.def_id).unwrap(),
+ format!("other definition for `{}`", name),
+ );
- for cause in &overlap.intercrate_ambiguity_causes {
- cause.add_intercrate_ambiguity_hint(&mut err);
- }
-
- if overlap.involves_placeholder {
- traits::add_placeholder_note(&mut err);
- }
-
- err.emit();
+ for cause in &overlap.intercrate_ambiguity_causes {
+ cause.add_intercrate_ambiguity_hint(&mut err);
}
+
+ if overlap.involves_placeholder {
+ traits::add_placeholder_note(&mut err);
+ }
+
+ err.emit();
}
}
}
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index 0a1c61b..c5f339d 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -83,7 +83,6 @@
mod constrained_generic_params;
mod impl_wf_check;
mod mem_categorization;
-mod namespace;
mod outlives;
mod structured_errors;
mod variance;
diff --git a/src/librustc_typeck/namespace.rs b/src/librustc_typeck/namespace.rs
deleted file mode 100644
index 2aa97aa..0000000
--- a/src/librustc_typeck/namespace.rs
+++ /dev/null
@@ -1,27 +0,0 @@
-use rustc::ty;
-use rustc_hir as hir;
-
-// Whether an item exists in the type or value namespace.
-#[derive(Copy, Clone, PartialEq, Eq, Debug)]
-pub enum Namespace {
- Type,
- Value,
-}
-
-impl From<ty::AssocKind> for Namespace {
- fn from(a_kind: ty::AssocKind) -> Self {
- match a_kind {
- ty::AssocKind::OpaqueTy | ty::AssocKind::Type => Namespace::Type,
- ty::AssocKind::Const | ty::AssocKind::Method => Namespace::Value,
- }
- }
-}
-
-impl<'a> From<&'a hir::ImplItemKind<'_>> for Namespace {
- fn from(impl_kind: &'a hir::ImplItemKind<'_>) -> Self {
- match *impl_kind {
- hir::ImplItemKind::OpaqueTy(..) | hir::ImplItemKind::TyAlias(..) => Namespace::Type,
- hir::ImplItemKind::Const(..) | hir::ImplItemKind::Method(..) => Namespace::Value,
- }
- }
-}
diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs
index f7968bf..4a1e257 100644
--- a/src/librustdoc/clean/blanket_impl.rs
+++ b/src/librustdoc/clean/blanket_impl.rs
@@ -114,8 +114,7 @@
.cx
.tcx
.associated_items(impl_def_id)
- .iter()
- .copied()
+ .in_definition_order()
.collect::<Vec<_>>()
.clean(self.cx),
polarity: None,
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 90ce880..78222d2 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -190,8 +190,10 @@
}
pub fn build_external_trait(cx: &DocContext<'_>, did: DefId) -> clean::Trait {
+ let trait_items =
+ cx.tcx.associated_items(did).in_definition_order().map(|item| item.clean(cx)).collect();
+
let auto_trait = cx.tcx.trait_def(did).has_auto_impl;
- let trait_items = cx.tcx.associated_items(did).iter().map(|item| item.clean(cx)).collect();
let predicates = cx.tcx.predicates_of(did);
let generics = (cx.tcx.generics_of(did), predicates).clean(cx);
let generics = filter_non_trait_generics(did, generics);
@@ -376,7 +378,7 @@
} else {
(
tcx.associated_items(did)
- .iter()
+ .in_definition_order()
.filter_map(|item| {
if associated_trait.is_some() || item.vis == ty::Visibility::Public {
Some(item.clean(cx))
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 79bcfe7..0b27e5c 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -95,7 +95,7 @@
.tcx
.inherent_impls(did)
.iter()
- .flat_map(|imp| cx.tcx.associated_items(*imp))
+ .flat_map(|imp| cx.tcx.associated_items(*imp).in_definition_order())
.any(|item| item.ident.name == variant_name)
{
return Err(ErrorKind::ResolutionFailure);
@@ -206,8 +206,8 @@
return cx
.tcx
.associated_items(did)
- .iter()
- .find(|item| item.ident.name == item_name)
+ .filter_by_name_unhygienic(item_name)
+ .next()
.and_then(|item| match item.kind {
ty::AssocKind::Method => Some("method"),
_ => None,
@@ -234,7 +234,7 @@
.tcx
.inherent_impls(did)
.iter()
- .flat_map(|imp| cx.tcx.associated_items(*imp))
+ .flat_map(|imp| cx.tcx.associated_items(*imp).in_definition_order())
.find(|item| item.ident.name == item_name);
if let Some(item) = item {
let out = match item.kind {
diff --git a/src/libstd/sync/once.rs b/src/libstd/sync/once.rs
index 61c4d0c..b99b4d8 100644
--- a/src/libstd/sync/once.rs
+++ b/src/libstd/sync/once.rs
@@ -331,14 +331,14 @@
/// * `call_once` was called, but has not yet completed,
/// * the `Once` instance is poisoned
///
- /// It is also possible that immediately after `is_completed`
- /// returns false, some other thread finishes executing
- /// `call_once`.
+ /// This function returning `false` does not mean that `Once` has not been
+ /// executed. For example, it may have been executed in the time between
+ /// when `is_completed` starts executing and when it returns, in which case
+ /// the `false` return value would be stale (but still permissible).
///
/// # Examples
///
/// ```
- /// #![feature(once_is_completed)]
/// use std::sync::Once;
///
/// static INIT: Once = Once::new();
@@ -351,7 +351,6 @@
/// ```
///
/// ```
- /// #![feature(once_is_completed)]
/// use std::sync::Once;
/// use std::thread;
///
@@ -364,7 +363,7 @@
/// assert!(handle.join().is_err());
/// assert_eq!(INIT.is_completed(), false);
/// ```
- #[unstable(feature = "once_is_completed", issue = "54890")]
+ #[stable(feature = "once_is_completed", since = "1.44.0")]
#[inline]
pub fn is_completed(&self) -> bool {
// An `Acquire` load is enough because that makes all the initialization
diff --git a/src/test/codegen/issue-56927.rs b/src/test/codegen/issue-56927.rs
index 0544ff8..d502673 100644
--- a/src/test/codegen/issue-56927.rs
+++ b/src/test/codegen/issue-56927.rs
@@ -23,7 +23,7 @@
// CHECK-LABEL: @test2
// CHECK: store i32 4, i32* %{{.+}}, align 4
-#[allow(const_err)]
+#[allow(unconditional_panic)]
#[no_mangle]
pub fn test2(s: &mut S) {
s.arr[usize::MAX / 4 + 1] = 4;
diff --git a/src/test/compile-fail/consts/const-err3.rs b/src/test/compile-fail/consts/const-err3.rs
deleted file mode 100644
index fc10824..0000000
--- a/src/test/compile-fail/consts/const-err3.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-#![feature(rustc_attrs)]
-#![deny(const_err)]
-
-fn black_box<T>(_: T) {
- unimplemented!()
-}
-
-fn main() {
- let b = 200u8 + 200u8 + 200u8;
- //~^ ERROR const_err
- let c = 200u8 * 4;
- //~^ ERROR const_err
- let d = 42u8 - (42u8 + 1);
- //~^ ERROR const_err
- let _e = [5u8][1];
- //~^ ERROR const_err
- black_box(b);
- black_box(c);
- black_box(d);
-}
diff --git a/src/test/incremental/warnings-reemitted.rs b/src/test/incremental/warnings-reemitted.rs
index 5fc8939..0eac2a1 100644
--- a/src/test/incremental/warnings-reemitted.rs
+++ b/src/test/incremental/warnings-reemitted.rs
@@ -2,8 +2,8 @@
// compile-flags: -Coverflow-checks=on
// build-pass (FIXME(62277): could be check-pass?)
-#![warn(const_err)]
+#![warn(arithmetic_overflow)]
fn main() {
- let _ = 255u8 + 1; //~ WARNING attempt to add with overflow
+ let _ = 255u8 + 1; //~ WARNING operation will overflow
}
diff --git a/src/test/run-fail/mir_indexing_oob_1.rs b/src/test/run-fail/mir_indexing_oob_1.rs
index 0ae0320..1cd53e3 100644
--- a/src/test/run-fail/mir_indexing_oob_1.rs
+++ b/src/test/run-fail/mir_indexing_oob_1.rs
@@ -2,7 +2,7 @@
const C: [u32; 5] = [0; 5];
-#[allow(const_err)]
+#[allow(unconditional_panic)]
fn test() -> u32 {
C[10]
}
diff --git a/src/test/run-fail/mir_indexing_oob_2.rs b/src/test/run-fail/mir_indexing_oob_2.rs
index a7a1177..64b2609 100644
--- a/src/test/run-fail/mir_indexing_oob_2.rs
+++ b/src/test/run-fail/mir_indexing_oob_2.rs
@@ -2,7 +2,7 @@
const C: &'static [u8; 5] = b"hello";
-#[allow(const_err)]
+#[allow(unconditional_panic)]
fn test() -> u8 {
C[10]
}
diff --git a/src/test/run-fail/mir_indexing_oob_3.rs b/src/test/run-fail/mir_indexing_oob_3.rs
index 188460f..3688088 100644
--- a/src/test/run-fail/mir_indexing_oob_3.rs
+++ b/src/test/run-fail/mir_indexing_oob_3.rs
@@ -2,7 +2,7 @@
const C: &'static [u8; 5] = b"hello";
-#[allow(const_err)]
+#[allow(unconditional_panic)]
fn mir() -> u8 {
C[10]
}
diff --git a/src/test/run-fail/overflowing-add.rs b/src/test/run-fail/overflowing-add.rs
index 24602ac..5ca9131 100644
--- a/src/test/run-fail/overflowing-add.rs
+++ b/src/test/run-fail/overflowing-add.rs
@@ -1,7 +1,7 @@
// error-pattern:thread 'main' panicked at 'attempt to add with overflow'
// compile-flags: -C debug-assertions
-#![allow(const_err)]
+#![allow(arithmetic_overflow)]
fn main() {
let _x = 200u8 + 200u8 + 200u8;
diff --git a/src/test/run-fail/overflowing-lsh-1.rs b/src/test/run-fail/overflowing-lsh-1.rs
index 37fbf01..977cfea 100644
--- a/src/test/run-fail/overflowing-lsh-1.rs
+++ b/src/test/run-fail/overflowing-lsh-1.rs
@@ -1,7 +1,7 @@
// error-pattern:thread 'main' panicked at 'attempt to shift left with overflow'
// compile-flags: -C debug-assertions
-#![warn(exceeding_bitshifts)]
+#![warn(arithmetic_overflow)]
#![warn(const_err)]
fn main() {
diff --git a/src/test/run-fail/overflowing-lsh-2.rs b/src/test/run-fail/overflowing-lsh-2.rs
index 7b0b37d..3517dac 100644
--- a/src/test/run-fail/overflowing-lsh-2.rs
+++ b/src/test/run-fail/overflowing-lsh-2.rs
@@ -1,7 +1,7 @@
// error-pattern:thread 'main' panicked at 'attempt to shift left with overflow'
// compile-flags: -C debug-assertions
-#![warn(exceeding_bitshifts)]
+#![warn(arithmetic_overflow)]
#![warn(const_err)]
fn main() {
diff --git a/src/test/run-fail/overflowing-lsh-3.rs b/src/test/run-fail/overflowing-lsh-3.rs
index 1768a8e..4a575c3 100644
--- a/src/test/run-fail/overflowing-lsh-3.rs
+++ b/src/test/run-fail/overflowing-lsh-3.rs
@@ -1,7 +1,7 @@
// error-pattern:thread 'main' panicked at 'attempt to shift left with overflow'
// compile-flags: -C debug-assertions
-#![warn(exceeding_bitshifts)]
+#![warn(arithmetic_overflow)]
#![warn(const_err)]
fn main() {
diff --git a/src/test/run-fail/overflowing-lsh-4.rs b/src/test/run-fail/overflowing-lsh-4.rs
index ec304b4..0d3912c 100644
--- a/src/test/run-fail/overflowing-lsh-4.rs
+++ b/src/test/run-fail/overflowing-lsh-4.rs
@@ -4,7 +4,7 @@
// This function is checking that our automatic truncation does not
// sidestep the overflow checking.
-#![warn(exceeding_bitshifts)]
+#![warn(arithmetic_overflow)]
#![warn(const_err)]
fn main() {
diff --git a/src/test/run-fail/overflowing-mul.rs b/src/test/run-fail/overflowing-mul.rs
index 4811036..2dfc9bb 100644
--- a/src/test/run-fail/overflowing-mul.rs
+++ b/src/test/run-fail/overflowing-mul.rs
@@ -1,7 +1,7 @@
// error-pattern:thread 'main' panicked at 'attempt to multiply with overflow'
// compile-flags: -C debug-assertions
-#![allow(const_err)]
+#![allow(arithmetic_overflow)]
fn main() {
let x = 200u8 * 4;
diff --git a/src/test/run-fail/overflowing-neg.rs b/src/test/run-fail/overflowing-neg.rs
index c4afd74..f512aa3 100644
--- a/src/test/run-fail/overflowing-neg.rs
+++ b/src/test/run-fail/overflowing-neg.rs
@@ -1,7 +1,7 @@
// error-pattern:thread 'main' panicked at 'attempt to negate with overflow'
// compile-flags: -C debug-assertions
-#![allow(const_err)]
+#![allow(arithmetic_overflow)]
fn main() {
let _x = -std::i8::MIN;
diff --git a/src/test/run-fail/overflowing-rsh-1.rs b/src/test/run-fail/overflowing-rsh-1.rs
index 1451454..4592b2b 100644
--- a/src/test/run-fail/overflowing-rsh-1.rs
+++ b/src/test/run-fail/overflowing-rsh-1.rs
@@ -1,7 +1,7 @@
// error-pattern:thread 'main' panicked at 'attempt to shift right with overflow'
// compile-flags: -C debug-assertions
-#![warn(exceeding_bitshifts)]
+#![warn(arithmetic_overflow)]
#![warn(const_err)]
fn main() {
diff --git a/src/test/run-fail/overflowing-rsh-2.rs b/src/test/run-fail/overflowing-rsh-2.rs
index 83dcbd1..066267b 100644
--- a/src/test/run-fail/overflowing-rsh-2.rs
+++ b/src/test/run-fail/overflowing-rsh-2.rs
@@ -1,7 +1,7 @@
// error-pattern:thread 'main' panicked at 'attempt to shift right with overflow'
// compile-flags: -C debug-assertions
-#![warn(exceeding_bitshifts)]
+#![warn(arithmetic_overflow)]
#![warn(const_err)]
fn main() {
diff --git a/src/test/run-fail/overflowing-rsh-3.rs b/src/test/run-fail/overflowing-rsh-3.rs
index 3521c05..67e7848 100644
--- a/src/test/run-fail/overflowing-rsh-3.rs
+++ b/src/test/run-fail/overflowing-rsh-3.rs
@@ -1,7 +1,7 @@
// error-pattern:thread 'main' panicked at 'attempt to shift right with overflow'
// compile-flags: -C debug-assertions
-#![warn(exceeding_bitshifts)]
+#![warn(arithmetic_overflow)]
#![warn(const_err)]
fn main() {
diff --git a/src/test/run-fail/overflowing-rsh-4.rs b/src/test/run-fail/overflowing-rsh-4.rs
index ed11918..1877d5c 100644
--- a/src/test/run-fail/overflowing-rsh-4.rs
+++ b/src/test/run-fail/overflowing-rsh-4.rs
@@ -4,7 +4,7 @@
// This function is checking that our (type-based) automatic
// truncation does not sidestep the overflow checking.
-#![warn(exceeding_bitshifts)]
+#![warn(arithmetic_overflow)]
#![warn(const_err)]
fn main() {
diff --git a/src/test/run-fail/overflowing-rsh-5.rs b/src/test/run-fail/overflowing-rsh-5.rs
index 58dfc57..20ef324 100644
--- a/src/test/run-fail/overflowing-rsh-5.rs
+++ b/src/test/run-fail/overflowing-rsh-5.rs
@@ -1,7 +1,7 @@
// error-pattern:thread 'main' panicked at 'attempt to shift right with overflow'
// compile-flags: -C debug-assertions
-#![warn(exceeding_bitshifts)]
+#![warn(arithmetic_overflow)]
#![warn(const_err)]
fn main() {
diff --git a/src/test/run-fail/overflowing-rsh-6.rs b/src/test/run-fail/overflowing-rsh-6.rs
index c2fec5e..589a98b 100644
--- a/src/test/run-fail/overflowing-rsh-6.rs
+++ b/src/test/run-fail/overflowing-rsh-6.rs
@@ -1,7 +1,7 @@
// error-pattern:thread 'main' panicked at 'attempt to shift right with overflow'
// compile-flags: -C debug-assertions
-#![warn(exceeding_bitshifts)]
+#![warn(arithmetic_overflow)]
#![warn(const_err)]
#![feature(const_indexing)]
diff --git a/src/test/run-fail/overflowing-sub.rs b/src/test/run-fail/overflowing-sub.rs
index e3b111dd..fb096c3 100644
--- a/src/test/run-fail/overflowing-sub.rs
+++ b/src/test/run-fail/overflowing-sub.rs
@@ -1,7 +1,7 @@
// error-pattern:thread 'main' panicked at 'attempt to subtract with overflow'
// compile-flags: -C debug-assertions
-#![allow(const_err)]
+#![allow(arithmetic_overflow)]
fn main() {
let _x = 42u8 - (42u8 + 1);
diff --git a/src/test/run-fail/promoted_div_by_zero.rs b/src/test/run-fail/promoted_div_by_zero.rs
index 3fe51a1..dc6719c 100644
--- a/src/test/run-fail/promoted_div_by_zero.rs
+++ b/src/test/run-fail/promoted_div_by_zero.rs
@@ -1,4 +1,4 @@
-#![allow(const_err)]
+#![allow(unconditional_panic, const_err)]
// error-pattern: attempt to divide by zero
diff --git a/src/test/run-fail/promoted_overflow.rs b/src/test/run-fail/promoted_overflow.rs
index 139bf54..3c42da4 100644
--- a/src/test/run-fail/promoted_overflow.rs
+++ b/src/test/run-fail/promoted_overflow.rs
@@ -1,4 +1,4 @@
-#![allow(const_err)]
+#![allow(arithmetic_overflow)]
// error-pattern: overflow
// compile-flags: -C overflow-checks=yes
diff --git a/src/test/ui/arg-count-mismatch.rs b/src/test/ui/arg-count-mismatch.rs
index cf74870..18926f5 100644
--- a/src/test/ui/arg-count-mismatch.rs
+++ b/src/test/ui/arg-count-mismatch.rs
@@ -1,4 +1,4 @@
-// error-pattern: parameters were supplied
+// error-pattern: arguments were supplied
fn f(x: isize) { }
diff --git a/src/test/ui/arg-count-mismatch.stderr b/src/test/ui/arg-count-mismatch.stderr
index 44f1604..7bc0613 100644
--- a/src/test/ui/arg-count-mismatch.stderr
+++ b/src/test/ui/arg-count-mismatch.stderr
@@ -1,11 +1,13 @@
-error[E0061]: this function takes 1 parameter but 0 parameters were supplied
+error[E0061]: this function takes 1 argument but 0 arguments were supplied
--> $DIR/arg-count-mismatch.rs:5:28
|
LL | fn f(x: isize) { }
| -------------- defined here
LL |
LL | fn main() { let i: (); i = f(); }
- | ^^^ expected 1 parameter
+ | ^-- supplied 0 arguments
+ | |
+ | expected 1 argument
error: aborting due to previous error
diff --git a/src/test/ui/builtin-superkinds/builtin-superkinds-self-type.stderr b/src/test/ui/builtin-superkinds/builtin-superkinds-self-type.stderr
index 2fdb383..999a583 100644
--- a/src/test/ui/builtin-superkinds/builtin-superkinds-self-type.stderr
+++ b/src/test/ui/builtin-superkinds/builtin-superkinds-self-type.stderr
@@ -4,7 +4,7 @@
LL | impl <T: Sync> Foo for T { }
| -- ^^^
| |
- | help: consider adding an explicit lifetime bound `T: 'static`...
+ | help: consider adding an explicit lifetime bound...: `T: 'static +`
|
note: ...so that the type `T` will meet its required lifetime bounds
--> $DIR/builtin-superkinds-self-type.rs:10:16
diff --git a/src/test/ui/c-variadic/variadic-ffi-1.rs b/src/test/ui/c-variadic/variadic-ffi-1.rs
index 6a3ff24..e7197a9 100644
--- a/src/test/ui/c-variadic/variadic-ffi-1.rs
+++ b/src/test/ui/c-variadic/variadic-ffi-1.rs
@@ -13,8 +13,8 @@
fn main() {
unsafe {
- foo(); //~ ERROR this function takes at least 2 parameters but 0 parameters were supplied
- foo(1); //~ ERROR this function takes at least 2 parameters but 1 parameter was supplied
+ foo(); //~ ERROR this function takes at least 2 arguments but 0 arguments were supplied
+ foo(1); //~ ERROR this function takes at least 2 arguments but 1 argument was supplied
let x: unsafe extern "C" fn(f: isize, x: u8) = foo; //~ ERROR mismatched types
let y: extern "C" fn(f: isize, x: u8, ...) = bar; //~ ERROR mismatched types
diff --git a/src/test/ui/c-variadic/variadic-ffi-1.stderr b/src/test/ui/c-variadic/variadic-ffi-1.stderr
index 05d839a..318b8aa 100644
--- a/src/test/ui/c-variadic/variadic-ffi-1.stderr
+++ b/src/test/ui/c-variadic/variadic-ffi-1.stderr
@@ -4,23 +4,27 @@
LL | fn printf(_: *const u8, ...);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadics require C or cdecl calling convention
-error[E0060]: this function takes at least 2 parameters but 0 parameters were supplied
+error[E0060]: this function takes at least 2 arguments but 0 arguments were supplied
--> $DIR/variadic-ffi-1.rs:16:9
|
LL | fn foo(f: isize, x: u8, ...);
| ----------------------------- defined here
...
LL | foo();
- | ^^^^^ expected at least 2 parameters
+ | ^^^-- supplied 0 arguments
+ | |
+ | expected at least 2 arguments
-error[E0060]: this function takes at least 2 parameters but 1 parameter was supplied
+error[E0060]: this function takes at least 2 arguments but 1 argument was supplied
--> $DIR/variadic-ffi-1.rs:17:9
|
LL | fn foo(f: isize, x: u8, ...);
| ----------------------------- defined here
...
LL | foo(1);
- | ^^^^^^ expected at least 2 parameters
+ | ^^^ - supplied 1 argument
+ | |
+ | expected at least 2 arguments
error[E0308]: mismatched types
--> $DIR/variadic-ffi-1.rs:19:56
diff --git a/src/test/ui/consts/array-literal-index-oob.rs b/src/test/ui/consts/array-literal-index-oob.rs
index af63d1f..492afa9 100644
--- a/src/test/ui/consts/array-literal-index-oob.rs
+++ b/src/test/ui/consts/array-literal-index-oob.rs
@@ -1,11 +1,11 @@
// build-pass
// ignore-pass (emit codegen-time warnings and verify that they are indeed warnings and not errors)
-#![warn(const_err)]
+#![warn(const_err, unconditional_panic)]
fn main() {
&{ [1, 2, 3][4] };
- //~^ WARN index out of bounds
+ //~^ WARN operation will panic
//~| 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 59e1169..6e0e7fe 100644
--- a/src/test/ui/consts/array-literal-index-oob.stderr
+++ b/src/test/ui/consts/array-literal-index-oob.stderr
@@ -1,14 +1,14 @@
-warning: index out of bounds: the len is 3 but the index is 4
+warning: this operation will panic at runtime
--> $DIR/array-literal-index-oob.rs:7:8
|
LL | &{ [1, 2, 3][4] };
- | ^^^^^^^^^^^^
+ | ^^^^^^^^^^^^ index out of bounds: the len is 3 but the index is 4
|
note: the lint level is defined here
- --> $DIR/array-literal-index-oob.rs:4:9
+ --> $DIR/array-literal-index-oob.rs:4:20
|
-LL | #![warn(const_err)]
- | ^^^^^^^^^
+LL | #![warn(const_err, unconditional_panic)]
+ | ^^^^^^^^^^^^^^^^^^^
warning: reaching this expression at runtime will panic or abort
--> $DIR/array-literal-index-oob.rs:7:8
@@ -17,6 +17,12 @@
| ---^^^^^^^^^^^^--
| |
| indexing out of bounds: the len is 3 but the index is 4
+ |
+note: the lint level is defined here
+ --> $DIR/array-literal-index-oob.rs:4:9
+ |
+LL | #![warn(const_err, unconditional_panic)]
+ | ^^^^^^^^^
warning: erroneous constant used
--> $DIR/array-literal-index-oob.rs:7:5
diff --git a/src/test/ui/consts/const-err.rs b/src/test/ui/consts/const-err.rs
index b204f70..d1c5f4f 100644
--- a/src/test/ui/consts/const-err.rs
+++ b/src/test/ui/consts/const-err.rs
@@ -1,7 +1,7 @@
// build-fail
// compile-flags: -Zforce-overflow-checks=on
-#![allow(exceeding_bitshifts)]
+#![allow(arithmetic_overflow)]
#![warn(const_err)]
fn black_box<T>(_: T) {
diff --git a/src/test/ui/consts/const-err2.noopt.stderr b/src/test/ui/consts/const-err2.noopt.stderr
new file mode 100644
index 0000000..5aeeec4
--- /dev/null
+++ b/src/test/ui/consts/const-err2.noopt.stderr
@@ -0,0 +1,48 @@
+error: this arithmetic operation will overflow
+ --> $DIR/const-err2.rs:19:13
+ |
+LL | let a = -std::i8::MIN;
+ | ^^^^^^^^^^^^^ attempt to negate with overflow
+ |
+ = note: `#[deny(arithmetic_overflow)]` on by default
+
+error: this arithmetic operation will overflow
+ --> $DIR/const-err2.rs:21:18
+ |
+LL | let a_i128 = -std::i128::MIN;
+ | ^^^^^^^^^^^^^^^ attempt to negate with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/const-err2.rs:23:13
+ |
+LL | let b = 200u8 + 200u8 + 200u8;
+ | ^^^^^^^^^^^^^ attempt to add with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/const-err2.rs:25:18
+ |
+LL | let b_i128 = std::i128::MIN - std::i128::MAX;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to subtract with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/const-err2.rs:27:13
+ |
+LL | let c = 200u8 * 4;
+ | ^^^^^^^^^ attempt to multiply with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/const-err2.rs:29:13
+ |
+LL | let d = 42u8 - (42u8 + 1);
+ | ^^^^^^^^^^^^^^^^^ attempt to subtract with overflow
+
+error: this operation will panic at runtime
+ --> $DIR/const-err2.rs:31:14
+ |
+LL | let _e = [5u8][1];
+ | ^^^^^^^^ index out of bounds: the len is 1 but the index is 1
+ |
+ = note: `#[deny(unconditional_panic)]` on by default
+
+error: aborting due to 7 previous errors
+
diff --git a/src/test/ui/consts/const-err2.opt.stderr b/src/test/ui/consts/const-err2.opt.stderr
new file mode 100644
index 0000000..5aeeec4
--- /dev/null
+++ b/src/test/ui/consts/const-err2.opt.stderr
@@ -0,0 +1,48 @@
+error: this arithmetic operation will overflow
+ --> $DIR/const-err2.rs:19:13
+ |
+LL | let a = -std::i8::MIN;
+ | ^^^^^^^^^^^^^ attempt to negate with overflow
+ |
+ = note: `#[deny(arithmetic_overflow)]` on by default
+
+error: this arithmetic operation will overflow
+ --> $DIR/const-err2.rs:21:18
+ |
+LL | let a_i128 = -std::i128::MIN;
+ | ^^^^^^^^^^^^^^^ attempt to negate with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/const-err2.rs:23:13
+ |
+LL | let b = 200u8 + 200u8 + 200u8;
+ | ^^^^^^^^^^^^^ attempt to add with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/const-err2.rs:25:18
+ |
+LL | let b_i128 = std::i128::MIN - std::i128::MAX;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to subtract with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/const-err2.rs:27:13
+ |
+LL | let c = 200u8 * 4;
+ | ^^^^^^^^^ attempt to multiply with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/const-err2.rs:29:13
+ |
+LL | let d = 42u8 - (42u8 + 1);
+ | ^^^^^^^^^^^^^^^^^ attempt to subtract with overflow
+
+error: this operation will panic at runtime
+ --> $DIR/const-err2.rs:31:14
+ |
+LL | let _e = [5u8][1];
+ | ^^^^^^^^ index out of bounds: the len is 1 but the index is 1
+ |
+ = note: `#[deny(unconditional_panic)]` on by default
+
+error: aborting due to 7 previous errors
+
diff --git a/src/test/ui/consts/const-err2.opt_with_overflow_checks.stderr b/src/test/ui/consts/const-err2.opt_with_overflow_checks.stderr
new file mode 100644
index 0000000..5aeeec4
--- /dev/null
+++ b/src/test/ui/consts/const-err2.opt_with_overflow_checks.stderr
@@ -0,0 +1,48 @@
+error: this arithmetic operation will overflow
+ --> $DIR/const-err2.rs:19:13
+ |
+LL | let a = -std::i8::MIN;
+ | ^^^^^^^^^^^^^ attempt to negate with overflow
+ |
+ = note: `#[deny(arithmetic_overflow)]` on by default
+
+error: this arithmetic operation will overflow
+ --> $DIR/const-err2.rs:21:18
+ |
+LL | let a_i128 = -std::i128::MIN;
+ | ^^^^^^^^^^^^^^^ attempt to negate with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/const-err2.rs:23:13
+ |
+LL | let b = 200u8 + 200u8 + 200u8;
+ | ^^^^^^^^^^^^^ attempt to add with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/const-err2.rs:25:18
+ |
+LL | let b_i128 = std::i128::MIN - std::i128::MAX;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to subtract with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/const-err2.rs:27:13
+ |
+LL | let c = 200u8 * 4;
+ | ^^^^^^^^^ attempt to multiply with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/const-err2.rs:29:13
+ |
+LL | let d = 42u8 - (42u8 + 1);
+ | ^^^^^^^^^^^^^^^^^ attempt to subtract with overflow
+
+error: this operation will panic at runtime
+ --> $DIR/const-err2.rs:31:14
+ |
+LL | let _e = [5u8][1];
+ | ^^^^^^^^ index out of bounds: the len is 1 but the index is 1
+ |
+ = note: `#[deny(unconditional_panic)]` on by default
+
+error: aborting due to 7 previous errors
+
diff --git a/src/test/ui/consts/const-err2.rs b/src/test/ui/consts/const-err2.rs
index 7c5aaed..2c6a987 100644
--- a/src/test/ui/consts/const-err2.rs
+++ b/src/test/ui/consts/const-err2.rs
@@ -2,13 +2,14 @@
// optimized compilation and unoptimized compilation and thus would
// lead to different lints being emitted
+// revisions: noopt opt opt_with_overflow_checks
+//[noopt]compile-flags: -C opt-level=0
+//[opt]compile-flags: -O
+//[opt_with_overflow_checks]compile-flags: -C overflow-checks=on -O
+
// build-fail
-// compile-flags: -O
#![feature(rustc_attrs)]
-#![allow(exceeding_bitshifts)]
-
-#![deny(const_err)]
fn black_box<T>(_: T) {
unimplemented!()
@@ -16,19 +17,19 @@
fn main() {
let a = -std::i8::MIN;
- //~^ ERROR const_err
+ //~^ ERROR arithmetic operation will overflow
let a_i128 = -std::i128::MIN;
- //~^ ERROR const_err
+ //~^ ERROR arithmetic operation will overflow
let b = 200u8 + 200u8 + 200u8;
- //~^ ERROR const_err
+ //~^ ERROR arithmetic operation will overflow
let b_i128 = std::i128::MIN - std::i128::MAX;
- //~^ ERROR const_err
+ //~^ ERROR arithmetic operation will overflow
let c = 200u8 * 4;
- //~^ ERROR const_err
+ //~^ ERROR arithmetic operation will overflow
let d = 42u8 - (42u8 + 1);
- //~^ ERROR const_err
+ //~^ ERROR arithmetic operation will overflow
let _e = [5u8][1];
- //~^ ERROR const_err
+ //~^ ERROR operation will panic
black_box(a);
black_box(a_i128);
black_box(b);
diff --git a/src/test/ui/consts/const-err2.stderr b/src/test/ui/consts/const-err2.stderr
deleted file mode 100644
index f135bf0..0000000
--- a/src/test/ui/consts/const-err2.stderr
+++ /dev/null
@@ -1,50 +0,0 @@
-error: this expression will panic at runtime
- --> $DIR/const-err2.rs:18:13
- |
-LL | let a = -std::i8::MIN;
- | ^^^^^^^^^^^^^ attempt to negate with overflow
- |
-note: the lint level is defined here
- --> $DIR/const-err2.rs:11:9
- |
-LL | #![deny(const_err)]
- | ^^^^^^^^^
-
-error: this expression will panic at runtime
- --> $DIR/const-err2.rs:20:18
- |
-LL | let a_i128 = -std::i128::MIN;
- | ^^^^^^^^^^^^^^^ attempt to negate with overflow
-
-error: this expression will panic at runtime
- --> $DIR/const-err2.rs:22:13
- |
-LL | let b = 200u8 + 200u8 + 200u8;
- | ^^^^^^^^^^^^^ attempt to add with overflow
-
-error: this expression will panic at runtime
- --> $DIR/const-err2.rs:24:18
- |
-LL | let b_i128 = std::i128::MIN - std::i128::MAX;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to subtract with overflow
-
-error: this expression will panic at runtime
- --> $DIR/const-err2.rs:26:13
- |
-LL | let c = 200u8 * 4;
- | ^^^^^^^^^ attempt to multiply with overflow
-
-error: this expression will panic at runtime
- --> $DIR/const-err2.rs:28:13
- |
-LL | let d = 42u8 - (42u8 + 1);
- | ^^^^^^^^^^^^^^^^^ attempt to subtract with overflow
-
-error: index out of bounds: the len is 1 but the index is 1
- --> $DIR/const-err2.rs:30:14
- |
-LL | let _e = [5u8][1];
- | ^^^^^^^^
-
-error: aborting due to 7 previous errors
-
diff --git a/src/test/ui/consts/const-err3.rs b/src/test/ui/consts/const-err3.rs
deleted file mode 100644
index 43aba4a..0000000
--- a/src/test/ui/consts/const-err3.rs
+++ /dev/null
@@ -1,38 +0,0 @@
-// needed because negating int::MIN will behave differently between
-// optimized compilation and unoptimized compilation and thus would
-// lead to different lints being emitted
-
-// build-fail
-// compile-flags: -C overflow-checks=on -O
-
-#![feature(rustc_attrs)]
-#![allow(exceeding_bitshifts)]
-
-#![deny(const_err)]
-
-fn black_box<T>(_: T) {
- unimplemented!()
-}
-
-fn main() {
- let a = -std::i8::MIN;
- //~^ ERROR const_err
- let a_i128 = -std::i128::MIN;
- //~^ ERROR const_err
- let b = 200u8 + 200u8 + 200u8;
- //~^ ERROR const_err
- let b_i128 = std::i128::MIN - std::i128::MAX;
- //~^ ERROR const_err
- let c = 200u8 * 4;
- //~^ ERROR const_err
- let d = 42u8 - (42u8 + 1);
- //~^ ERROR const_err
- let _e = [5u8][1];
- //~^ ERROR const_err
- black_box(a);
- black_box(a_i128);
- black_box(b);
- black_box(b_i128);
- black_box(c);
- black_box(d);
-}
diff --git a/src/test/ui/consts/const-err3.stderr b/src/test/ui/consts/const-err3.stderr
deleted file mode 100644
index 05f64b8..0000000
--- a/src/test/ui/consts/const-err3.stderr
+++ /dev/null
@@ -1,50 +0,0 @@
-error: attempt to negate with overflow
- --> $DIR/const-err3.rs:18:13
- |
-LL | let a = -std::i8::MIN;
- | ^^^^^^^^^^^^^
- |
-note: the lint level is defined here
- --> $DIR/const-err3.rs:11:9
- |
-LL | #![deny(const_err)]
- | ^^^^^^^^^
-
-error: attempt to negate with overflow
- --> $DIR/const-err3.rs:20:18
- |
-LL | let a_i128 = -std::i128::MIN;
- | ^^^^^^^^^^^^^^^
-
-error: attempt to add with overflow
- --> $DIR/const-err3.rs:22:13
- |
-LL | let b = 200u8 + 200u8 + 200u8;
- | ^^^^^^^^^^^^^
-
-error: attempt to subtract with overflow
- --> $DIR/const-err3.rs:24:18
- |
-LL | let b_i128 = std::i128::MIN - std::i128::MAX;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: attempt to multiply with overflow
- --> $DIR/const-err3.rs:26:13
- |
-LL | let c = 200u8 * 4;
- | ^^^^^^^^^
-
-error: attempt to subtract with overflow
- --> $DIR/const-err3.rs:28:13
- |
-LL | let d = 42u8 - (42u8 + 1);
- | ^^^^^^^^^^^^^^^^^
-
-error: index out of bounds: the len is 1 but the index is 1
- --> $DIR/const-err3.rs:30:14
- |
-LL | let _e = [5u8][1];
- | ^^^^^^^^
-
-error: aborting due to 7 previous errors
-
diff --git a/src/test/ui/consts/const-eval/index_out_of_bounds_propagated.rs b/src/test/ui/consts/const-eval/index_out_of_bounds_propagated.rs
index 6d6bb94..608e6e1 100644
--- a/src/test/ui/consts/const-eval/index_out_of_bounds_propagated.rs
+++ b/src/test/ui/consts/const-eval/index_out_of_bounds_propagated.rs
@@ -2,5 +2,5 @@
fn main() {
let array = [std::env::args().len()];
- array[1]; //~ ERROR index out of bounds
+ array[1]; //~ ERROR operation will panic
}
diff --git a/src/test/ui/consts/const-eval/index_out_of_bounds_propagated.stderr b/src/test/ui/consts/const-eval/index_out_of_bounds_propagated.stderr
index 9519ccd..4188efd 100644
--- a/src/test/ui/consts/const-eval/index_out_of_bounds_propagated.stderr
+++ b/src/test/ui/consts/const-eval/index_out_of_bounds_propagated.stderr
@@ -1,10 +1,10 @@
-error: index out of bounds: the len is 1 but the index is 1
+error: this operation will panic at runtime
--> $DIR/index_out_of_bounds_propagated.rs:5:5
|
LL | array[1];
- | ^^^^^^^^
+ | ^^^^^^^^ index out of bounds: the len is 1 but the index is 1
|
- = note: `#[deny(const_err)]` on by default
+ = note: `#[deny(unconditional_panic)]` on by default
error: aborting due to previous error
diff --git a/src/test/ui/consts/const-eval/promoted_errors.noopt.stderr b/src/test/ui/consts/const-eval/promoted_errors.noopt.stderr
new file mode 100644
index 0000000..94c1593
--- /dev/null
+++ b/src/test/ui/consts/const-eval/promoted_errors.noopt.stderr
@@ -0,0 +1,78 @@
+warning: this arithmetic operation will overflow
+ --> $DIR/promoted_errors.rs:12:20
+ |
+LL | println!("{}", 0u32 - 1);
+ | ^^^^^^^^ attempt to subtract with overflow
+ |
+note: the lint level is defined here
+ --> $DIR/promoted_errors.rs:9:20
+ |
+LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)]
+ | ^^^^^^^^^^^^^^^^^^^
+
+warning: this arithmetic operation will overflow
+ --> $DIR/promoted_errors.rs:14:14
+ |
+LL | let _x = 0u32 - 1;
+ | ^^^^^^^^ attempt to subtract with overflow
+
+warning: this operation will panic at runtime
+ --> $DIR/promoted_errors.rs:16:20
+ |
+LL | println!("{}", 1 / (1 - 1));
+ | ^^^^^^^^^^^ attempt to divide by zero
+ |
+note: the lint level is defined here
+ --> $DIR/promoted_errors.rs:9:41
+ |
+LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)]
+ | ^^^^^^^^^^^^^^^^^^^
+
+warning: reaching this expression at runtime will panic or abort
+ --> $DIR/promoted_errors.rs:16:20
+ |
+LL | println!("{}", 1 / (1 - 1));
+ | ^^^^^^^^^^^ dividing by zero
+ |
+note: the lint level is defined here
+ --> $DIR/promoted_errors.rs:9:9
+ |
+LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)]
+ | ^^^^^^^^^
+
+warning: erroneous constant used
+ --> $DIR/promoted_errors.rs:16:20
+ |
+LL | println!("{}", 1 / (1 - 1));
+ | ^^^^^^^^^^^ referenced constant has errors
+
+warning: this operation will panic at runtime
+ --> $DIR/promoted_errors.rs:20:14
+ |
+LL | let _x = 1 / (1 - 1);
+ | ^^^^^^^^^^^ attempt to divide by zero
+
+warning: this operation will panic at runtime
+ --> $DIR/promoted_errors.rs:22:20
+ |
+LL | println!("{}", 1 / (false as u32));
+ | ^^^^^^^^^^^^^^^^^^ attempt to divide by zero
+
+warning: reaching this expression at runtime will panic or abort
+ --> $DIR/promoted_errors.rs:22:20
+ |
+LL | println!("{}", 1 / (false as u32));
+ | ^^^^^^^^^^^^^^^^^^ dividing by zero
+
+warning: erroneous constant used
+ --> $DIR/promoted_errors.rs:22:20
+ |
+LL | println!("{}", 1 / (false as u32));
+ | ^^^^^^^^^^^^^^^^^^ referenced constant has errors
+
+warning: this operation will panic at runtime
+ --> $DIR/promoted_errors.rs:26:14
+ |
+LL | let _x = 1 / (false as u32);
+ | ^^^^^^^^^^^^^^^^^^ attempt to divide by zero
+
diff --git a/src/test/ui/consts/const-eval/promoted_errors.opt.stderr b/src/test/ui/consts/const-eval/promoted_errors.opt.stderr
new file mode 100644
index 0000000..034dea0
--- /dev/null
+++ b/src/test/ui/consts/const-eval/promoted_errors.opt.stderr
@@ -0,0 +1,72 @@
+warning: this arithmetic operation will overflow
+ --> $DIR/promoted_errors.rs:14:14
+ |
+LL | let _x = 0u32 - 1;
+ | ^^^^^^^^ attempt to subtract with overflow
+ |
+note: the lint level is defined here
+ --> $DIR/promoted_errors.rs:9:20
+ |
+LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)]
+ | ^^^^^^^^^^^^^^^^^^^
+
+warning: this operation will panic at runtime
+ --> $DIR/promoted_errors.rs:16:20
+ |
+LL | println!("{}", 1 / (1 - 1));
+ | ^^^^^^^^^^^ attempt to divide by zero
+ |
+note: the lint level is defined here
+ --> $DIR/promoted_errors.rs:9:41
+ |
+LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)]
+ | ^^^^^^^^^^^^^^^^^^^
+
+warning: reaching this expression at runtime will panic or abort
+ --> $DIR/promoted_errors.rs:16:20
+ |
+LL | println!("{}", 1 / (1 - 1));
+ | ^^^^^^^^^^^ dividing by zero
+ |
+note: the lint level is defined here
+ --> $DIR/promoted_errors.rs:9:9
+ |
+LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)]
+ | ^^^^^^^^^
+
+warning: erroneous constant used
+ --> $DIR/promoted_errors.rs:16:20
+ |
+LL | println!("{}", 1 / (1 - 1));
+ | ^^^^^^^^^^^ referenced constant has errors
+
+warning: this operation will panic at runtime
+ --> $DIR/promoted_errors.rs:20:14
+ |
+LL | let _x = 1 / (1 - 1);
+ | ^^^^^^^^^^^ attempt to divide by zero
+
+warning: this operation will panic at runtime
+ --> $DIR/promoted_errors.rs:22:20
+ |
+LL | println!("{}", 1 / (false as u32));
+ | ^^^^^^^^^^^^^^^^^^ attempt to divide by zero
+
+warning: reaching this expression at runtime will panic or abort
+ --> $DIR/promoted_errors.rs:22:20
+ |
+LL | println!("{}", 1 / (false as u32));
+ | ^^^^^^^^^^^^^^^^^^ dividing by zero
+
+warning: erroneous constant used
+ --> $DIR/promoted_errors.rs:22:20
+ |
+LL | println!("{}", 1 / (false as u32));
+ | ^^^^^^^^^^^^^^^^^^ referenced constant has errors
+
+warning: this operation will panic at runtime
+ --> $DIR/promoted_errors.rs:26:14
+ |
+LL | let _x = 1 / (false as u32);
+ | ^^^^^^^^^^^^^^^^^^ attempt to divide by zero
+
diff --git a/src/test/ui/consts/const-eval/promoted_errors.opt_with_overflow_checks.stderr b/src/test/ui/consts/const-eval/promoted_errors.opt_with_overflow_checks.stderr
new file mode 100644
index 0000000..94c1593
--- /dev/null
+++ b/src/test/ui/consts/const-eval/promoted_errors.opt_with_overflow_checks.stderr
@@ -0,0 +1,78 @@
+warning: this arithmetic operation will overflow
+ --> $DIR/promoted_errors.rs:12:20
+ |
+LL | println!("{}", 0u32 - 1);
+ | ^^^^^^^^ attempt to subtract with overflow
+ |
+note: the lint level is defined here
+ --> $DIR/promoted_errors.rs:9:20
+ |
+LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)]
+ | ^^^^^^^^^^^^^^^^^^^
+
+warning: this arithmetic operation will overflow
+ --> $DIR/promoted_errors.rs:14:14
+ |
+LL | let _x = 0u32 - 1;
+ | ^^^^^^^^ attempt to subtract with overflow
+
+warning: this operation will panic at runtime
+ --> $DIR/promoted_errors.rs:16:20
+ |
+LL | println!("{}", 1 / (1 - 1));
+ | ^^^^^^^^^^^ attempt to divide by zero
+ |
+note: the lint level is defined here
+ --> $DIR/promoted_errors.rs:9:41
+ |
+LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)]
+ | ^^^^^^^^^^^^^^^^^^^
+
+warning: reaching this expression at runtime will panic or abort
+ --> $DIR/promoted_errors.rs:16:20
+ |
+LL | println!("{}", 1 / (1 - 1));
+ | ^^^^^^^^^^^ dividing by zero
+ |
+note: the lint level is defined here
+ --> $DIR/promoted_errors.rs:9:9
+ |
+LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)]
+ | ^^^^^^^^^
+
+warning: erroneous constant used
+ --> $DIR/promoted_errors.rs:16:20
+ |
+LL | println!("{}", 1 / (1 - 1));
+ | ^^^^^^^^^^^ referenced constant has errors
+
+warning: this operation will panic at runtime
+ --> $DIR/promoted_errors.rs:20:14
+ |
+LL | let _x = 1 / (1 - 1);
+ | ^^^^^^^^^^^ attempt to divide by zero
+
+warning: this operation will panic at runtime
+ --> $DIR/promoted_errors.rs:22:20
+ |
+LL | println!("{}", 1 / (false as u32));
+ | ^^^^^^^^^^^^^^^^^^ attempt to divide by zero
+
+warning: reaching this expression at runtime will panic or abort
+ --> $DIR/promoted_errors.rs:22:20
+ |
+LL | println!("{}", 1 / (false as u32));
+ | ^^^^^^^^^^^^^^^^^^ dividing by zero
+
+warning: erroneous constant used
+ --> $DIR/promoted_errors.rs:22:20
+ |
+LL | println!("{}", 1 / (false as u32));
+ | ^^^^^^^^^^^^^^^^^^ referenced constant has errors
+
+warning: this operation will panic at runtime
+ --> $DIR/promoted_errors.rs:26:14
+ |
+LL | let _x = 1 / (false as u32);
+ | ^^^^^^^^^^^^^^^^^^ attempt to divide by zero
+
diff --git a/src/test/ui/consts/const-eval/promoted_errors.rs b/src/test/ui/consts/const-eval/promoted_errors.rs
index 22f863f..3ab6ce2 100644
--- a/src/test/ui/consts/const-eval/promoted_errors.rs
+++ b/src/test/ui/consts/const-eval/promoted_errors.rs
@@ -1,23 +1,28 @@
+// revisions: noopt opt opt_with_overflow_checks
+//[noopt]compile-flags: -C opt-level=0
+//[opt]compile-flags: -O
+//[opt_with_overflow_checks]compile-flags: -C overflow-checks=on -O
+
// build-pass
// ignore-pass (emit codegen-time warnings and verify that they are indeed warnings and not errors)
-// compile-flags: -O
-#![warn(const_err)]
+#![warn(const_err, arithmetic_overflow, unconditional_panic)]
fn main() {
println!("{}", 0u32 - 1);
+ //[opt_with_overflow_checks,noopt]~^ WARN [arithmetic_overflow]
let _x = 0u32 - 1;
- //~^ WARN const_err
+ //~^ WARN [arithmetic_overflow]
println!("{}", 1 / (1 - 1));
- //~^ WARN attempt to divide by zero [const_err]
- //~| WARN const_err
+ //~^ WARN [unconditional_panic]
+ //~| WARN panic or abort [const_err]
//~| WARN erroneous constant used [const_err]
let _x = 1 / (1 - 1);
- //~^ WARN const_err
+ //~^ WARN [unconditional_panic]
println!("{}", 1 / (false as u32));
- //~^ WARN attempt to divide by zero [const_err]
- //~| WARN const_err
+ //~^ WARN [unconditional_panic]
+ //~| WARN panic or abort [const_err]
//~| WARN erroneous constant used [const_err]
let _x = 1 / (false as u32);
- //~^ WARN const_err
+ //~^ WARN [unconditional_panic]
}
diff --git a/src/test/ui/consts/const-eval/promoted_errors.stderr b/src/test/ui/consts/const-eval/promoted_errors.stderr
deleted file mode 100644
index 08ae5c7..0000000
--- a/src/test/ui/consts/const-eval/promoted_errors.stderr
+++ /dev/null
@@ -1,60 +0,0 @@
-warning: this expression will panic at runtime
- --> $DIR/promoted_errors.rs:9:14
- |
-LL | let _x = 0u32 - 1;
- | ^^^^^^^^ attempt to subtract with overflow
- |
-note: the lint level is defined here
- --> $DIR/promoted_errors.rs:5:9
- |
-LL | #![warn(const_err)]
- | ^^^^^^^^^
-
-warning: attempt to divide by zero
- --> $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:11:20
- |
-LL | println!("{}", 1 / (1 - 1));
- | ^^^^^^^^^^^ dividing by zero
-
-warning: erroneous constant used
- --> $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:15:14
- |
-LL | let _x = 1 / (1 - 1);
- | ^^^^^^^^^^^
-
-warning: attempt to divide by zero
- --> $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:17:20
- |
-LL | println!("{}", 1 / (false as u32));
- | ^^^^^^^^^^^^^^^^^^ dividing by zero
-
-warning: erroneous constant used
- --> $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: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
deleted file mode 100644
index 62c77f7..0000000
--- a/src/test/ui/consts/const-eval/promoted_errors2.rs
+++ /dev/null
@@ -1,24 +0,0 @@
-// 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)]
-
-fn main() {
- println!("{}", 0u32 - 1);
- //~^ WARN attempt to subtract with overflow
- let _x = 0u32 - 1;
- //~^ 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
deleted file mode 100644
index d1a9cb9..0000000
--- a/src/test/ui/consts/const-eval/promoted_errors2.stderr
+++ /dev/null
@@ -1,66 +0,0 @@
-warning: attempt to subtract with overflow
- --> $DIR/promoted_errors2.rs:8:20
- |
-LL | println!("{}", 0u32 - 1);
- | ^^^^^^^^
- |
-note: the lint level is defined here
- --> $DIR/promoted_errors2.rs:5:9
- |
-LL | #![warn(const_err)]
- | ^^^^^^^^^
-
-warning: attempt to subtract with overflow
- --> $DIR/promoted_errors2.rs:10:14
- |
-LL | let _x = 0u32 - 1;
- | ^^^^^^^^
-
-warning: attempt to divide by zero
- --> $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:12:20
- |
-LL | println!("{}", 1 / (1 - 1));
- | ^^^^^^^^^^^ dividing by zero
-
-warning: erroneous constant used
- --> $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:16:14
- |
-LL | let _x = 1 / (1 - 1);
- | ^^^^^^^^^^^
-
-warning: attempt to divide by zero
- --> $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:18:20
- |
-LL | println!("{}", 1 / (false as u32));
- | ^^^^^^^^^^^^^^^^^^ dividing by zero
-
-warning: erroneous constant used
- --> $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:22:14
- |
-LL | let _x = 1 / (false as u32);
- | ^^^^^^^^^^^^^^^^^^
-
diff --git a/src/test/ui/consts/const-int-pow-rpass.rs b/src/test/ui/consts/const-int-pow-rpass.rs
index 8e84a90..b0fba19 100644
--- a/src/test/ui/consts/const-int-pow-rpass.rs
+++ b/src/test/ui/consts/const-int-pow-rpass.rs
@@ -1,11 +1,48 @@
// run-pass
+#![feature(const_int_pow)]
+#![feature(wrapping_next_power_of_two)]
+
const IS_POWER_OF_TWO_A: bool = 0u32.is_power_of_two();
const IS_POWER_OF_TWO_B: bool = 32u32.is_power_of_two();
const IS_POWER_OF_TWO_C: bool = 33u32.is_power_of_two();
+const POW: u8 = 3u8.pow(5);
+
+const CHECKED_POW_OK: Option<u8> = 3u8.checked_pow(5);
+const CHECKED_POW_OVERFLOW: Option<u8> = 3u8.checked_pow(6);
+
+const WRAPPING_POW: u8 = 3u8.wrapping_pow(6);
+const OVERFLOWING_POW: (u8, bool) = 3u8.overflowing_pow(6);
+const SATURATING_POW: u8 = 3u8.saturating_pow(6);
+
+const NEXT_POWER_OF_TWO: u32 = 3u32.next_power_of_two();
+
+const CHECKED_NEXT_POWER_OF_TWO_OK: Option<u32> = 3u32.checked_next_power_of_two();
+const CHECKED_NEXT_POWER_OF_TWO_OVERFLOW: Option<u32> =
+ u32::max_value().checked_next_power_of_two();
+
+const WRAPPING_NEXT_POWER_OF_TWO: u32 =
+ u32::max_value().wrapping_next_power_of_two();
+
fn main() {
assert!(!IS_POWER_OF_TWO_A);
assert!(IS_POWER_OF_TWO_B);
assert!(!IS_POWER_OF_TWO_C);
+
+ assert_eq!(POW, 243);
+
+ assert_eq!(CHECKED_POW_OK, Some(243));
+ assert_eq!(CHECKED_POW_OVERFLOW, None);
+
+ assert_eq!(WRAPPING_POW, 217);
+ assert_eq!(OVERFLOWING_POW, (217, true));
+ assert_eq!(SATURATING_POW, u8::max_value());
+
+ assert_eq!(NEXT_POWER_OF_TWO, 4);
+
+ assert_eq!(CHECKED_NEXT_POWER_OF_TWO_OK, Some(4));
+ assert_eq!(CHECKED_NEXT_POWER_OF_TWO_OVERFLOW, None);
+
+ assert_eq!(WRAPPING_NEXT_POWER_OF_TWO, 0);
}
diff --git a/src/test/ui/consts/const-prop-ice.rs b/src/test/ui/consts/const-prop-ice.rs
index 8682d2e..5bffe02 100644
--- a/src/test/ui/consts/const-prop-ice.rs
+++ b/src/test/ui/consts/const-prop-ice.rs
@@ -1,5 +1,5 @@
// build-fail
fn main() {
- [0; 3][3u64 as usize]; //~ ERROR the len is 3 but the index is 3
+ [0; 3][3u64 as usize]; //~ ERROR this operation will panic at runtime
}
diff --git a/src/test/ui/consts/const-prop-ice.stderr b/src/test/ui/consts/const-prop-ice.stderr
index 65502a4..7bb4acb 100644
--- a/src/test/ui/consts/const-prop-ice.stderr
+++ b/src/test/ui/consts/const-prop-ice.stderr
@@ -1,10 +1,10 @@
-error: index out of bounds: the len is 3 but the index is 3
+error: this operation will panic at runtime
--> $DIR/const-prop-ice.rs:4:5
|
LL | [0; 3][3u64 as usize];
- | ^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^ index out of bounds: the len is 3 but the index is 3
|
- = note: `#[deny(const_err)]` on by default
+ = note: `#[deny(unconditional_panic)]` on by default
error: aborting due to previous error
diff --git a/src/test/ui/consts/const-prop-ice2.rs b/src/test/ui/consts/const-prop-ice2.rs
index 6a73483..d533e39 100644
--- a/src/test/ui/consts/const-prop-ice2.rs
+++ b/src/test/ui/consts/const-prop-ice2.rs
@@ -3,5 +3,5 @@
fn main() {
enum Enum { One=1 }
let xs=[0;1 as usize];
- println!("{}", xs[Enum::One as usize]); //~ ERROR the len is 1 but the index is 1
+ println!("{}", xs[Enum::One as usize]); //~ ERROR this operation will panic at runtime
}
diff --git a/src/test/ui/consts/const-prop-ice2.stderr b/src/test/ui/consts/const-prop-ice2.stderr
index cbb8fde..73405ec 100644
--- a/src/test/ui/consts/const-prop-ice2.stderr
+++ b/src/test/ui/consts/const-prop-ice2.stderr
@@ -1,10 +1,10 @@
-error: index out of bounds: the len is 1 but the index is 1
+error: this operation will panic at runtime
--> $DIR/const-prop-ice2.rs:6:20
|
LL | println!("{}", xs[Enum::One as usize]);
- | ^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^ index out of bounds: the len is 1 but the index is 1
|
- = note: `#[deny(const_err)]` on by default
+ = note: `#[deny(unconditional_panic)]` on by default
error: aborting due to previous error
diff --git a/src/test/ui/consts/is_ascii.rs b/src/test/ui/consts/is_ascii.rs
new file mode 100644
index 0000000..d842454
--- /dev/null
+++ b/src/test/ui/consts/is_ascii.rs
@@ -0,0 +1,15 @@
+// run-pass
+
+static X: bool = 'a'.is_ascii();
+static Y: bool = 'ä'.is_ascii();
+
+static BX: bool = b'a'.is_ascii();
+static BY: bool = 192u8.is_ascii();
+
+fn main() {
+ assert!(X);
+ assert!(!Y);
+
+ assert!(BX);
+ assert!(!BY);
+}
diff --git a/src/test/ui/consts/issue-64059-2.rs b/src/test/ui/consts/issue-64059-2.rs
deleted file mode 100644
index 38911c3..0000000
--- a/src/test/ui/consts/issue-64059-2.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-// compile-flags: -C overflow-checks=on -O
-// run-pass
-
-fn main() {
- let _ = -(-0.0);
-}
diff --git a/src/test/ui/consts/issue-64059.rs b/src/test/ui/consts/issue-64059.rs
index c4c895f..02c8b72 100644
--- a/src/test/ui/consts/issue-64059.rs
+++ b/src/test/ui/consts/issue-64059.rs
@@ -1,3 +1,8 @@
+// revisions: noopt opt opt_with_overflow_checks
+//[noopt]compile-flags: -C opt-level=0
+//[opt]compile-flags: -O
+//[opt_with_overflow_checks]compile-flags: -C overflow-checks=on -O
+
// run-pass
fn main() {
diff --git a/src/test/ui/consts/issue-69020.noopt.stderr b/src/test/ui/consts/issue-69020.noopt.stderr
new file mode 100644
index 0000000..c48a106
--- /dev/null
+++ b/src/test/ui/consts/issue-69020.noopt.stderr
@@ -0,0 +1,30 @@
+error: this arithmetic operation will overflow
+ --> $DIR/issue-69020.rs:21:22
+ |
+LL | const NEG: i32 = -i32::MIN + T::NEG;
+ | ^^^^^^^^^ attempt to negate with overflow
+ |
+ = note: `#[deny(arithmetic_overflow)]` on by default
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-69020.rs:23:22
+ |
+LL | const ADD: i32 = (i32::MAX+1) + T::ADD;
+ | ^^^^^^^^^^^^ attempt to add with overflow
+
+error: this operation will panic at runtime
+ --> $DIR/issue-69020.rs:25:22
+ |
+LL | const DIV: i32 = (1/0) + T::DIV;
+ | ^^^^^ attempt to divide by zero
+ |
+ = note: `#[deny(unconditional_panic)]` on by default
+
+error: this operation will panic at runtime
+ --> $DIR/issue-69020.rs:27:22
+ |
+LL | const OOB: i32 = [1][1] + T::OOB;
+ | ^^^^^^ index out of bounds: the len is 1 but the index is 1
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/consts/issue-69020.opt.stderr b/src/test/ui/consts/issue-69020.opt.stderr
new file mode 100644
index 0000000..c48a106
--- /dev/null
+++ b/src/test/ui/consts/issue-69020.opt.stderr
@@ -0,0 +1,30 @@
+error: this arithmetic operation will overflow
+ --> $DIR/issue-69020.rs:21:22
+ |
+LL | const NEG: i32 = -i32::MIN + T::NEG;
+ | ^^^^^^^^^ attempt to negate with overflow
+ |
+ = note: `#[deny(arithmetic_overflow)]` on by default
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-69020.rs:23:22
+ |
+LL | const ADD: i32 = (i32::MAX+1) + T::ADD;
+ | ^^^^^^^^^^^^ attempt to add with overflow
+
+error: this operation will panic at runtime
+ --> $DIR/issue-69020.rs:25:22
+ |
+LL | const DIV: i32 = (1/0) + T::DIV;
+ | ^^^^^ attempt to divide by zero
+ |
+ = note: `#[deny(unconditional_panic)]` on by default
+
+error: this operation will panic at runtime
+ --> $DIR/issue-69020.rs:27:22
+ |
+LL | const OOB: i32 = [1][1] + T::OOB;
+ | ^^^^^^ index out of bounds: the len is 1 but the index is 1
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/consts/issue-69020.opt_with_overflow_checks.stderr b/src/test/ui/consts/issue-69020.opt_with_overflow_checks.stderr
new file mode 100644
index 0000000..c48a106
--- /dev/null
+++ b/src/test/ui/consts/issue-69020.opt_with_overflow_checks.stderr
@@ -0,0 +1,30 @@
+error: this arithmetic operation will overflow
+ --> $DIR/issue-69020.rs:21:22
+ |
+LL | const NEG: i32 = -i32::MIN + T::NEG;
+ | ^^^^^^^^^ attempt to negate with overflow
+ |
+ = note: `#[deny(arithmetic_overflow)]` on by default
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-69020.rs:23:22
+ |
+LL | const ADD: i32 = (i32::MAX+1) + T::ADD;
+ | ^^^^^^^^^^^^ attempt to add with overflow
+
+error: this operation will panic at runtime
+ --> $DIR/issue-69020.rs:25:22
+ |
+LL | const DIV: i32 = (1/0) + T::DIV;
+ | ^^^^^ attempt to divide by zero
+ |
+ = note: `#[deny(unconditional_panic)]` on by default
+
+error: this operation will panic at runtime
+ --> $DIR/issue-69020.rs:27:22
+ |
+LL | const OOB: i32 = [1][1] + T::OOB;
+ | ^^^^^^ index out of bounds: the len is 1 but the index is 1
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/consts/issue-69020.rs b/src/test/ui/consts/issue-69020.rs
new file mode 100644
index 0000000..e079feb
--- /dev/null
+++ b/src/test/ui/consts/issue-69020.rs
@@ -0,0 +1,29 @@
+// revisions: noopt opt opt_with_overflow_checks
+//[noopt]compile-flags: -C opt-level=0
+//[opt]compile-flags: -O
+//[opt_with_overflow_checks]compile-flags: -C overflow-checks=on -O
+
+#![crate_type="lib"]
+
+use std::i32;
+
+pub trait Foo {
+ const NEG: i32;
+ const ADD: i32;
+ const DIV: i32;
+ const OOB: i32;
+}
+
+// These constants cannot be evaluated already (they depend on `T::N`), so
+// they can just be linted like normal run-time code. But codegen works
+// a bit different in const context, so this test makes sure that we still catch overflow.
+impl<T: Foo> Foo for Vec<T> {
+ const NEG: i32 = -i32::MIN + T::NEG;
+ //~^ ERROR arithmetic operation will overflow
+ const ADD: i32 = (i32::MAX+1) + T::ADD;
+ //~^ ERROR arithmetic operation will overflow
+ const DIV: i32 = (1/0) + T::DIV;
+ //~^ ERROR operation will panic
+ const OOB: i32 = [1][1] + T::OOB;
+ //~^ ERROR operation will panic
+}
diff --git a/src/test/ui/consts/issue-69310-array-size-lit-wrong-ty.rs b/src/test/ui/consts/issue-69310-array-size-lit-wrong-ty.rs
new file mode 100644
index 0000000..98be8c3
--- /dev/null
+++ b/src/test/ui/consts/issue-69310-array-size-lit-wrong-ty.rs
@@ -0,0 +1,11 @@
+// This is a regression test for #69310, which was injected by #68118.
+// The issue here was that as a performance optimization,
+// we call the query `lit_to_const(input);`.
+// However, the literal `input.lit` would not be of the type expected by `input.ty`.
+// As a result, we immediately called `bug!(...)` instead of bubbling up the problem
+// so that it could be handled by the caller of `lit_to_const` (`ast_const_to_const`).
+
+fn main() {}
+
+const A: [(); 0.1] = [()]; //~ ERROR mismatched types
+const B: [(); b"a"] = [()]; //~ ERROR mismatched types
diff --git a/src/test/ui/consts/issue-69310-array-size-lit-wrong-ty.stderr b/src/test/ui/consts/issue-69310-array-size-lit-wrong-ty.stderr
new file mode 100644
index 0000000..7078b4b
--- /dev/null
+++ b/src/test/ui/consts/issue-69310-array-size-lit-wrong-ty.stderr
@@ -0,0 +1,15 @@
+error[E0308]: mismatched types
+ --> $DIR/issue-69310-array-size-lit-wrong-ty.rs:10:15
+ |
+LL | const A: [(); 0.1] = [()];
+ | ^^^ expected `usize`, found floating-point number
+
+error[E0308]: mismatched types
+ --> $DIR/issue-69310-array-size-lit-wrong-ty.rs:11:15
+ |
+LL | const B: [(); b"a"] = [()];
+ | ^^^^ expected `usize`, found `&[u8; 1]`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/consts/issue-69312.rs b/src/test/ui/consts/issue-69312.rs
new file mode 100644
index 0000000..413c675
--- /dev/null
+++ b/src/test/ui/consts/issue-69312.rs
@@ -0,0 +1,10 @@
+// build-pass
+
+// Verify that the compiler doesn't ICE during const prop while evaluating the index operation.
+
+#![allow(unconditional_panic)]
+
+fn main() {
+ let cols = [0u32; 0];
+ cols[0];
+}
diff --git a/src/test/ui/consts/std/char.rs b/src/test/ui/consts/std/char.rs
deleted file mode 100644
index fe79059..0000000
--- a/src/test/ui/consts/std/char.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-// run-pass
-
-static X: bool = 'a'.is_ascii();
-static Y: bool = 'ä'.is_ascii();
-
-fn main() {
- assert!(X);
- assert!(!Y);
-}
diff --git a/src/test/ui/error-codes/E0057.stderr b/src/test/ui/error-codes/E0057.stderr
index 6b5890c..31579e2 100644
--- a/src/test/ui/error-codes/E0057.stderr
+++ b/src/test/ui/error-codes/E0057.stderr
@@ -1,14 +1,18 @@
-error[E0057]: this function takes 1 parameter but 0 parameters were supplied
+error[E0057]: this function takes 1 argument but 0 arguments were supplied
--> $DIR/E0057.rs:3:13
|
LL | let a = f();
- | ^^^ expected 1 parameter
+ | ^-- supplied 0 arguments
+ | |
+ | expected 1 argument
-error[E0057]: this function takes 1 parameter but 2 parameters were supplied
+error[E0057]: this function takes 1 argument but 2 arguments were supplied
--> $DIR/E0057.rs:5:13
|
LL | let c = f(2, 3);
- | ^^^^^^^ expected 1 parameter
+ | ^ - - supplied 2 arguments
+ | |
+ | expected 1 argument
error: aborting due to 2 previous errors
diff --git a/src/test/ui/error-codes/E0060.rs b/src/test/ui/error-codes/E0060.rs
index 2bb490f..941eb2a2 100644
--- a/src/test/ui/error-codes/E0060.rs
+++ b/src/test/ui/error-codes/E0060.rs
@@ -5,5 +5,5 @@
fn main() {
unsafe { printf(); }
//~^ ERROR E0060
- //~| expected at least 1 parameter
+ //~| expected at least 1 argument
}
diff --git a/src/test/ui/error-codes/E0060.stderr b/src/test/ui/error-codes/E0060.stderr
index 8a2e7d1..a600592 100644
--- a/src/test/ui/error-codes/E0060.stderr
+++ b/src/test/ui/error-codes/E0060.stderr
@@ -1,11 +1,13 @@
-error[E0060]: this function takes at least 1 parameter but 0 parameters were supplied
+error[E0060]: this function takes at least 1 argument but 0 arguments were supplied
--> $DIR/E0060.rs:6:14
|
LL | fn printf(_: *const u8, ...) -> u32;
| ------------------------------------ defined here
...
LL | unsafe { printf(); }
- | ^^^^^^^^ expected at least 1 parameter
+ | ^^^^^^-- supplied 0 arguments
+ | |
+ | expected at least 1 argument
error: aborting due to previous error
diff --git a/src/test/ui/error-codes/E0061.rs b/src/test/ui/error-codes/E0061.rs
index e64ea36..c7b5fe4 100644
--- a/src/test/ui/error-codes/E0061.rs
+++ b/src/test/ui/error-codes/E0061.rs
@@ -5,9 +5,9 @@
fn main() {
f(0);
//~^ ERROR E0061
- //~| expected 2 parameters
+ //~| expected 2 arguments
f2();
//~^ ERROR E0061
- //~| expected 1 parameter
+ //~| expected 1 argument
}
diff --git a/src/test/ui/error-codes/E0061.stderr b/src/test/ui/error-codes/E0061.stderr
index 7310324..dfefa0d 100644
--- a/src/test/ui/error-codes/E0061.stderr
+++ b/src/test/ui/error-codes/E0061.stderr
@@ -1,20 +1,24 @@
-error[E0061]: this function takes 2 parameters but 1 parameter was supplied
+error[E0061]: this function takes 2 arguments but 1 argument was supplied
--> $DIR/E0061.rs:6:5
|
LL | fn f(a: u16, b: &str) {}
| --------------------- defined here
...
LL | f(0);
- | ^^^^ expected 2 parameters
+ | ^ - supplied 1 argument
+ | |
+ | expected 2 arguments
-error[E0061]: this function takes 1 parameter but 0 parameters were supplied
+error[E0061]: this function takes 1 argument but 0 arguments were supplied
--> $DIR/E0061.rs:10:5
|
LL | fn f2(a: u16) {}
| ------------- defined here
...
LL | f2();
- | ^^^^ expected 1 parameter
+ | ^^-- supplied 0 arguments
+ | |
+ | expected 1 argument
error: aborting due to 2 previous errors
diff --git a/src/test/ui/feature-gates/feature-gate-infer_static_outlives_requirements.stderr b/src/test/ui/feature-gates/feature-gate-infer_static_outlives_requirements.stderr
index 689a375..fbc4e8a 100644
--- a/src/test/ui/feature-gates/feature-gate-infer_static_outlives_requirements.stderr
+++ b/src/test/ui/feature-gates/feature-gate-infer_static_outlives_requirements.stderr
@@ -2,7 +2,7 @@
--> $DIR/feature-gate-infer_static_outlives_requirements.rs:5:5
|
LL | struct Foo<U> {
- | - help: consider adding an explicit lifetime bound `U: 'static`...
+ | - help: consider adding an explicit lifetime bound...: `U: 'static`
LL | bar: Bar<U>
| ^^^^^^^^^^^
|
diff --git a/src/test/ui/generator/issue-69039.rs b/src/test/ui/generator/issue-69039.rs
new file mode 100644
index 0000000..60004f3
--- /dev/null
+++ b/src/test/ui/generator/issue-69039.rs
@@ -0,0 +1,30 @@
+// run-pass
+
+#![feature(generators, generator_trait)]
+
+use std::ops::{Generator, GeneratorState};
+
+fn my_scenario() -> impl Generator<String, Yield = &'static str, Return = String> {
+ |_arg: String| {
+ let my_name = yield "What is your name?";
+ let my_mood = yield "How are you feeling?";
+ format!("{} is {}", my_name.trim(), my_mood.trim())
+ }
+}
+
+fn main() {
+ let mut my_session = Box::pin(my_scenario());
+
+ assert_eq!(
+ my_session.as_mut().resume("_arg".to_string()),
+ GeneratorState::Yielded("What is your name?")
+ );
+ assert_eq!(
+ my_session.as_mut().resume("Your Name".to_string()),
+ GeneratorState::Yielded("How are you feeling?")
+ );
+ assert_eq!(
+ my_session.as_mut().resume("Sensory Organs".to_string()),
+ GeneratorState::Complete("Your Name is Sensory Organs".to_string())
+ );
+}
diff --git a/src/test/ui/hrtb/issue-58451.rs b/src/test/ui/hrtb/issue-58451.rs
index 229e505..f36d549 100644
--- a/src/test/ui/hrtb/issue-58451.rs
+++ b/src/test/ui/hrtb/issue-58451.rs
@@ -9,5 +9,5 @@
{}
fn main() {
- f(&[f()]); //~ ERROR this function takes 1 parameter
+ f(&[f()]); //~ ERROR this function takes 1 argument
}
diff --git a/src/test/ui/hrtb/issue-58451.stderr b/src/test/ui/hrtb/issue-58451.stderr
index 4648c01..c091580 100644
--- a/src/test/ui/hrtb/issue-58451.stderr
+++ b/src/test/ui/hrtb/issue-58451.stderr
@@ -1,4 +1,4 @@
-error[E0061]: this function takes 1 parameter but 0 parameters were supplied
+error[E0061]: this function takes 1 argument but 0 arguments were supplied
--> $DIR/issue-58451.rs:12:9
|
LL | / fn f<I>(i: I)
@@ -9,7 +9,9 @@
| |__- defined here
...
LL | f(&[f()]);
- | ^^^ expected 1 parameter
+ | ^-- supplied 0 arguments
+ | |
+ | expected 1 argument
error: aborting due to previous error
diff --git a/src/test/ui/huge-array-simple-32.rs b/src/test/ui/huge-array-simple-32.rs
index 3e574df..2290e3d 100644
--- a/src/test/ui/huge-array-simple-32.rs
+++ b/src/test/ui/huge-array-simple-32.rs
@@ -4,7 +4,7 @@
// FIXME https://github.com/rust-lang/rust/issues/59774
// normalize-stderr-test "thread.*panicked.*Metadata module not compiled.*\n" -> ""
// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> ""
-#![allow(exceeding_bitshifts)]
+#![allow(arithmetic_overflow)]
fn main() {
let _fat: [u8; (1<<31)+(1<<15)] = //~ ERROR too big for the current architecture
diff --git a/src/test/ui/huge-array-simple-64.rs b/src/test/ui/huge-array-simple-64.rs
index d4c9330..02c961f 100644
--- a/src/test/ui/huge-array-simple-64.rs
+++ b/src/test/ui/huge-array-simple-64.rs
@@ -4,7 +4,7 @@
// FIXME https://github.com/rust-lang/rust/issues/59774
// normalize-stderr-test "thread.*panicked.*Metadata module not compiled.*\n" -> ""
// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> ""
-#![allow(exceeding_bitshifts)]
+#![allow(arithmetic_overflow)]
fn main() {
let _fat: [u8; (1<<61)+(1<<31)] = //~ ERROR too big for the current architecture
diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr
index 7f92e70..cffa5ee 100644
--- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr
+++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr
@@ -67,7 +67,7 @@
LL | fn ty_param_wont_outlive_static<T:Debug>(x: T) -> impl Debug + 'static {
| -- ^^^^^^^^^^^^^^^^^^^^
| |
- | help: consider adding an explicit lifetime bound `T: 'static`...
+ | help: consider adding an explicit lifetime bound...: `T: 'static +`
|
note: ...so that the type `T` will meet its required lifetime bounds
--> $DIR/must_outlive_least_region_or_bound.rs:22:51
diff --git a/src/test/ui/impl-trait/type_parameters_captured.stderr b/src/test/ui/impl-trait/type_parameters_captured.stderr
index 708b479..34f0f7f 100644
--- a/src/test/ui/impl-trait/type_parameters_captured.stderr
+++ b/src/test/ui/impl-trait/type_parameters_captured.stderr
@@ -4,7 +4,7 @@
LL | fn foo<T>(x: T) -> impl Any + 'static {
| - ^^^^^^^^^^^^^^^^^^
| |
- | help: consider adding an explicit lifetime bound `T: 'static`...
+ | help: consider adding an explicit lifetime bound...: `T: 'static`
|
note: ...so that the type `T` will meet its required lifetime bounds
--> $DIR/type_parameters_captured.rs:7:20
diff --git a/src/test/ui/issues/issue-16939.stderr b/src/test/ui/issues/issue-16939.stderr
index 5df2119..103f56f 100644
--- a/src/test/ui/issues/issue-16939.stderr
+++ b/src/test/ui/issues/issue-16939.stderr
@@ -1,8 +1,10 @@
-error[E0057]: this function takes 0 parameters but 1 parameter was supplied
+error[E0057]: this function takes 0 arguments but 1 argument was supplied
--> $DIR/issue-16939.rs:5:9
|
LL | |t| f(t);
- | ^^^^ expected 0 parameters
+ | ^ - supplied 1 argument
+ | |
+ | expected 0 arguments
error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-18819.stderr b/src/test/ui/issues/issue-18819.stderr
index 41e8470..a952c9b 100644
--- a/src/test/ui/issues/issue-18819.stderr
+++ b/src/test/ui/issues/issue-18819.stderr
@@ -1,11 +1,13 @@
-error[E0061]: this function takes 2 parameters but 1 parameter was supplied
+error[E0061]: this function takes 2 arguments but 1 argument was supplied
--> $DIR/issue-18819.rs:16:5
|
LL | fn print_x(_: &dyn Foo<Item=bool>, extra: &str) {
| ----------------------------------------------- defined here
...
LL | print_x(X);
- | ^^^^^^^^^^ expected 2 parameters
+ | ^^^^^^^ - supplied 1 argument
+ | |
+ | expected 2 arguments
error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-26094.rs b/src/test/ui/issues/issue-26094.rs
index b943384..78fb049 100644
--- a/src/test/ui/issues/issue-26094.rs
+++ b/src/test/ui/issues/issue-26094.rs
@@ -1,13 +1,13 @@
macro_rules! some_macro {
($other: expr) => ({
- $other(None)
- //~^ this function takes 0 parameters but 1 parameter was supplied
+ $other(None) //~ NOTE supplied 1 argument
})
}
-fn some_function() {}
+fn some_function() {} //~ NOTE defined here
fn main() {
some_macro!(some_function);
- //~^ in this expansion of some_macro!
+ //~^ ERROR this function takes 0 arguments but 1 argument was supplied
+ //~| NOTE expected 0 arguments
}
diff --git a/src/test/ui/issues/issue-26094.stderr b/src/test/ui/issues/issue-26094.stderr
index 0b5b6d5..2038d88 100644
--- a/src/test/ui/issues/issue-26094.stderr
+++ b/src/test/ui/issues/issue-26094.stderr
@@ -1,16 +1,14 @@
-error[E0061]: this function takes 0 parameters but 1 parameter was supplied
- --> $DIR/issue-26094.rs:3:9
+error[E0061]: this function takes 0 arguments but 1 argument was supplied
+ --> $DIR/issue-26094.rs:10:17
|
LL | $other(None)
- | ^^^^^^^^^^^^ expected 0 parameters
+ | ---- supplied 1 argument
...
LL | fn some_function() {}
| ------------------ defined here
...
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)
+ | ^^^^^^^^^^^^^ expected 0 arguments
error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-3044.rs b/src/test/ui/issues/issue-3044.rs
index 26db04b..81d76a9 100644
--- a/src/test/ui/issues/issue-3044.rs
+++ b/src/test/ui/issues/issue-3044.rs
@@ -2,5 +2,5 @@
let needlesArr: Vec<char> = vec!['a', 'f'];
needlesArr.iter().fold(|x, y| {
});
- //~^^ ERROR this function takes 2 parameters but 1 parameter was supplied
+ //~^^ ERROR this function takes 2 arguments but 1 argument was supplied
}
diff --git a/src/test/ui/issues/issue-3044.stderr b/src/test/ui/issues/issue-3044.stderr
index 35a85b6..d2c0106 100644
--- a/src/test/ui/issues/issue-3044.stderr
+++ b/src/test/ui/issues/issue-3044.stderr
@@ -1,8 +1,12 @@
-error[E0061]: this function takes 2 parameters but 1 parameter was supplied
+error[E0061]: this function takes 2 arguments but 1 argument was supplied
--> $DIR/issue-3044.rs:3:23
|
-LL | needlesArr.iter().fold(|x, y| {
- | ^^^^ expected 2 parameters
+LL | needlesArr.iter().fold(|x, y| {
+ | _______________________^^^^_-
+ | | |
+ | | expected 2 arguments
+LL | | });
+ | |_____- supplied 1 argument
error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-4935.rs b/src/test/ui/issues/issue-4935.rs
index 3b258c3..b342bbb 100644
--- a/src/test/ui/issues/issue-4935.rs
+++ b/src/test/ui/issues/issue-4935.rs
@@ -3,4 +3,4 @@
fn foo(a: usize) {}
//~^ defined here
fn main() { foo(5, 6) }
-//~^ ERROR this function takes 1 parameter but 2 parameters were supplied
+//~^ ERROR this function takes 1 argument but 2 arguments were supplied
diff --git a/src/test/ui/issues/issue-4935.stderr b/src/test/ui/issues/issue-4935.stderr
index a99581f..0cc686e 100644
--- a/src/test/ui/issues/issue-4935.stderr
+++ b/src/test/ui/issues/issue-4935.stderr
@@ -1,11 +1,13 @@
-error[E0061]: this function takes 1 parameter but 2 parameters were supplied
+error[E0061]: this function takes 1 argument but 2 arguments were supplied
--> $DIR/issue-4935.rs:5:13
|
LL | fn foo(a: usize) {}
| ---------------- defined here
LL |
LL | fn main() { foo(5, 6) }
- | ^^^^^^^^^ expected 1 parameter
+ | ^^^ - - supplied 2 arguments
+ | |
+ | expected 1 argument
error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-54348.rs b/src/test/ui/issues/issue-54348.rs
index fd9a9e0..5c38d7c 100644
--- a/src/test/ui/issues/issue-54348.rs
+++ b/src/test/ui/issues/issue-54348.rs
@@ -2,6 +2,6 @@
fn main() {
[1][0u64 as usize];
- [1][1.5 as usize]; //~ ERROR index out of bounds
- [1][1u64 as usize]; //~ ERROR index out of bounds
+ [1][1.5 as usize]; //~ ERROR operation will panic
+ [1][1u64 as usize]; //~ ERROR operation will panic
}
diff --git a/src/test/ui/issues/issue-54348.stderr b/src/test/ui/issues/issue-54348.stderr
index 7619cd7..6b67125 100644
--- a/src/test/ui/issues/issue-54348.stderr
+++ b/src/test/ui/issues/issue-54348.stderr
@@ -1,16 +1,16 @@
-error: index out of bounds: the len is 1 but the index is 1
+error: this operation will panic at runtime
--> $DIR/issue-54348.rs:5:5
|
LL | [1][1.5 as usize];
- | ^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^ index out of bounds: the len is 1 but the index is 1
|
- = note: `#[deny(const_err)]` on by default
+ = note: `#[deny(unconditional_panic)]` on by default
-error: index out of bounds: the len is 1 but the index is 1
+error: this operation will panic at runtime
--> $DIR/issue-54348.rs:6:5
|
LL | [1][1u64 as usize];
- | ^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^ index out of bounds: the len is 1 but the index is 1
error: aborting due to 2 previous errors
diff --git a/src/test/ui/issues/issue-8460-const.noopt.stderr b/src/test/ui/issues/issue-8460-const.noopt.stderr
new file mode 100644
index 0000000..3556ec0
--- /dev/null
+++ b/src/test/ui/issues/issue-8460-const.noopt.stderr
@@ -0,0 +1,150 @@
+error: this arithmetic operation will overflow
+ --> $DIR/issue-8460-const.rs:14:36
+ |
+LL | assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err());
+ | ^^^^^^^^^^^^^^^ attempt to divide with overflow
+ |
+ = note: `#[deny(arithmetic_overflow)]` on by default
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-8460-const.rs:16:36
+ |
+LL | assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err());
+ | ^^^^^^^^^^^^ attempt to divide with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-8460-const.rs:18:36
+ |
+LL | assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err());
+ | ^^^^^^^^^^^^^ attempt to divide with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-8460-const.rs:20:36
+ |
+LL | assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err());
+ | ^^^^^^^^^^^^^ attempt to divide with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-8460-const.rs:22:36
+ |
+LL | assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err());
+ | ^^^^^^^^^^^^^ attempt to divide with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-8460-const.rs:24:36
+ |
+LL | assert!(thread::spawn(move|| { i128::MIN / -1; }).join().is_err());
+ | ^^^^^^^^^^^^^^ attempt to divide with overflow
+
+error: this operation will panic at runtime
+ --> $DIR/issue-8460-const.rs:26:36
+ |
+LL | assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err());
+ | ^^^^^^^^^^ attempt to divide by zero
+ |
+ = note: `#[deny(unconditional_panic)]` on by default
+
+error: this operation will panic at runtime
+ --> $DIR/issue-8460-const.rs:28:36
+ |
+LL | assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err());
+ | ^^^^^^^ attempt to divide by zero
+
+error: this operation will panic at runtime
+ --> $DIR/issue-8460-const.rs:30:36
+ |
+LL | assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err());
+ | ^^^^^^^^ attempt to divide by zero
+
+error: this operation will panic at runtime
+ --> $DIR/issue-8460-const.rs:32:36
+ |
+LL | assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err());
+ | ^^^^^^^^ attempt to divide by zero
+
+error: this operation will panic at runtime
+ --> $DIR/issue-8460-const.rs:34:36
+ |
+LL | assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err());
+ | ^^^^^^^^ attempt to divide by zero
+
+error: this operation will panic at runtime
+ --> $DIR/issue-8460-const.rs:36:36
+ |
+LL | assert!(thread::spawn(move|| { 1i128 / 0; }).join().is_err());
+ | ^^^^^^^^^ attempt to divide by zero
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-8460-const.rs:38:36
+ |
+LL | assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err());
+ | ^^^^^^^^^^^^^^^ attempt to calculate the remainder with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-8460-const.rs:40:36
+ |
+LL | assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err());
+ | ^^^^^^^^^^^^ attempt to calculate the remainder with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-8460-const.rs:42:36
+ |
+LL | assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err());
+ | ^^^^^^^^^^^^^ attempt to calculate the remainder with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-8460-const.rs:44:36
+ |
+LL | assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err());
+ | ^^^^^^^^^^^^^ attempt to calculate the remainder with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-8460-const.rs:46:36
+ |
+LL | assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err());
+ | ^^^^^^^^^^^^^ attempt to calculate the remainder with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-8460-const.rs:48:36
+ |
+LL | assert!(thread::spawn(move|| { i128::MIN % -1; }).join().is_err());
+ | ^^^^^^^^^^^^^^ attempt to calculate the remainder with overflow
+
+error: this operation will panic at runtime
+ --> $DIR/issue-8460-const.rs:50:36
+ |
+LL | assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err());
+ | ^^^^^^^^^^ attempt to calculate the remainder with a divisor of zero
+
+error: this operation will panic at runtime
+ --> $DIR/issue-8460-const.rs:52:36
+ |
+LL | assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err());
+ | ^^^^^^^ attempt to calculate the remainder with a divisor of zero
+
+error: this operation will panic at runtime
+ --> $DIR/issue-8460-const.rs:54:36
+ |
+LL | assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err());
+ | ^^^^^^^^ attempt to calculate the remainder with a divisor of zero
+
+error: this operation will panic at runtime
+ --> $DIR/issue-8460-const.rs:56:36
+ |
+LL | assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err());
+ | ^^^^^^^^ attempt to calculate the remainder with a divisor of zero
+
+error: this operation will panic at runtime
+ --> $DIR/issue-8460-const.rs:58:36
+ |
+LL | assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err());
+ | ^^^^^^^^ attempt to calculate the remainder with a divisor of zero
+
+error: this operation will panic at runtime
+ --> $DIR/issue-8460-const.rs:60:36
+ |
+LL | assert!(thread::spawn(move|| { 1i128 % 0; }).join().is_err());
+ | ^^^^^^^^^ attempt to calculate the remainder with a divisor of zero
+
+error: aborting due to 24 previous errors
+
diff --git a/src/test/ui/issues/issue-8460-const.opt.stderr b/src/test/ui/issues/issue-8460-const.opt.stderr
new file mode 100644
index 0000000..3556ec0
--- /dev/null
+++ b/src/test/ui/issues/issue-8460-const.opt.stderr
@@ -0,0 +1,150 @@
+error: this arithmetic operation will overflow
+ --> $DIR/issue-8460-const.rs:14:36
+ |
+LL | assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err());
+ | ^^^^^^^^^^^^^^^ attempt to divide with overflow
+ |
+ = note: `#[deny(arithmetic_overflow)]` on by default
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-8460-const.rs:16:36
+ |
+LL | assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err());
+ | ^^^^^^^^^^^^ attempt to divide with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-8460-const.rs:18:36
+ |
+LL | assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err());
+ | ^^^^^^^^^^^^^ attempt to divide with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-8460-const.rs:20:36
+ |
+LL | assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err());
+ | ^^^^^^^^^^^^^ attempt to divide with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-8460-const.rs:22:36
+ |
+LL | assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err());
+ | ^^^^^^^^^^^^^ attempt to divide with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-8460-const.rs:24:36
+ |
+LL | assert!(thread::spawn(move|| { i128::MIN / -1; }).join().is_err());
+ | ^^^^^^^^^^^^^^ attempt to divide with overflow
+
+error: this operation will panic at runtime
+ --> $DIR/issue-8460-const.rs:26:36
+ |
+LL | assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err());
+ | ^^^^^^^^^^ attempt to divide by zero
+ |
+ = note: `#[deny(unconditional_panic)]` on by default
+
+error: this operation will panic at runtime
+ --> $DIR/issue-8460-const.rs:28:36
+ |
+LL | assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err());
+ | ^^^^^^^ attempt to divide by zero
+
+error: this operation will panic at runtime
+ --> $DIR/issue-8460-const.rs:30:36
+ |
+LL | assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err());
+ | ^^^^^^^^ attempt to divide by zero
+
+error: this operation will panic at runtime
+ --> $DIR/issue-8460-const.rs:32:36
+ |
+LL | assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err());
+ | ^^^^^^^^ attempt to divide by zero
+
+error: this operation will panic at runtime
+ --> $DIR/issue-8460-const.rs:34:36
+ |
+LL | assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err());
+ | ^^^^^^^^ attempt to divide by zero
+
+error: this operation will panic at runtime
+ --> $DIR/issue-8460-const.rs:36:36
+ |
+LL | assert!(thread::spawn(move|| { 1i128 / 0; }).join().is_err());
+ | ^^^^^^^^^ attempt to divide by zero
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-8460-const.rs:38:36
+ |
+LL | assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err());
+ | ^^^^^^^^^^^^^^^ attempt to calculate the remainder with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-8460-const.rs:40:36
+ |
+LL | assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err());
+ | ^^^^^^^^^^^^ attempt to calculate the remainder with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-8460-const.rs:42:36
+ |
+LL | assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err());
+ | ^^^^^^^^^^^^^ attempt to calculate the remainder with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-8460-const.rs:44:36
+ |
+LL | assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err());
+ | ^^^^^^^^^^^^^ attempt to calculate the remainder with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-8460-const.rs:46:36
+ |
+LL | assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err());
+ | ^^^^^^^^^^^^^ attempt to calculate the remainder with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-8460-const.rs:48:36
+ |
+LL | assert!(thread::spawn(move|| { i128::MIN % -1; }).join().is_err());
+ | ^^^^^^^^^^^^^^ attempt to calculate the remainder with overflow
+
+error: this operation will panic at runtime
+ --> $DIR/issue-8460-const.rs:50:36
+ |
+LL | assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err());
+ | ^^^^^^^^^^ attempt to calculate the remainder with a divisor of zero
+
+error: this operation will panic at runtime
+ --> $DIR/issue-8460-const.rs:52:36
+ |
+LL | assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err());
+ | ^^^^^^^ attempt to calculate the remainder with a divisor of zero
+
+error: this operation will panic at runtime
+ --> $DIR/issue-8460-const.rs:54:36
+ |
+LL | assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err());
+ | ^^^^^^^^ attempt to calculate the remainder with a divisor of zero
+
+error: this operation will panic at runtime
+ --> $DIR/issue-8460-const.rs:56:36
+ |
+LL | assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err());
+ | ^^^^^^^^ attempt to calculate the remainder with a divisor of zero
+
+error: this operation will panic at runtime
+ --> $DIR/issue-8460-const.rs:58:36
+ |
+LL | assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err());
+ | ^^^^^^^^ attempt to calculate the remainder with a divisor of zero
+
+error: this operation will panic at runtime
+ --> $DIR/issue-8460-const.rs:60:36
+ |
+LL | assert!(thread::spawn(move|| { 1i128 % 0; }).join().is_err());
+ | ^^^^^^^^^ attempt to calculate the remainder with a divisor of zero
+
+error: aborting due to 24 previous errors
+
diff --git a/src/test/ui/issues/issue-8460-const.opt_with_overflow_checks.stderr b/src/test/ui/issues/issue-8460-const.opt_with_overflow_checks.stderr
new file mode 100644
index 0000000..3556ec0
--- /dev/null
+++ b/src/test/ui/issues/issue-8460-const.opt_with_overflow_checks.stderr
@@ -0,0 +1,150 @@
+error: this arithmetic operation will overflow
+ --> $DIR/issue-8460-const.rs:14:36
+ |
+LL | assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err());
+ | ^^^^^^^^^^^^^^^ attempt to divide with overflow
+ |
+ = note: `#[deny(arithmetic_overflow)]` on by default
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-8460-const.rs:16:36
+ |
+LL | assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err());
+ | ^^^^^^^^^^^^ attempt to divide with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-8460-const.rs:18:36
+ |
+LL | assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err());
+ | ^^^^^^^^^^^^^ attempt to divide with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-8460-const.rs:20:36
+ |
+LL | assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err());
+ | ^^^^^^^^^^^^^ attempt to divide with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-8460-const.rs:22:36
+ |
+LL | assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err());
+ | ^^^^^^^^^^^^^ attempt to divide with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-8460-const.rs:24:36
+ |
+LL | assert!(thread::spawn(move|| { i128::MIN / -1; }).join().is_err());
+ | ^^^^^^^^^^^^^^ attempt to divide with overflow
+
+error: this operation will panic at runtime
+ --> $DIR/issue-8460-const.rs:26:36
+ |
+LL | assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err());
+ | ^^^^^^^^^^ attempt to divide by zero
+ |
+ = note: `#[deny(unconditional_panic)]` on by default
+
+error: this operation will panic at runtime
+ --> $DIR/issue-8460-const.rs:28:36
+ |
+LL | assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err());
+ | ^^^^^^^ attempt to divide by zero
+
+error: this operation will panic at runtime
+ --> $DIR/issue-8460-const.rs:30:36
+ |
+LL | assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err());
+ | ^^^^^^^^ attempt to divide by zero
+
+error: this operation will panic at runtime
+ --> $DIR/issue-8460-const.rs:32:36
+ |
+LL | assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err());
+ | ^^^^^^^^ attempt to divide by zero
+
+error: this operation will panic at runtime
+ --> $DIR/issue-8460-const.rs:34:36
+ |
+LL | assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err());
+ | ^^^^^^^^ attempt to divide by zero
+
+error: this operation will panic at runtime
+ --> $DIR/issue-8460-const.rs:36:36
+ |
+LL | assert!(thread::spawn(move|| { 1i128 / 0; }).join().is_err());
+ | ^^^^^^^^^ attempt to divide by zero
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-8460-const.rs:38:36
+ |
+LL | assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err());
+ | ^^^^^^^^^^^^^^^ attempt to calculate the remainder with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-8460-const.rs:40:36
+ |
+LL | assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err());
+ | ^^^^^^^^^^^^ attempt to calculate the remainder with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-8460-const.rs:42:36
+ |
+LL | assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err());
+ | ^^^^^^^^^^^^^ attempt to calculate the remainder with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-8460-const.rs:44:36
+ |
+LL | assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err());
+ | ^^^^^^^^^^^^^ attempt to calculate the remainder with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-8460-const.rs:46:36
+ |
+LL | assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err());
+ | ^^^^^^^^^^^^^ attempt to calculate the remainder with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/issue-8460-const.rs:48:36
+ |
+LL | assert!(thread::spawn(move|| { i128::MIN % -1; }).join().is_err());
+ | ^^^^^^^^^^^^^^ attempt to calculate the remainder with overflow
+
+error: this operation will panic at runtime
+ --> $DIR/issue-8460-const.rs:50:36
+ |
+LL | assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err());
+ | ^^^^^^^^^^ attempt to calculate the remainder with a divisor of zero
+
+error: this operation will panic at runtime
+ --> $DIR/issue-8460-const.rs:52:36
+ |
+LL | assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err());
+ | ^^^^^^^ attempt to calculate the remainder with a divisor of zero
+
+error: this operation will panic at runtime
+ --> $DIR/issue-8460-const.rs:54:36
+ |
+LL | assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err());
+ | ^^^^^^^^ attempt to calculate the remainder with a divisor of zero
+
+error: this operation will panic at runtime
+ --> $DIR/issue-8460-const.rs:56:36
+ |
+LL | assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err());
+ | ^^^^^^^^ attempt to calculate the remainder with a divisor of zero
+
+error: this operation will panic at runtime
+ --> $DIR/issue-8460-const.rs:58:36
+ |
+LL | assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err());
+ | ^^^^^^^^ attempt to calculate the remainder with a divisor of zero
+
+error: this operation will panic at runtime
+ --> $DIR/issue-8460-const.rs:60:36
+ |
+LL | assert!(thread::spawn(move|| { 1i128 % 0; }).join().is_err());
+ | ^^^^^^^^^ attempt to calculate the remainder with a divisor of zero
+
+error: aborting due to 24 previous errors
+
diff --git a/src/test/ui/issues/issue-8460-const.rs b/src/test/ui/issues/issue-8460-const.rs
index 5866cef..53005e4 100644
--- a/src/test/ui/issues/issue-8460-const.rs
+++ b/src/test/ui/issues/issue-8460-const.rs
@@ -1,5 +1,9 @@
+// revisions: noopt opt opt_with_overflow_checks
+//[noopt]compile-flags: -C opt-level=0
+//[opt]compile-flags: -O
+//[opt_with_overflow_checks]compile-flags: -C overflow-checks=on -O
+
// build-fail
-// compile-flags: -O
#![deny(const_err)]
@@ -8,63 +12,51 @@
fn main() {
assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err());
- //~^ ERROR attempt to divide with overflow
- //~| ERROR this expression will panic at runtime
+ //~^ ERROR arithmetic operation will overflow
assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err());
- //~^ ERROR attempt to divide with overflow
- //~| ERROR this expression will panic at runtime
+ //~^ ERROR arithmetic operation will overflow
assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err());
- //~^ ERROR attempt to divide with overflow
- //~| ERROR this expression will panic at runtime
+ //~^ ERROR arithmetic operation will overflow
assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err());
- //~^ ERROR attempt to divide with overflow
- //~| ERROR this expression will panic at runtime
+ //~^ ERROR arithmetic operation will overflow
assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err());
- //~^ ERROR attempt to divide with overflow
- //~| ERROR this expression will panic at runtime
+ //~^ ERROR arithmetic operation will overflow
assert!(thread::spawn(move|| { i128::MIN / -1; }).join().is_err());
- //~^ ERROR attempt to divide with overflow
- //~| ERROR this expression will panic at runtime
+ //~^ ERROR arithmetic operation will overflow
assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err());
- //~^ ERROR attempt to divide by zero
+ //~^ ERROR operation will panic
assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err());
- //~^ ERROR attempt to divide by zero
+ //~^ ERROR operation will panic
assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err());
- //~^ ERROR attempt to divide by zero
+ //~^ ERROR operation will panic
assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err());
- //~^ ERROR attempt to divide by zero
+ //~^ ERROR operation will panic
assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err());
- //~^ ERROR attempt to divide by zero
+ //~^ ERROR operation will panic
assert!(thread::spawn(move|| { 1i128 / 0; }).join().is_err());
- //~^ ERROR attempt to divide by zero
+ //~^ ERROR operation will panic
assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err());
- //~^ ERROR attempt to calculate the remainder with overflow
- //~| ERROR this expression will panic at runtime
+ //~^ ERROR arithmetic operation will overflow
assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err());
- //~^ ERROR attempt to calculate the remainder with overflow
- //~| ERROR this expression will panic at runtime
+ //~^ ERROR arithmetic operation will overflow
assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err());
- //~^ ERROR attempt to calculate the remainder with overflow
- //~| ERROR this expression will panic at runtime
+ //~^ ERROR arithmetic operation will overflow
assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err());
- //~^ ERROR attempt to calculate the remainder with overflow
- //~| ERROR this expression will panic at runtime
+ //~^ ERROR arithmetic operation will overflow
assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err());
- //~^ ERROR attempt to calculate the remainder with overflow
- //~| ERROR this expression will panic at runtime
+ //~^ ERROR arithmetic operation will overflow
assert!(thread::spawn(move|| { i128::MIN % -1; }).join().is_err());
- //~^ ERROR attempt to calculate the remainder with overflow
- //~| ERROR this expression will panic at runtime
+ //~^ ERROR arithmetic operation will overflow
assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err());
- //~^ ERROR attempt to calculate the remainder with a divisor of zero
+ //~^ ERROR operation will panic
assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err());
- //~^ ERROR attempt to calculate the remainder with a divisor of zero
+ //~^ ERROR operation will panic
assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err());
- //~^ ERROR attempt to calculate the remainder with a divisor of zero
+ //~^ ERROR operation will panic
assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err());
- //~^ ERROR attempt to calculate the remainder with a divisor of zero
+ //~^ ERROR operation will panic
assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err());
- //~^ ERROR attempt to calculate the remainder with a divisor of zero
+ //~^ ERROR operation will panic
assert!(thread::spawn(move|| { 1i128 % 0; }).join().is_err());
- //~^ ERROR attempt to calculate the remainder with a divisor of zero
+ //~^ ERROR operation will panic
}
diff --git a/src/test/ui/issues/issue-8460-const.stderr b/src/test/ui/issues/issue-8460-const.stderr
deleted file mode 100644
index d737394..0000000
--- a/src/test/ui/issues/issue-8460-const.stderr
+++ /dev/null
@@ -1,224 +0,0 @@
-error: attempt to divide with overflow
- --> $DIR/issue-8460-const.rs:10:36
- |
-LL | assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err());
- | ^^^^^^^^^^^^^^^
- |
-note: the lint level is defined here
- --> $DIR/issue-8460-const.rs:4:9
- |
-LL | #![deny(const_err)]
- | ^^^^^^^^^
-
-error: this expression will panic at runtime
- --> $DIR/issue-8460-const.rs:10:36
- |
-LL | assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err());
- | ^^^^^^^^^^^^^^^ attempt to divide with overflow
-
-error: attempt to divide with overflow
- --> $DIR/issue-8460-const.rs:13:36
- |
-LL | assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err());
- | ^^^^^^^^^^^^
-
-error: this expression will panic at runtime
- --> $DIR/issue-8460-const.rs:13:36
- |
-LL | assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err());
- | ^^^^^^^^^^^^ attempt to divide with overflow
-
-error: attempt to divide with overflow
- --> $DIR/issue-8460-const.rs:16:36
- |
-LL | assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err());
- | ^^^^^^^^^^^^^
-
-error: this expression will panic at runtime
- --> $DIR/issue-8460-const.rs:16:36
- |
-LL | assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err());
- | ^^^^^^^^^^^^^ attempt to divide with overflow
-
-error: attempt to divide with overflow
- --> $DIR/issue-8460-const.rs:19:36
- |
-LL | assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err());
- | ^^^^^^^^^^^^^
-
-error: this expression will panic at runtime
- --> $DIR/issue-8460-const.rs:19:36
- |
-LL | assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err());
- | ^^^^^^^^^^^^^ attempt to divide with overflow
-
-error: attempt to divide with overflow
- --> $DIR/issue-8460-const.rs:22:36
- |
-LL | assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err());
- | ^^^^^^^^^^^^^
-
-error: this expression will panic at runtime
- --> $DIR/issue-8460-const.rs:22:36
- |
-LL | assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err());
- | ^^^^^^^^^^^^^ attempt to divide with overflow
-
-error: attempt to divide with overflow
- --> $DIR/issue-8460-const.rs:25:36
- |
-LL | assert!(thread::spawn(move|| { i128::MIN / -1; }).join().is_err());
- | ^^^^^^^^^^^^^^
-
-error: this expression will panic at runtime
- --> $DIR/issue-8460-const.rs:25:36
- |
-LL | assert!(thread::spawn(move|| { i128::MIN / -1; }).join().is_err());
- | ^^^^^^^^^^^^^^ attempt to divide with overflow
-
-error: attempt to divide by zero
- --> $DIR/issue-8460-const.rs:28:36
- |
-LL | assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err());
- | ^^^^^^^^^^
-
-error: attempt to divide by zero
- --> $DIR/issue-8460-const.rs:30:36
- |
-LL | assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err());
- | ^^^^^^^
-
-error: attempt to divide by zero
- --> $DIR/issue-8460-const.rs:32:36
- |
-LL | assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err());
- | ^^^^^^^^
-
-error: attempt to divide by zero
- --> $DIR/issue-8460-const.rs:34:36
- |
-LL | assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err());
- | ^^^^^^^^
-
-error: attempt to divide by zero
- --> $DIR/issue-8460-const.rs:36:36
- |
-LL | assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err());
- | ^^^^^^^^
-
-error: attempt to divide by zero
- --> $DIR/issue-8460-const.rs:38:36
- |
-LL | assert!(thread::spawn(move|| { 1i128 / 0; }).join().is_err());
- | ^^^^^^^^^
-
-error: attempt to calculate the remainder with overflow
- --> $DIR/issue-8460-const.rs:40:36
- |
-LL | assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err());
- | ^^^^^^^^^^^^^^^
-
-error: this expression will panic at runtime
- --> $DIR/issue-8460-const.rs:40:36
- |
-LL | assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err());
- | ^^^^^^^^^^^^^^^ attempt to calculate the remainder with overflow
-
-error: attempt to calculate the remainder with overflow
- --> $DIR/issue-8460-const.rs:43:36
- |
-LL | assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err());
- | ^^^^^^^^^^^^
-
-error: this expression will panic at runtime
- --> $DIR/issue-8460-const.rs:43:36
- |
-LL | assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err());
- | ^^^^^^^^^^^^ attempt to calculate the remainder with overflow
-
-error: attempt to calculate the remainder with overflow
- --> $DIR/issue-8460-const.rs:46:36
- |
-LL | assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err());
- | ^^^^^^^^^^^^^
-
-error: this expression will panic at runtime
- --> $DIR/issue-8460-const.rs:46:36
- |
-LL | assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err());
- | ^^^^^^^^^^^^^ attempt to calculate the remainder with overflow
-
-error: attempt to calculate the remainder with overflow
- --> $DIR/issue-8460-const.rs:49:36
- |
-LL | assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err());
- | ^^^^^^^^^^^^^
-
-error: this expression will panic at runtime
- --> $DIR/issue-8460-const.rs:49:36
- |
-LL | assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err());
- | ^^^^^^^^^^^^^ attempt to calculate the remainder with overflow
-
-error: attempt to calculate the remainder with overflow
- --> $DIR/issue-8460-const.rs:52:36
- |
-LL | assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err());
- | ^^^^^^^^^^^^^
-
-error: this expression will panic at runtime
- --> $DIR/issue-8460-const.rs:52:36
- |
-LL | assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err());
- | ^^^^^^^^^^^^^ attempt to calculate the remainder with overflow
-
-error: attempt to calculate the remainder with overflow
- --> $DIR/issue-8460-const.rs:55:36
- |
-LL | assert!(thread::spawn(move|| { i128::MIN % -1; }).join().is_err());
- | ^^^^^^^^^^^^^^
-
-error: this expression will panic at runtime
- --> $DIR/issue-8460-const.rs:55:36
- |
-LL | assert!(thread::spawn(move|| { i128::MIN % -1; }).join().is_err());
- | ^^^^^^^^^^^^^^ attempt to calculate the remainder with overflow
-
-error: attempt to calculate the remainder with a divisor of zero
- --> $DIR/issue-8460-const.rs:58:36
- |
-LL | assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err());
- | ^^^^^^^^^^
-
-error: attempt to calculate the remainder with a divisor of zero
- --> $DIR/issue-8460-const.rs:60:36
- |
-LL | assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err());
- | ^^^^^^^
-
-error: attempt to calculate the remainder with a divisor of zero
- --> $DIR/issue-8460-const.rs:62:36
- |
-LL | assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err());
- | ^^^^^^^^
-
-error: attempt to calculate the remainder with a divisor of zero
- --> $DIR/issue-8460-const.rs:64:36
- |
-LL | assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err());
- | ^^^^^^^^
-
-error: attempt to calculate the remainder with a divisor of zero
- --> $DIR/issue-8460-const.rs:66:36
- |
-LL | assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err());
- | ^^^^^^^^
-
-error: attempt to calculate the remainder with a divisor of zero
- --> $DIR/issue-8460-const.rs:68:36
- |
-LL | assert!(thread::spawn(move|| { 1i128 % 0; }).join().is_err());
- | ^^^^^^^^^
-
-error: aborting due to 36 previous errors
-
diff --git a/src/test/ui/issues/issue-8460-const2.rs b/src/test/ui/issues/issue-8460-const2.rs
deleted file mode 100644
index afea859..0000000
--- a/src/test/ui/issues/issue-8460-const2.rs
+++ /dev/null
@@ -1,58 +0,0 @@
-// build-fail
-// compile-flags: -C overflow-checks=on -O
-
-#![deny(const_err)]
-
-use std::{isize, i8, i16, i32, i64, i128};
-use std::thread;
-
-fn main() {
- assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err());
- //~^ ERROR attempt to divide with overflow
- assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err());
- //~^ ERROR attempt to divide with overflow
- assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err());
- //~^ ERROR attempt to divide with overflow
- assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err());
- //~^ ERROR attempt to divide with overflow
- assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err());
- //~^ ERROR attempt to divide with overflow
- assert!(thread::spawn(move|| { i128::MIN / -1; }).join().is_err());
- //~^ ERROR attempt to divide with overflow
- assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err());
- //~^ ERROR attempt to divide by zero
- assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err());
- //~^ ERROR attempt to divide by zero
- assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err());
- //~^ ERROR attempt to divide by zero
- assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err());
- //~^ ERROR attempt to divide by zero
- assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err());
- //~^ ERROR attempt to divide by zero
- assert!(thread::spawn(move|| { 1i128 / 0; }).join().is_err());
- //~^ ERROR attempt to divide by zero
- assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err());
- //~^ ERROR attempt to calculate the remainder with overflow
- assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err());
- //~^ ERROR attempt to calculate the remainder with overflow
- assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err());
- //~^ ERROR attempt to calculate the remainder with overflow
- assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err());
- //~^ ERROR attempt to calculate the remainder with overflow
- assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err());
- //~^ ERROR attempt to calculate the remainder with overflow
- assert!(thread::spawn(move|| { i128::MIN % -1; }).join().is_err());
- //~^ ERROR attempt to calculate the remainder with overflow
- assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err());
- //~^ ERROR attempt to calculate the remainder with a divisor of zero
- assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err());
- //~^ ERROR attempt to calculate the remainder with a divisor of zero
- assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err());
- //~^ ERROR attempt to calculate the remainder with a divisor of zero
- assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err());
- //~^ ERROR attempt to calculate the remainder with a divisor of zero
- assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err());
- //~^ ERROR attempt to calculate the remainder with a divisor of zero
- assert!(thread::spawn(move|| { 1i128 % 0; }).join().is_err());
- //~^ ERROR attempt to calculate the remainder with a divisor of zero
-}
diff --git a/src/test/ui/issues/issue-8460-const2.stderr b/src/test/ui/issues/issue-8460-const2.stderr
deleted file mode 100644
index e25d560..0000000
--- a/src/test/ui/issues/issue-8460-const2.stderr
+++ /dev/null
@@ -1,152 +0,0 @@
-error: attempt to divide with overflow
- --> $DIR/issue-8460-const2.rs:10:36
- |
-LL | assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err());
- | ^^^^^^^^^^^^^^^
- |
-note: the lint level is defined here
- --> $DIR/issue-8460-const2.rs:4:9
- |
-LL | #![deny(const_err)]
- | ^^^^^^^^^
-
-error: attempt to divide with overflow
- --> $DIR/issue-8460-const2.rs:12:36
- |
-LL | assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err());
- | ^^^^^^^^^^^^
-
-error: attempt to divide with overflow
- --> $DIR/issue-8460-const2.rs:14:36
- |
-LL | assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err());
- | ^^^^^^^^^^^^^
-
-error: attempt to divide with overflow
- --> $DIR/issue-8460-const2.rs:16:36
- |
-LL | assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err());
- | ^^^^^^^^^^^^^
-
-error: attempt to divide with overflow
- --> $DIR/issue-8460-const2.rs:18:36
- |
-LL | assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err());
- | ^^^^^^^^^^^^^
-
-error: attempt to divide with overflow
- --> $DIR/issue-8460-const2.rs:20:36
- |
-LL | assert!(thread::spawn(move|| { i128::MIN / -1; }).join().is_err());
- | ^^^^^^^^^^^^^^
-
-error: attempt to divide by zero
- --> $DIR/issue-8460-const2.rs:22:36
- |
-LL | assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err());
- | ^^^^^^^^^^
-
-error: attempt to divide by zero
- --> $DIR/issue-8460-const2.rs:24:36
- |
-LL | assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err());
- | ^^^^^^^
-
-error: attempt to divide by zero
- --> $DIR/issue-8460-const2.rs:26:36
- |
-LL | assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err());
- | ^^^^^^^^
-
-error: attempt to divide by zero
- --> $DIR/issue-8460-const2.rs:28:36
- |
-LL | assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err());
- | ^^^^^^^^
-
-error: attempt to divide by zero
- --> $DIR/issue-8460-const2.rs:30:36
- |
-LL | assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err());
- | ^^^^^^^^
-
-error: attempt to divide by zero
- --> $DIR/issue-8460-const2.rs:32:36
- |
-LL | assert!(thread::spawn(move|| { 1i128 / 0; }).join().is_err());
- | ^^^^^^^^^
-
-error: attempt to calculate the remainder with overflow
- --> $DIR/issue-8460-const2.rs:34:36
- |
-LL | assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err());
- | ^^^^^^^^^^^^^^^
-
-error: attempt to calculate the remainder with overflow
- --> $DIR/issue-8460-const2.rs:36:36
- |
-LL | assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err());
- | ^^^^^^^^^^^^
-
-error: attempt to calculate the remainder with overflow
- --> $DIR/issue-8460-const2.rs:38:36
- |
-LL | assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err());
- | ^^^^^^^^^^^^^
-
-error: attempt to calculate the remainder with overflow
- --> $DIR/issue-8460-const2.rs:40:36
- |
-LL | assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err());
- | ^^^^^^^^^^^^^
-
-error: attempt to calculate the remainder with overflow
- --> $DIR/issue-8460-const2.rs:42:36
- |
-LL | assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err());
- | ^^^^^^^^^^^^^
-
-error: attempt to calculate the remainder with overflow
- --> $DIR/issue-8460-const2.rs:44:36
- |
-LL | assert!(thread::spawn(move|| { i128::MIN % -1; }).join().is_err());
- | ^^^^^^^^^^^^^^
-
-error: attempt to calculate the remainder with a divisor of zero
- --> $DIR/issue-8460-const2.rs:46:36
- |
-LL | assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err());
- | ^^^^^^^^^^
-
-error: attempt to calculate the remainder with a divisor of zero
- --> $DIR/issue-8460-const2.rs:48:36
- |
-LL | assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err());
- | ^^^^^^^
-
-error: attempt to calculate the remainder with a divisor of zero
- --> $DIR/issue-8460-const2.rs:50:36
- |
-LL | assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err());
- | ^^^^^^^^
-
-error: attempt to calculate the remainder with a divisor of zero
- --> $DIR/issue-8460-const2.rs:52:36
- |
-LL | assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err());
- | ^^^^^^^^
-
-error: attempt to calculate the remainder with a divisor of zero
- --> $DIR/issue-8460-const2.rs:54:36
- |
-LL | assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err());
- | ^^^^^^^^
-
-error: attempt to calculate the remainder with a divisor of zero
- --> $DIR/issue-8460-const2.rs:56:36
- |
-LL | assert!(thread::spawn(move|| { 1i128 % 0; }).join().is_err());
- | ^^^^^^^^^
-
-error: aborting due to 24 previous errors
-
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 4e50064..e60c461 100644
--- a/src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr
+++ b/src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr
@@ -2,7 +2,7 @@
--> $DIR/lifetime-doesnt-live-long-enough.rs:19:5
|
LL | struct Foo<T> {
- | - help: consider adding an explicit lifetime bound `T: 'static`...
+ | - help: consider adding an explicit lifetime bound...: `T: 'static`
LL | foo: &'static T
| ^^^^^^^^^^^^^^^
|
@@ -16,7 +16,7 @@
--> $DIR/lifetime-doesnt-live-long-enough.rs:24:19
|
LL | trait X<K>: Sized {
- | - help: consider adding an explicit lifetime bound `K: 'a`...
+ | - help: consider adding an explicit lifetime bound...: `K: 'a`
LL | fn foo<'a, L: X<&'a Nested<K>>>();
| ^^^^^^^^^^^^^^^^
|
@@ -45,7 +45,7 @@
LL | fn baz<'a, L, M: X<&'a Nested<L>>>() {
| - ^^^^^^^^^^^^^^^^
| |
- | 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<L>` does not outlive the data it points at
--> $DIR/lifetime-doesnt-live-long-enough.rs:32:22
@@ -57,7 +57,7 @@
--> $DIR/lifetime-doesnt-live-long-enough.rs:41:33
|
LL | impl<K> Nested<K> {
- | - help: consider adding an explicit lifetime bound `K: 'a`...
+ | - help: consider adding an explicit lifetime bound...: `K: 'a`
LL | fn generic_in_parent<'a, L: X<&'a Nested<K>>>() {
| ^^^^^^^^^^^^^^^^
|
@@ -71,7 +71,7 @@
--> $DIR/lifetime-doesnt-live-long-enough.rs:44:36
|
LL | fn generic_in_child<'a, 'b, L: X<&'a Nested<M>>, 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<M>` does not outlive the data it points at
--> $DIR/lifetime-doesnt-live-long-enough.rs:44:36
diff --git a/src/test/ui/lint/lint-exceeding-bitshifts.noopt.stderr b/src/test/ui/lint/lint-exceeding-bitshifts.noopt.stderr
new file mode 100644
index 0000000..ce9b02b
--- /dev/null
+++ b/src/test/ui/lint/lint-exceeding-bitshifts.noopt.stderr
@@ -0,0 +1,146 @@
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:22:13
+ |
+LL | let _ = x << 42;
+ | ^^^^^^^ attempt to shift left with overflow
+ |
+note: the lint level is defined here
+ --> $DIR/lint-exceeding-bitshifts.rs:9:9
+ |
+LL | #![deny(arithmetic_overflow, const_err)]
+ | ^^^^^^^^^^^^^^^^^^^
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:27:15
+ |
+LL | let n = 1u8 << 8;
+ | ^^^^^^^^ attempt to shift left with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:29:15
+ |
+LL | let n = 1u16 << 16;
+ | ^^^^^^^^^^ attempt to shift left with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:31:15
+ |
+LL | let n = 1u32 << 32;
+ | ^^^^^^^^^^ attempt to shift left with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:33:15
+ |
+LL | let n = 1u64 << 64;
+ | ^^^^^^^^^^ attempt to shift left with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:35:15
+ |
+LL | let n = 1i8 << 8;
+ | ^^^^^^^^ attempt to shift left with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:37:15
+ |
+LL | let n = 1i16 << 16;
+ | ^^^^^^^^^^ attempt to shift left with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:39:15
+ |
+LL | let n = 1i32 << 32;
+ | ^^^^^^^^^^ attempt to shift left with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:41:15
+ |
+LL | let n = 1i64 << 64;
+ | ^^^^^^^^^^ attempt to shift left with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:44:15
+ |
+LL | let n = 1u8 >> 8;
+ | ^^^^^^^^ attempt to shift right with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:46:15
+ |
+LL | let n = 1u16 >> 16;
+ | ^^^^^^^^^^ attempt to shift right with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:48:15
+ |
+LL | let n = 1u32 >> 32;
+ | ^^^^^^^^^^ attempt to shift right with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:50:15
+ |
+LL | let n = 1u64 >> 64;
+ | ^^^^^^^^^^ attempt to shift right with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:52:15
+ |
+LL | let n = 1i8 >> 8;
+ | ^^^^^^^^ attempt to shift right with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:54:15
+ |
+LL | let n = 1i16 >> 16;
+ | ^^^^^^^^^^ attempt to shift right with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:56:15
+ |
+LL | let n = 1i32 >> 32;
+ | ^^^^^^^^^^ attempt to shift right with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:58:15
+ |
+LL | let n = 1i64 >> 64;
+ | ^^^^^^^^^^ attempt to shift right with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:62:15
+ |
+LL | let n = n << 8;
+ | ^^^^^^ attempt to shift left with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:64:15
+ |
+LL | let n = 1u8 << -8;
+ | ^^^^^^^^^ attempt to shift left with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:69:15
+ |
+LL | let n = 1u8 << (4+4);
+ | ^^^^^^^^^^^^ attempt to shift left with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:71:15
+ |
+LL | let n = 1i64 >> [64][0];
+ | ^^^^^^^^^^^^^^^ attempt to shift right with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:77:15
+ |
+LL | let n = 1_isize << BITS;
+ | ^^^^^^^^^^^^^^^ attempt to shift left with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:78:15
+ |
+LL | let n = 1_usize << BITS;
+ | ^^^^^^^^^^^^^^^ attempt to shift left with overflow
+
+error: aborting due to 23 previous errors
+
diff --git a/src/test/ui/lint/lint-exceeding-bitshifts.opt.stderr b/src/test/ui/lint/lint-exceeding-bitshifts.opt.stderr
new file mode 100644
index 0000000..ce9b02b
--- /dev/null
+++ b/src/test/ui/lint/lint-exceeding-bitshifts.opt.stderr
@@ -0,0 +1,146 @@
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:22:13
+ |
+LL | let _ = x << 42;
+ | ^^^^^^^ attempt to shift left with overflow
+ |
+note: the lint level is defined here
+ --> $DIR/lint-exceeding-bitshifts.rs:9:9
+ |
+LL | #![deny(arithmetic_overflow, const_err)]
+ | ^^^^^^^^^^^^^^^^^^^
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:27:15
+ |
+LL | let n = 1u8 << 8;
+ | ^^^^^^^^ attempt to shift left with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:29:15
+ |
+LL | let n = 1u16 << 16;
+ | ^^^^^^^^^^ attempt to shift left with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:31:15
+ |
+LL | let n = 1u32 << 32;
+ | ^^^^^^^^^^ attempt to shift left with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:33:15
+ |
+LL | let n = 1u64 << 64;
+ | ^^^^^^^^^^ attempt to shift left with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:35:15
+ |
+LL | let n = 1i8 << 8;
+ | ^^^^^^^^ attempt to shift left with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:37:15
+ |
+LL | let n = 1i16 << 16;
+ | ^^^^^^^^^^ attempt to shift left with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:39:15
+ |
+LL | let n = 1i32 << 32;
+ | ^^^^^^^^^^ attempt to shift left with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:41:15
+ |
+LL | let n = 1i64 << 64;
+ | ^^^^^^^^^^ attempt to shift left with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:44:15
+ |
+LL | let n = 1u8 >> 8;
+ | ^^^^^^^^ attempt to shift right with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:46:15
+ |
+LL | let n = 1u16 >> 16;
+ | ^^^^^^^^^^ attempt to shift right with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:48:15
+ |
+LL | let n = 1u32 >> 32;
+ | ^^^^^^^^^^ attempt to shift right with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:50:15
+ |
+LL | let n = 1u64 >> 64;
+ | ^^^^^^^^^^ attempt to shift right with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:52:15
+ |
+LL | let n = 1i8 >> 8;
+ | ^^^^^^^^ attempt to shift right with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:54:15
+ |
+LL | let n = 1i16 >> 16;
+ | ^^^^^^^^^^ attempt to shift right with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:56:15
+ |
+LL | let n = 1i32 >> 32;
+ | ^^^^^^^^^^ attempt to shift right with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:58:15
+ |
+LL | let n = 1i64 >> 64;
+ | ^^^^^^^^^^ attempt to shift right with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:62:15
+ |
+LL | let n = n << 8;
+ | ^^^^^^ attempt to shift left with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:64:15
+ |
+LL | let n = 1u8 << -8;
+ | ^^^^^^^^^ attempt to shift left with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:69:15
+ |
+LL | let n = 1u8 << (4+4);
+ | ^^^^^^^^^^^^ attempt to shift left with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:71:15
+ |
+LL | let n = 1i64 >> [64][0];
+ | ^^^^^^^^^^^^^^^ attempt to shift right with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:77:15
+ |
+LL | let n = 1_isize << BITS;
+ | ^^^^^^^^^^^^^^^ attempt to shift left with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:78:15
+ |
+LL | let n = 1_usize << BITS;
+ | ^^^^^^^^^^^^^^^ attempt to shift left with overflow
+
+error: aborting due to 23 previous errors
+
diff --git a/src/test/ui/lint/lint-exceeding-bitshifts.opt_with_overflow_checks.stderr b/src/test/ui/lint/lint-exceeding-bitshifts.opt_with_overflow_checks.stderr
new file mode 100644
index 0000000..ce9b02b
--- /dev/null
+++ b/src/test/ui/lint/lint-exceeding-bitshifts.opt_with_overflow_checks.stderr
@@ -0,0 +1,146 @@
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:22:13
+ |
+LL | let _ = x << 42;
+ | ^^^^^^^ attempt to shift left with overflow
+ |
+note: the lint level is defined here
+ --> $DIR/lint-exceeding-bitshifts.rs:9:9
+ |
+LL | #![deny(arithmetic_overflow, const_err)]
+ | ^^^^^^^^^^^^^^^^^^^
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:27:15
+ |
+LL | let n = 1u8 << 8;
+ | ^^^^^^^^ attempt to shift left with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:29:15
+ |
+LL | let n = 1u16 << 16;
+ | ^^^^^^^^^^ attempt to shift left with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:31:15
+ |
+LL | let n = 1u32 << 32;
+ | ^^^^^^^^^^ attempt to shift left with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:33:15
+ |
+LL | let n = 1u64 << 64;
+ | ^^^^^^^^^^ attempt to shift left with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:35:15
+ |
+LL | let n = 1i8 << 8;
+ | ^^^^^^^^ attempt to shift left with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:37:15
+ |
+LL | let n = 1i16 << 16;
+ | ^^^^^^^^^^ attempt to shift left with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:39:15
+ |
+LL | let n = 1i32 << 32;
+ | ^^^^^^^^^^ attempt to shift left with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:41:15
+ |
+LL | let n = 1i64 << 64;
+ | ^^^^^^^^^^ attempt to shift left with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:44:15
+ |
+LL | let n = 1u8 >> 8;
+ | ^^^^^^^^ attempt to shift right with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:46:15
+ |
+LL | let n = 1u16 >> 16;
+ | ^^^^^^^^^^ attempt to shift right with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:48:15
+ |
+LL | let n = 1u32 >> 32;
+ | ^^^^^^^^^^ attempt to shift right with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:50:15
+ |
+LL | let n = 1u64 >> 64;
+ | ^^^^^^^^^^ attempt to shift right with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:52:15
+ |
+LL | let n = 1i8 >> 8;
+ | ^^^^^^^^ attempt to shift right with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:54:15
+ |
+LL | let n = 1i16 >> 16;
+ | ^^^^^^^^^^ attempt to shift right with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:56:15
+ |
+LL | let n = 1i32 >> 32;
+ | ^^^^^^^^^^ attempt to shift right with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:58:15
+ |
+LL | let n = 1i64 >> 64;
+ | ^^^^^^^^^^ attempt to shift right with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:62:15
+ |
+LL | let n = n << 8;
+ | ^^^^^^ attempt to shift left with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:64:15
+ |
+LL | let n = 1u8 << -8;
+ | ^^^^^^^^^ attempt to shift left with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:69:15
+ |
+LL | let n = 1u8 << (4+4);
+ | ^^^^^^^^^^^^ attempt to shift left with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:71:15
+ |
+LL | let n = 1i64 >> [64][0];
+ | ^^^^^^^^^^^^^^^ attempt to shift right with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:77:15
+ |
+LL | let n = 1_isize << BITS;
+ | ^^^^^^^^^^^^^^^ attempt to shift left with overflow
+
+error: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:78:15
+ |
+LL | let n = 1_usize << BITS;
+ | ^^^^^^^^^^^^^^^ attempt to shift left with overflow
+
+error: aborting due to 23 previous errors
+
diff --git a/src/test/ui/lint/lint-exceeding-bitshifts.rs b/src/test/ui/lint/lint-exceeding-bitshifts.rs
index 121e5b7..7deee53 100644
--- a/src/test/ui/lint/lint-exceeding-bitshifts.rs
+++ b/src/test/ui/lint/lint-exceeding-bitshifts.rs
@@ -1,50 +1,79 @@
-// build-fail
-// compile-flags: -O
+// revisions: noopt opt opt_with_overflow_checks
+//[noopt]compile-flags: -C opt-level=0
+//[opt]compile-flags: -O
+//[opt_with_overflow_checks]compile-flags: -C overflow-checks=on -O
-#![deny(exceeding_bitshifts, const_err)]
+// build-fail
+
+#![crate_type="lib"]
+#![deny(arithmetic_overflow, const_err)]
#![allow(unused_variables)]
#![allow(dead_code)]
-fn main() {
+pub trait Foo {
+ const N: i32;
+}
+
+impl<T: Foo> Foo for Vec<T> {
+ const N: i32 = T::N << 42; // FIXME this should warn
+}
+
+pub fn foo(x: i32) {
+ let _ = x << 42; //~ ERROR: arithmetic operation will overflow
+}
+
+pub fn main() {
let n = 1u8 << 7;
- let n = 1u8 << 8; //~ ERROR: attempt to shift left with overflow
+ let n = 1u8 << 8; //~ ERROR: arithmetic operation will overflow
let n = 1u16 << 15;
- let n = 1u16 << 16; //~ ERROR: attempt to shift left with overflow
+ let n = 1u16 << 16; //~ ERROR: arithmetic operation will overflow
let n = 1u32 << 31;
- let n = 1u32 << 32; //~ ERROR: attempt to shift left with overflow
+ let n = 1u32 << 32; //~ ERROR: arithmetic operation will overflow
let n = 1u64 << 63;
- let n = 1u64 << 64; //~ ERROR: attempt to shift left with overflow
+ let n = 1u64 << 64; //~ ERROR: arithmetic operation will overflow
let n = 1i8 << 7;
- let n = 1i8 << 8; //~ ERROR: attempt to shift left with overflow
+ let n = 1i8 << 8; //~ ERROR: arithmetic operation will overflow
let n = 1i16 << 15;
- let n = 1i16 << 16; //~ ERROR: attempt to shift left with overflow
+ let n = 1i16 << 16; //~ ERROR: arithmetic operation will overflow
let n = 1i32 << 31;
- let n = 1i32 << 32; //~ ERROR: attempt to shift left with overflow
+ let n = 1i32 << 32; //~ ERROR: arithmetic operation will overflow
let n = 1i64 << 63;
- let n = 1i64 << 64; //~ ERROR: attempt to shift left with overflow
+ let n = 1i64 << 64; //~ ERROR: arithmetic operation will overflow
let n = 1u8 >> 7;
- let n = 1u8 >> 8; //~ ERROR: attempt to shift right with overflow
+ let n = 1u8 >> 8; //~ ERROR: arithmetic operation will overflow
let n = 1u16 >> 15;
- let n = 1u16 >> 16; //~ ERROR: attempt to shift right with overflow
+ let n = 1u16 >> 16; //~ ERROR: arithmetic operation will overflow
let n = 1u32 >> 31;
- let n = 1u32 >> 32; //~ ERROR: attempt to shift right with overflow
+ let n = 1u32 >> 32; //~ ERROR: arithmetic operation will overflow
let n = 1u64 >> 63;
- let n = 1u64 >> 64; //~ ERROR: attempt to shift right with overflow
+ let n = 1u64 >> 64; //~ ERROR: arithmetic operation will overflow
let n = 1i8 >> 7;
- let n = 1i8 >> 8; //~ ERROR: attempt to shift right with overflow
+ let n = 1i8 >> 8; //~ ERROR: arithmetic operation will overflow
let n = 1i16 >> 15;
- let n = 1i16 >> 16; //~ ERROR: attempt to shift right with overflow
+ let n = 1i16 >> 16; //~ ERROR: arithmetic operation will overflow
let n = 1i32 >> 31;
- let n = 1i32 >> 32; //~ ERROR: attempt to shift right with overflow
+ let n = 1i32 >> 32; //~ ERROR: arithmetic operation will overflow
let n = 1i64 >> 63;
- let n = 1i64 >> 64; //~ ERROR: attempt to shift right with overflow
+ let n = 1i64 >> 64; //~ ERROR: arithmetic operation will overflow
let n = 1u8;
let n = n << 7;
- let n = n << 8; //~ ERROR: attempt to shift left with overflow
+ let n = n << 8; //~ ERROR: arithmetic operation will overflow
- let n = 1u8 << -8; //~ ERROR: attempt to shift left with overflow
+ let n = 1u8 << -8; //~ ERROR: arithmetic operation will overflow
let n = 1i8<<(1isize+-1);
+
+ let n = 1u8 << (4+3);
+ let n = 1u8 << (4+4); //~ ERROR: arithmetic operation will overflow
+ let n = 1i64 >> [63][0];
+ let n = 1i64 >> [64][0]; //~ ERROR: arithmetic operation will overflow
+
+ #[cfg(target_pointer_width = "32")]
+ const BITS: usize = 32;
+ #[cfg(target_pointer_width = "64")]
+ const BITS: usize = 64;
+ let n = 1_isize << BITS; //~ ERROR: arithmetic operation will overflow
+ let n = 1_usize << BITS; //~ ERROR: arithmetic operation will overflow
}
diff --git a/src/test/ui/lint/lint-exceeding-bitshifts.stderr b/src/test/ui/lint/lint-exceeding-bitshifts.stderr
deleted file mode 100644
index 6585772..0000000
--- a/src/test/ui/lint/lint-exceeding-bitshifts.stderr
+++ /dev/null
@@ -1,116 +0,0 @@
-error: attempt to shift left with overflow
- --> $DIR/lint-exceeding-bitshifts.rs:10:15
- |
-LL | let n = 1u8 << 8;
- | ^^^^^^^^
- |
-note: the lint level is defined here
- --> $DIR/lint-exceeding-bitshifts.rs:4:9
- |
-LL | #![deny(exceeding_bitshifts, const_err)]
- | ^^^^^^^^^^^^^^^^^^^
-
-error: attempt to shift left with overflow
- --> $DIR/lint-exceeding-bitshifts.rs:12:15
- |
-LL | let n = 1u16 << 16;
- | ^^^^^^^^^^
-
-error: attempt to shift left with overflow
- --> $DIR/lint-exceeding-bitshifts.rs:14:15
- |
-LL | let n = 1u32 << 32;
- | ^^^^^^^^^^
-
-error: attempt to shift left with overflow
- --> $DIR/lint-exceeding-bitshifts.rs:16:15
- |
-LL | let n = 1u64 << 64;
- | ^^^^^^^^^^
-
-error: attempt to shift left with overflow
- --> $DIR/lint-exceeding-bitshifts.rs:18:15
- |
-LL | let n = 1i8 << 8;
- | ^^^^^^^^
-
-error: attempt to shift left with overflow
- --> $DIR/lint-exceeding-bitshifts.rs:20:15
- |
-LL | let n = 1i16 << 16;
- | ^^^^^^^^^^
-
-error: attempt to shift left with overflow
- --> $DIR/lint-exceeding-bitshifts.rs:22:15
- |
-LL | let n = 1i32 << 32;
- | ^^^^^^^^^^
-
-error: attempt to shift left with overflow
- --> $DIR/lint-exceeding-bitshifts.rs:24:15
- |
-LL | let n = 1i64 << 64;
- | ^^^^^^^^^^
-
-error: attempt to shift right with overflow
- --> $DIR/lint-exceeding-bitshifts.rs:27:15
- |
-LL | let n = 1u8 >> 8;
- | ^^^^^^^^
-
-error: attempt to shift right with overflow
- --> $DIR/lint-exceeding-bitshifts.rs:29:15
- |
-LL | let n = 1u16 >> 16;
- | ^^^^^^^^^^
-
-error: attempt to shift right with overflow
- --> $DIR/lint-exceeding-bitshifts.rs:31:15
- |
-LL | let n = 1u32 >> 32;
- | ^^^^^^^^^^
-
-error: attempt to shift right with overflow
- --> $DIR/lint-exceeding-bitshifts.rs:33:15
- |
-LL | let n = 1u64 >> 64;
- | ^^^^^^^^^^
-
-error: attempt to shift right with overflow
- --> $DIR/lint-exceeding-bitshifts.rs:35:15
- |
-LL | let n = 1i8 >> 8;
- | ^^^^^^^^
-
-error: attempt to shift right with overflow
- --> $DIR/lint-exceeding-bitshifts.rs:37:15
- |
-LL | let n = 1i16 >> 16;
- | ^^^^^^^^^^
-
-error: attempt to shift right with overflow
- --> $DIR/lint-exceeding-bitshifts.rs:39:15
- |
-LL | let n = 1i32 >> 32;
- | ^^^^^^^^^^
-
-error: attempt to shift right with overflow
- --> $DIR/lint-exceeding-bitshifts.rs:41:15
- |
-LL | let n = 1i64 >> 64;
- | ^^^^^^^^^^
-
-error: attempt to shift left with overflow
- --> $DIR/lint-exceeding-bitshifts.rs:45:15
- |
-LL | let n = n << 8;
- | ^^^^^^
-
-error: attempt to shift left with overflow
- --> $DIR/lint-exceeding-bitshifts.rs:47:15
- |
-LL | let n = 1u8 << -8;
- | ^^^^^^^^^
-
-error: aborting due to 18 previous errors
-
diff --git a/src/test/ui/lint/lint-exceeding-bitshifts2.rs b/src/test/ui/lint/lint-exceeding-bitshifts2.rs
deleted file mode 100644
index 2a7cbc1..0000000
--- a/src/test/ui/lint/lint-exceeding-bitshifts2.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-// build-fail
-// compile-flags: -O
-
-#![deny(exceeding_bitshifts, const_err)]
-#![allow(unused_variables)]
-#![allow(dead_code)]
-
-fn main() {
- let n = 1u8 << (4+3);
- let n = 1u8 << (4+4); //~ ERROR: attempt to shift left with overflow
- let n = 1i64 >> [63][0];
- let n = 1i64 >> [64][0]; //~ ERROR: attempt to shift right with overflow
-
- #[cfg(target_pointer_width = "32")]
- const BITS: usize = 32;
- #[cfg(target_pointer_width = "64")]
- const BITS: usize = 64;
- let n = 1_isize << BITS; //~ ERROR: attempt to shift left with overflow
- let n = 1_usize << BITS; //~ ERROR: attempt to shift left with overflow
-}
diff --git a/src/test/ui/lint/lint-exceeding-bitshifts2.stderr b/src/test/ui/lint/lint-exceeding-bitshifts2.stderr
deleted file mode 100644
index ac9f3b1..0000000
--- a/src/test/ui/lint/lint-exceeding-bitshifts2.stderr
+++ /dev/null
@@ -1,32 +0,0 @@
-error: attempt to shift left with overflow
- --> $DIR/lint-exceeding-bitshifts2.rs:10:15
- |
-LL | let n = 1u8 << (4+4);
- | ^^^^^^^^^^^^
- |
-note: the lint level is defined here
- --> $DIR/lint-exceeding-bitshifts2.rs:4:9
- |
-LL | #![deny(exceeding_bitshifts, const_err)]
- | ^^^^^^^^^^^^^^^^^^^
-
-error: attempt to shift right with overflow
- --> $DIR/lint-exceeding-bitshifts2.rs:12:15
- |
-LL | let n = 1i64 >> [64][0];
- | ^^^^^^^^^^^^^^^
-
-error: attempt to shift left with overflow
- --> $DIR/lint-exceeding-bitshifts2.rs:18:15
- |
-LL | let n = 1_isize << BITS;
- | ^^^^^^^^^^^^^^^
-
-error: attempt to shift left with overflow
- --> $DIR/lint-exceeding-bitshifts2.rs:19:15
- |
-LL | let n = 1_usize << BITS;
- | ^^^^^^^^^^^^^^^
-
-error: aborting due to 4 previous errors
-
diff --git a/src/test/ui/methods/method-call-err-msg.rs b/src/test/ui/methods/method-call-err-msg.rs
index 5ff4b41..9bfacc7 100644
--- a/src/test/ui/methods/method-call-err-msg.rs
+++ b/src/test/ui/methods/method-call-err-msg.rs
@@ -5,16 +5,18 @@
fn zero(self) -> Foo { self }
fn one(self, _: isize) -> Foo { self }
fn two(self, _: isize, _: isize) -> Foo { self }
+ fn three<T>(self, _: T, _: T, _: T) -> Foo { self }
}
fn main() {
let x = Foo;
- x.zero(0) //~ ERROR this function takes 0 parameters but 1 parameter was supplied
- .one() //~ ERROR this function takes 1 parameter but 0 parameters were supplied
- .two(0); //~ ERROR this function takes 2 parameters but 1 parameter was supplied
+ x.zero(0) //~ ERROR this function takes 0 arguments but 1 argument was supplied
+ .one() //~ ERROR this function takes 1 argument but 0 arguments were supplied
+ .two(0); //~ ERROR this function takes 2 arguments but 1 argument was supplied
let y = Foo;
y.zero()
.take() //~ ERROR no method named `take` found
.one(0);
+ y.three::<usize>(); //~ ERROR this function takes 3 arguments but 0 arguments were supplied
}
diff --git a/src/test/ui/methods/method-call-err-msg.stderr b/src/test/ui/methods/method-call-err-msg.stderr
index 7efdd91..ab1ef5b 100644
--- a/src/test/ui/methods/method-call-err-msg.stderr
+++ b/src/test/ui/methods/method-call-err-msg.stderr
@@ -1,32 +1,38 @@
-error[E0061]: this function takes 0 parameters but 1 parameter was supplied
- --> $DIR/method-call-err-msg.rs:12:7
+error[E0061]: this function takes 0 arguments but 1 argument was supplied
+ --> $DIR/method-call-err-msg.rs:13:7
|
LL | fn zero(self) -> Foo { self }
| -------------------- defined here
...
LL | x.zero(0)
- | ^^^^ expected 0 parameters
+ | ^^^^ - supplied 1 argument
+ | |
+ | expected 0 arguments
-error[E0061]: this function takes 1 parameter but 0 parameters were supplied
- --> $DIR/method-call-err-msg.rs:13:7
+error[E0061]: this function takes 1 argument but 0 arguments were supplied
+ --> $DIR/method-call-err-msg.rs:14:7
|
LL | fn one(self, _: isize) -> Foo { self }
| ----------------------------- defined here
...
LL | .one()
- | ^^^ expected 1 parameter
+ | ^^^- supplied 0 arguments
+ | |
+ | expected 1 argument
-error[E0061]: this function takes 2 parameters but 1 parameter was supplied
- --> $DIR/method-call-err-msg.rs:14:7
+error[E0061]: this function takes 2 arguments but 1 argument was supplied
+ --> $DIR/method-call-err-msg.rs:15:7
|
LL | fn two(self, _: isize, _: isize) -> Foo { self }
| --------------------------------------- defined here
...
LL | .two(0);
- | ^^^ expected 2 parameters
+ | ^^^ - supplied 1 argument
+ | |
+ | expected 2 arguments
error[E0599]: no method named `take` found for struct `Foo` in the current scope
- --> $DIR/method-call-err-msg.rs:18:7
+ --> $DIR/method-call-err-msg.rs:19:7
|
LL | pub struct Foo;
| --------------- method `take` not found for this
@@ -41,7 +47,18 @@
candidate #1: `std::io::Read`
candidate #2: `std::iter::Iterator`
-error: aborting due to 4 previous errors
+error[E0061]: this function takes 3 arguments but 0 arguments were supplied
+ --> $DIR/method-call-err-msg.rs:21:7
+ |
+LL | fn three<T>(self, _: T, _: T, _: T) -> Foo { self }
+ | ------------------------------------------ defined here
+...
+LL | y.three::<usize>();
+ | ^^^^^--------- supplied 0 arguments
+ | |
+ | expected 3 arguments
+
+error: aborting due to 5 previous errors
Some errors have detailed explanations: E0061, E0599.
For more information about an error, try `rustc --explain E0061`.
diff --git a/src/test/ui/mismatched_types/overloaded-calls-bad.rs b/src/test/ui/mismatched_types/overloaded-calls-bad.rs
index 73e74a9..902a6ec 100644
--- a/src/test/ui/mismatched_types/overloaded-calls-bad.rs
+++ b/src/test/ui/mismatched_types/overloaded-calls-bad.rs
@@ -27,7 +27,7 @@
};
let ans = s("what"); //~ ERROR mismatched types
let ans = s();
- //~^ ERROR this function takes 1 parameter but 0 parameters were supplied
+ //~^ ERROR this function takes 1 argument but 0 arguments were supplied
let ans = s("burma", "shave");
- //~^ ERROR this function takes 1 parameter but 2 parameters were supplied
+ //~^ ERROR this function takes 1 argument but 2 arguments were supplied
}
diff --git a/src/test/ui/mismatched_types/overloaded-calls-bad.stderr b/src/test/ui/mismatched_types/overloaded-calls-bad.stderr
index 5a5dd05..706e255 100644
--- a/src/test/ui/mismatched_types/overloaded-calls-bad.stderr
+++ b/src/test/ui/mismatched_types/overloaded-calls-bad.stderr
@@ -4,17 +4,21 @@
LL | let ans = s("what");
| ^^^^^^ expected `isize`, found `&str`
-error[E0057]: this function takes 1 parameter but 0 parameters were supplied
+error[E0057]: this function takes 1 argument but 0 arguments were supplied
--> $DIR/overloaded-calls-bad.rs:29:15
|
LL | let ans = s();
- | ^^^ expected 1 parameter
+ | ^-- supplied 0 arguments
+ | |
+ | expected 1 argument
-error[E0057]: this function takes 1 parameter but 2 parameters were supplied
+error[E0057]: this function takes 1 argument but 2 arguments were supplied
--> $DIR/overloaded-calls-bad.rs:31:15
|
LL | let ans = s("burma", "shave");
- | ^^^^^^^^^^^^^^^^^^^ expected 1 parameter
+ | ^ ------- ------- supplied 2 arguments
+ | |
+ | expected 1 argument
error: aborting due to 3 previous errors
diff --git a/src/test/ui/nll/do-not-ignore-lifetime-bounds-in-copy-proj.rs b/src/test/ui/nll/do-not-ignore-lifetime-bounds-in-copy-proj.rs
new file mode 100644
index 0000000..96c8719
--- /dev/null
+++ b/src/test/ui/nll/do-not-ignore-lifetime-bounds-in-copy-proj.rs
@@ -0,0 +1,12 @@
+// Test that the 'static bound from the Copy impl is respected. Regression test for #29149.
+
+#[derive(Clone)]
+struct Foo<'a>(&'a u32);
+impl Copy for Foo<'static> {}
+
+fn main() {
+ let s = 2;
+ let a = (Foo(&s),); //~ ERROR `s` does not live long enough [E0597]
+ drop(a.0);
+ drop(a.0);
+}
diff --git a/src/test/ui/nll/do-not-ignore-lifetime-bounds-in-copy-proj.stderr b/src/test/ui/nll/do-not-ignore-lifetime-bounds-in-copy-proj.stderr
new file mode 100644
index 0000000..65be3b3
--- /dev/null
+++ b/src/test/ui/nll/do-not-ignore-lifetime-bounds-in-copy-proj.stderr
@@ -0,0 +1,14 @@
+error[E0597]: `s` does not live long enough
+ --> $DIR/do-not-ignore-lifetime-bounds-in-copy-proj.rs:9:18
+ |
+LL | let a = (Foo(&s),);
+ | ^^ borrowed value does not live long enough
+LL | drop(a.0);
+ | --- copying this value requires that `s` is borrowed for `'static`
+LL | drop(a.0);
+LL | }
+ | - `s` dropped here while still borrowed
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/nll/issue-69114-static-mut-ty.rs b/src/test/ui/nll/issue-69114-static-mut-ty.rs
new file mode 100644
index 0000000..ce37da0
--- /dev/null
+++ b/src/test/ui/nll/issue-69114-static-mut-ty.rs
@@ -0,0 +1,30 @@
+// Check that borrowck ensures that `static mut` items have the expected type.
+
+static FOO: u8 = 42;
+static mut BAR: &'static u8 = &FOO;
+static mut BAR_ELIDED: &u8 = &FOO;
+
+fn main() {
+ unsafe {
+ println!("{} {}", BAR, BAR_ELIDED);
+ set_bar();
+ set_bar_elided();
+ println!("{} {}", BAR, BAR_ELIDED);
+ }
+}
+
+fn set_bar() {
+ let n = 42;
+ unsafe {
+ BAR = &n;
+ //~^ ERROR does not live long enough
+ }
+}
+
+fn set_bar_elided() {
+ let n = 42;
+ unsafe {
+ BAR_ELIDED = &n;
+ //~^ ERROR does not live long enough
+ }
+}
diff --git a/src/test/ui/nll/issue-69114-static-mut-ty.stderr b/src/test/ui/nll/issue-69114-static-mut-ty.stderr
new file mode 100644
index 0000000..5e55cb5
--- /dev/null
+++ b/src/test/ui/nll/issue-69114-static-mut-ty.stderr
@@ -0,0 +1,27 @@
+error[E0597]: `n` does not live long enough
+ --> $DIR/issue-69114-static-mut-ty.rs:19:15
+ |
+LL | BAR = &n;
+ | ------^^
+ | | |
+ | | borrowed value does not live long enough
+ | assignment requires that `n` is borrowed for `'static`
+...
+LL | }
+ | - `n` dropped here while still borrowed
+
+error[E0597]: `n` does not live long enough
+ --> $DIR/issue-69114-static-mut-ty.rs:27:22
+ |
+LL | BAR_ELIDED = &n;
+ | -------------^^
+ | | |
+ | | borrowed value does not live long enough
+ | assignment requires that `n` is borrowed for `'static`
+...
+LL | }
+ | - `n` dropped here while still borrowed
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/nll/issue-69114-static-ty.rs b/src/test/ui/nll/issue-69114-static-ty.rs
new file mode 100644
index 0000000..3318433
--- /dev/null
+++ b/src/test/ui/nll/issue-69114-static-ty.rs
@@ -0,0 +1,9 @@
+// Check that borrowck ensures that `static` items have the expected type.
+
+static FOO: &'static (dyn Fn(&'static u8) + Send + Sync) = &drop;
+
+fn main() {
+ let n = 42;
+ FOO(&n);
+ //~^ ERROR does not live long enough
+}
diff --git a/src/test/ui/nll/issue-69114-static-ty.stderr b/src/test/ui/nll/issue-69114-static-ty.stderr
new file mode 100644
index 0000000..0815e74
--- /dev/null
+++ b/src/test/ui/nll/issue-69114-static-ty.stderr
@@ -0,0 +1,15 @@
+error[E0597]: `n` does not live long enough
+ --> $DIR/issue-69114-static-ty.rs:7:9
+ |
+LL | FOO(&n);
+ | ----^^-
+ | | |
+ | | borrowed value does not live long enough
+ | argument requires that `n` is borrowed for `'static`
+LL |
+LL | }
+ | - `n` dropped here while still borrowed
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/not-enough-arguments.rs b/src/test/ui/not-enough-arguments.rs
index 309283e..631bb1d 100644
--- a/src/test/ui/not-enough-arguments.rs
+++ b/src/test/ui/not-enough-arguments.rs
@@ -8,5 +8,5 @@
fn main() {
foo(1, 2, 3);
- //~^ ERROR this function takes 4 parameters but 3
+ //~^ ERROR this function takes 4 arguments but 3
}
diff --git a/src/test/ui/not-enough-arguments.stderr b/src/test/ui/not-enough-arguments.stderr
index c1ee43e..f2b57f7 100644
--- a/src/test/ui/not-enough-arguments.stderr
+++ b/src/test/ui/not-enough-arguments.stderr
@@ -1,11 +1,13 @@
-error[E0061]: this function takes 4 parameters but 3 parameters were supplied
+error[E0061]: this function takes 4 arguments but 3 arguments were supplied
--> $DIR/not-enough-arguments.rs:10:3
|
LL | fn foo(a: isize, b: isize, c: isize, d:isize) {
| --------------------------------------------- defined here
...
LL | foo(1, 2, 3);
- | ^^^^^^^^^^^^ expected 4 parameters
+ | ^^^ - - - supplied 3 arguments
+ | |
+ | expected 4 arguments
error: aborting due to previous error
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 026747c..f2186b9 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
@@ -15,7 +15,7 @@
| | |
| | value borrowed here after move
| value moved into `_z` here
- | move occurs because `_z` has type `X` which does implement the `Copy` trait
+ | move occurs because `_z` has type `X` which does not implement the `Copy` trait
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
@@ -34,7 +34,7 @@
| | |
| | value borrowed here after move
| value moved into `_z` here
- | move occurs because `_z` has type `X` which does implement the `Copy` trait
+ | move occurs because `_z` 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:21:19
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 91fdfd4..54900e9 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
@@ -6,7 +6,7 @@
| | |
| | value borrowed here after move
| value moved into `a` here
- | move occurs because `a` has type `main::U` which does implement the `Copy` trait
+ | move occurs because `a` has type `main::U` which does not 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 ec86692..f819e67 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
@@ -6,7 +6,7 @@
| | |
| | value borrowed here after move
| value moved into `a` here
- | move occurs because `a` has type `main::U` which does implement the `Copy` trait
+ | move occurs because `a` has type `main::U` which does not implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:31:9
@@ -17,7 +17,7 @@
| | | value borrowed here after move
| | value borrowed here after move
| value moved into `a` here
- | move occurs because `a` has type `(main::U, main::U)` which does implement the `Copy` trait
+ | move occurs because `a` has type `(main::U, main::U)` which does not implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:31:14
@@ -27,7 +27,7 @@
| | |
| | value borrowed here after move
| value moved into `b` here
- | move occurs because `b` has type `main::U` which does implement the `Copy` trait
+ | move occurs because `b` has type `main::U` which does not implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:31:33
@@ -37,7 +37,7 @@
| | |
| | value borrowed here after move
| value moved into `d` here
- | move occurs because `d` has type `main::U` which does implement the `Copy` trait
+ | move occurs because `d` has type `main::U` which does not implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:38:9
@@ -48,7 +48,7 @@
| | | value borrowed here after move
| | value borrowed here after move
| value moved into `a` here
- | move occurs because `a` has type `[main::U; 2]` which does implement the `Copy` trait
+ | move occurs because `a` has type `[main::U; 2]` which does not implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:41:9
@@ -58,7 +58,7 @@
| | |
| | value borrowed here after move
| value moved into `a` here
- | move occurs because `a` has type `main::U` which does implement the `Copy` trait
+ | move occurs because `a` has type `main::U` which does not implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:44:9
@@ -69,7 +69,7 @@
| | | value borrowed here after move
| | value borrowed here after move
| value moved into `a` here
- | move occurs because `a` has type `(main::U, main::U)` which does implement the `Copy` trait
+ | move occurs because `a` has type `(main::U, main::U)` which does not implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:44:14
@@ -79,7 +79,7 @@
| | |
| | value borrowed here after move
| value moved into `b` here
- | move occurs because `b` has type `main::U` which does implement the `Copy` trait
+ | move occurs because `b` has type `main::U` which does not implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:44:33
@@ -89,7 +89,7 @@
| | |
| | value borrowed here after move
| value moved into `d` here
- | move occurs because `d` has type `main::U` which does implement the `Copy` trait
+ | move occurs because `d` has type `main::U` which does not implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:51:9
@@ -100,7 +100,7 @@
| | | value borrowed here after move
| | value borrowed here after move
| value moved into `a` here
- | move occurs because `a` has type `[main::U; 2]` which does implement the `Copy` trait
+ | move occurs because `a` has type `[main::U; 2]` which does not implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:56:9
@@ -110,7 +110,7 @@
| | |
| | value borrowed here after move
| value moved into `a` here
- | move occurs because `a` has type `std::option::Option<main::U>` which does implement the `Copy` trait
+ | move occurs because `a` has type `std::option::Option<main::U>` which does not implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:61:9
@@ -121,7 +121,7 @@
| | | value borrowed here after move
| | value borrowed here after move
| value moved into `a` here
- | move occurs because `a` has type `std::option::Option<(main::U, main::U)>` which does implement the `Copy` trait
+ | move occurs because `a` has type `std::option::Option<(main::U, main::U)>` which does not implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:61:19
@@ -131,7 +131,7 @@
| | |
| | value borrowed here after move
| value moved into `b` here
- | move occurs because `b` has type `main::U` which does implement the `Copy` trait
+ | move occurs because `b` has type `main::U` which does not implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:61:38
@@ -141,7 +141,7 @@
| | |
| | value borrowed here after move
| value moved into `d` here
- | move occurs because `d` has type `main::U` which does implement the `Copy` trait
+ | move occurs because `d` has type `main::U` which does not implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:71:9
@@ -152,7 +152,7 @@
| | | value borrowed here after move
| | value borrowed here after move
| value moved into `a` here
- | move occurs because `a` has type `std::option::Option<[main::U; 2]>` which does implement the `Copy` trait
+ | move occurs because `a` has type `std::option::Option<[main::U; 2]>` which does not implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:77:9
@@ -162,7 +162,7 @@
| | |
| | value borrowed here after move
| value moved into `a` here
- | move occurs because `a` has type `std::option::Option<main::U>` which does implement the `Copy` trait
+ | move occurs because `a` has type `std::option::Option<main::U>` which does not implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:83:9
@@ -173,7 +173,7 @@
| | | value borrowed here after move
| | value borrowed here after move
| value moved into `a` here
- | move occurs because `a` has type `std::option::Option<(main::U, main::U)>` which does implement the `Copy` trait
+ | move occurs because `a` has type `std::option::Option<(main::U, main::U)>` which does not implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:83:19
@@ -183,7 +183,7 @@
| | |
| | value borrowed here after move
| value moved into `b` here
- | move occurs because `b` has type `main::U` which does implement the `Copy` trait
+ | move occurs because `b` has type `main::U` which does not implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:83:38
@@ -193,7 +193,7 @@
| | |
| | value borrowed here after move
| value moved into `d` here
- | move occurs because `d` has type `main::U` which does implement the `Copy` trait
+ | move occurs because `d` has type `main::U` which does not implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:93:9
@@ -204,7 +204,7 @@
| | | value borrowed here after move
| | value borrowed here after move
| value moved into `a` here
- | move occurs because `a` has type `std::option::Option<[main::U; 2]>` which does implement the `Copy` trait
+ | move occurs because `a` has type `std::option::Option<[main::U; 2]>` which does not implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:14:11
@@ -214,7 +214,7 @@
| | |
| | value borrowed here after move
| value moved into `a` here
- | move occurs because `a` has type `main::U` which does implement the `Copy` trait
+ | move occurs because `a` has type `main::U` which does not implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:18:11
@@ -225,7 +225,7 @@
| | | value borrowed here after move
| | value borrowed here after move
| value moved into `a` here
- | move occurs because `a` has type `(main::U, main::U)` which does implement the `Copy` trait
+ | move occurs because `a` has type `(main::U, main::U)` which does not implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:18:20
@@ -235,7 +235,7 @@
| | |
| | value borrowed here after move
| value moved into `b` here
- | move occurs because `b` has type `main::U` which does implement the `Copy` trait
+ | move occurs because `b` has type `main::U` which does not implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:18:31
@@ -245,7 +245,7 @@
| | |
| | value borrowed here after move
| value moved into `d` here
- | move occurs because `d` has type `main::U` which does implement the `Copy` trait
+ | move occurs because `d` has type `main::U` which does not implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:25:11
@@ -256,7 +256,7 @@
| | | value borrowed here after move
| | value borrowed here after move
| value moved into `a` here
- | move occurs because `a` has type `[main::U; 2]` which does implement the `Copy` trait
+ | move occurs because `a` has type `[main::U; 2]` which does not implement the `Copy` trait
error[E0382]: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:31:22
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 4e96c6e..e74f227 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
@@ -96,7 +96,7 @@
| | | value borrowed here after move
| | value borrowed here after move
| value moved into `a` here
- | move occurs because `a` has type `(main::U, main::U)` which does implement the `Copy` trait
+ | move occurs because `a` has type `(main::U, main::U)` which does not implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-ref-mut-twice.rs:70:9
@@ -108,7 +108,7 @@
| | | value borrowed here after move
| | value borrowed here after move
| value moved into `a` here
- | move occurs because `a` has type `&mut (main::U, [main::U; 2])` which does implement the `Copy` trait
+ | move occurs because `a` has type `&mut (main::U, [main::U; 2])` which does not implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-ref-mut-twice.rs:74:9
@@ -118,7 +118,7 @@
| | |
| | value borrowed here after move
| value moved into `a` here
- | move occurs because `a` has type `&mut main::U` which does implement the `Copy` trait
+ | move occurs because `a` has type `&mut main::U` which does not implement the `Copy` trait
error: borrow of moved value
--> $DIR/borrowck-pat-ref-mut-twice.rs:77:9
@@ -129,7 +129,7 @@
| | | value borrowed here after move
| | value borrowed here after move
| value moved into `a` here
- | move occurs because `a` has type `&mut (main::U, main::U)` which does implement the `Copy` trait
+ | move occurs because `a` has type `&mut (main::U, main::U)` which does not implement the `Copy` trait
error: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:82:9
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 697a8b9..19e815a 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
@@ -33,7 +33,7 @@
| | |
| | value borrowed here after move
| value moved into `b` here
- | move occurs because `b` has type `main::NotCopy` which does implement the `Copy` trait
+ | move occurs because `b` has type `main::NotCopy` which does not implement the `Copy` trait
error: cannot move out of value because it is borrowed
--> $DIR/default-binding-modes-both-sides-independent.rs:44:9
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 7c530ce..1472700 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
@@ -2,7 +2,7 @@
--> $DIR/regions-close-object-into-object-5.rs:17:5
|
LL | fn f<'a, T, U>(v: Box<A<T>+'static>) -> Box<X+'static> {
- | - help: consider adding an explicit lifetime bound `T: 'static`...
+ | - help: consider adding an explicit lifetime bound...: `T: 'static`
LL | // oh dear!
LL | box B(&*v) as Box<X>
| ^^^^^^^^^^
@@ -17,7 +17,7 @@
--> $DIR/regions-close-object-into-object-5.rs:17:5
|
LL | fn f<'a, T, U>(v: Box<A<T>+'static>) -> Box<X+'static> {
- | - help: consider adding an explicit lifetime bound `T: 'static`...
+ | - help: consider adding an explicit lifetime bound...: `T: 'static`
LL | // oh dear!
LL | box B(&*v) as Box<X>
| ^^^^^^^^^^^^^^^^^^^^
@@ -32,7 +32,7 @@
--> $DIR/regions-close-object-into-object-5.rs:17:9
|
LL | fn f<'a, T, U>(v: Box<A<T>+'static>) -> Box<X+'static> {
- | - help: consider adding an explicit lifetime bound `T: 'static`...
+ | - help: consider adding an explicit lifetime bound...: `T: 'static`
LL | // oh dear!
LL | box B(&*v) as Box<X>
| ^
@@ -47,7 +47,7 @@
--> $DIR/regions-close-object-into-object-5.rs:17:9
|
LL | fn f<'a, T, U>(v: Box<A<T>+'static>) -> Box<X+'static> {
- | - help: consider adding an explicit lifetime bound `T: 'static`...
+ | - help: consider adding an explicit lifetime bound...: `T: 'static`
LL | // oh dear!
LL | box B(&*v) as Box<X>
| ^^^^^^
@@ -62,7 +62,7 @@
--> $DIR/regions-close-object-into-object-5.rs:17:11
|
LL | fn f<'a, T, U>(v: Box<A<T>+'static>) -> Box<X+'static> {
- | - help: consider adding an explicit lifetime bound `T: 'static`...
+ | - help: consider adding an explicit lifetime bound...: `T: 'static`
LL | // oh dear!
LL | box B(&*v) as Box<X>
| ^^^
@@ -77,7 +77,7 @@
--> $DIR/regions-close-object-into-object-5.rs:17:11
|
LL | fn f<'a, T, U>(v: Box<A<T>+'static>) -> Box<X+'static> {
- | - help: consider adding an explicit lifetime bound `T: 'static`...
+ | - help: consider adding an explicit lifetime bound...: `T: 'static`
LL | // oh dear!
LL | box B(&*v) as Box<X>
| ^^^
@@ -92,7 +92,7 @@
--> $DIR/regions-close-object-into-object-5.rs:17:11
|
LL | fn f<'a, T, U>(v: Box<A<T>+'static>) -> Box<X+'static> {
- | - help: consider adding an explicit lifetime bound `T: 'static`...
+ | - help: consider adding an explicit lifetime bound...: `T: 'static`
LL | // oh dear!
LL | box B(&*v) as Box<X>
| ^^^
diff --git a/src/test/ui/regions/regions-close-over-type-parameter-1.stderr b/src/test/ui/regions/regions-close-over-type-parameter-1.stderr
index 81534b7..ed9a604 100644
--- a/src/test/ui/regions/regions-close-over-type-parameter-1.stderr
+++ b/src/test/ui/regions/regions-close-over-type-parameter-1.stderr
@@ -2,7 +2,7 @@
--> $DIR/regions-close-over-type-parameter-1.rs:10:5
|
LL | fn make_object1<A:SomeTrait>(v: A) -> Box<dyn SomeTrait + 'static> {
- | -- help: consider adding an explicit lifetime bound `A: 'static`...
+ | -- help: consider adding an explicit lifetime bound...: `A: 'static +`
LL | box v as Box<dyn SomeTrait + 'static>
| ^^^^^
|
@@ -16,7 +16,7 @@
--> $DIR/regions-close-over-type-parameter-1.rs:10:5
|
LL | fn make_object1<A:SomeTrait>(v: A) -> Box<dyn SomeTrait + 'static> {
- | -- help: consider adding an explicit lifetime bound `A: 'static`...
+ | -- help: consider adding an explicit lifetime bound...: `A: 'static +`
LL | box v as Box<dyn SomeTrait + 'static>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
@@ -30,7 +30,7 @@
--> $DIR/regions-close-over-type-parameter-1.rs:20:5
|
LL | fn make_object3<'a,'b,A:SomeTrait+'a>(v: A) -> Box<dyn SomeTrait + 'b> {
- | -- help: consider adding an explicit lifetime bound `A: 'b`...
+ | -- help: consider adding an explicit lifetime bound...: `A: 'b +`
LL | box v as Box<dyn SomeTrait + 'b>
| ^^^^^
|
@@ -44,7 +44,7 @@
--> $DIR/regions-close-over-type-parameter-1.rs:20:5
|
LL | fn make_object3<'a,'b,A:SomeTrait+'a>(v: A) -> Box<dyn SomeTrait + 'b> {
- | -- help: consider adding an explicit lifetime bound `A: 'b`...
+ | -- help: consider adding an explicit lifetime bound...: `A: 'b +`
LL | box v as Box<dyn SomeTrait + 'b>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
diff --git a/src/test/ui/regions/regions-close-param-into-object.stderr b/src/test/ui/regions/regions-close-param-into-object.stderr
index 7f2c646..3b1a89d 100644
--- a/src/test/ui/regions/regions-close-param-into-object.stderr
+++ b/src/test/ui/regions/regions-close-param-into-object.stderr
@@ -2,7 +2,7 @@
--> $DIR/regions-close-param-into-object.rs:6:5
|
LL | fn p1<T>(v: T) -> Box<dyn X + 'static>
- | - help: consider adding an explicit lifetime bound `T: 'static`...
+ | - help: consider adding an explicit lifetime bound...: `T: 'static`
...
LL | Box::new(v)
| ^^^^^^^^^^^
@@ -17,7 +17,7 @@
--> $DIR/regions-close-param-into-object.rs:12:5
|
LL | fn p2<T>(v: Box<T>) -> Box<dyn X + 'static>
- | - help: consider adding an explicit lifetime bound `T: 'static`...
+ | - help: consider adding an explicit lifetime bound...: `T: 'static`
...
LL | Box::new(v)
| ^^^^^^^^^^^
@@ -32,7 +32,7 @@
--> $DIR/regions-close-param-into-object.rs:18:5
|
LL | fn p3<'a,T>(v: T) -> Box<dyn X + 'a>
- | - help: consider adding an explicit lifetime bound `T: 'a`...
+ | - help: consider adding an explicit lifetime bound...: `T: 'a`
...
LL | Box::new(v)
| ^^^^^^^^^^^
@@ -47,7 +47,7 @@
--> $DIR/regions-close-param-into-object.rs:24:5
|
LL | fn p4<'a,T>(v: Box<T>) -> Box<dyn X + 'a>
- | - help: consider adding an explicit lifetime bound `T: 'a`...
+ | - help: consider adding an explicit lifetime bound...: `T: 'a`
...
LL | Box::new(v)
| ^^^^^^^^^^^
diff --git a/src/test/ui/regions/regions-enum-not-wf.stderr b/src/test/ui/regions/regions-enum-not-wf.stderr
index 8701408..297fcb0 100644
--- a/src/test/ui/regions/regions-enum-not-wf.stderr
+++ b/src/test/ui/regions/regions-enum-not-wf.stderr
@@ -2,7 +2,7 @@
--> $DIR/regions-enum-not-wf.rs:18:18
|
LL | enum Ref1<'a, T> {
- | - help: consider adding an explicit lifetime bound `T: 'a`...
+ | - help: consider adding an explicit lifetime bound...: `T: 'a`
LL | Ref1Variant1(RequireOutlives<'a, T>)
| ^^^^^^^^^^^^^^^^^^^^^^
|
@@ -16,7 +16,7 @@
--> $DIR/regions-enum-not-wf.rs:23:25
|
LL | enum Ref2<'a, T> {
- | - help: consider adding an explicit lifetime bound `T: 'a`...
+ | - help: consider adding an explicit lifetime bound...: `T: 'a`
LL | Ref2Variant1,
LL | Ref2Variant2(isize, RequireOutlives<'a, T>),
| ^^^^^^^^^^^^^^^^^^^^^^
@@ -31,7 +31,7 @@
--> $DIR/regions-enum-not-wf.rs:35:1
|
LL | enum RefDouble<'a, 'b, T> {
- | ^ - help: consider adding an explicit lifetime bound `T: 'b`...
+ | ^ - help: consider adding an explicit lifetime bound...: `T: 'b`
| _|
| |
LL | | RefDoubleVariant1(&'a RequireOutlives<'b, T>)
@@ -52,7 +52,7 @@
--> $DIR/regions-enum-not-wf.rs:36:23
|
LL | enum RefDouble<'a, 'b, T> {
- | - help: consider adding an explicit lifetime bound `T: 'b`...
+ | - help: consider adding an explicit lifetime bound...: `T: 'b`
LL | RefDoubleVariant1(&'a RequireOutlives<'b, T>)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
diff --git a/src/test/ui/regions/regions-implied-bounds-projection-gap-1.stderr b/src/test/ui/regions/regions-implied-bounds-projection-gap-1.stderr
index 7fbc162..2f1a4ce 100644
--- a/src/test/ui/regions/regions-implied-bounds-projection-gap-1.stderr
+++ b/src/test/ui/regions/regions-implied-bounds-projection-gap-1.stderr
@@ -2,7 +2,7 @@
--> $DIR/regions-implied-bounds-projection-gap-1.rs:16:10
|
LL | fn func<'x, T:Trait1<'x>>(t: &'x T::Foo)
- | -- help: consider adding an explicit lifetime bound `T: 'x`...
+ | -- help: consider adding an explicit lifetime bound...: `T: 'x +`
LL | {
LL | wf::<&'x T>();
| ^^^^^
diff --git a/src/test/ui/regions/regions-infer-bound-from-trait.stderr b/src/test/ui/regions/regions-infer-bound-from-trait.stderr
index 382d932..a5a0ff5 100644
--- a/src/test/ui/regions/regions-infer-bound-from-trait.stderr
+++ b/src/test/ui/regions/regions-infer-bound-from-trait.stderr
@@ -2,7 +2,7 @@
--> $DIR/regions-infer-bound-from-trait.rs:33:5
|
LL | fn bar1<'a,A>(x: Inv<'a>, a: A) {
- | - help: consider adding an explicit lifetime bound `A: 'a`...
+ | - help: consider adding an explicit lifetime bound...: `A: 'a`
LL | check_bound(x, a)
| ^^^^^^^^^^^
|
@@ -16,7 +16,7 @@
--> $DIR/regions-infer-bound-from-trait.rs:37:5
|
LL | fn bar2<'a,'b,A:Is<'b>>(x: Inv<'a>, y: Inv<'b>, a: A) {
- | -- help: consider adding an explicit lifetime bound `A: 'a`...
+ | -- help: consider adding an explicit lifetime bound...: `A: 'a +`
LL | check_bound(x, a)
| ^^^^^^^^^^^
|
diff --git a/src/test/ui/resolve/resolve-primitive-fallback.rs b/src/test/ui/resolve/resolve-primitive-fallback.rs
index e5a3d68..992bcd7 100644
--- a/src/test/ui/resolve/resolve-primitive-fallback.rs
+++ b/src/test/ui/resolve/resolve-primitive-fallback.rs
@@ -2,7 +2,7 @@
// Make sure primitive type fallback doesn't work in value namespace
std::mem::size_of(u16);
//~^ ERROR expected value, found builtin type `u16`
- //~| ERROR this function takes 0 parameters but 1 parameter was supplied
+ //~| ERROR this function takes 0 arguments but 1 argument was supplied
// Make sure primitive type fallback doesn't work with global paths
let _: ::u8;
diff --git a/src/test/ui/resolve/resolve-primitive-fallback.stderr b/src/test/ui/resolve/resolve-primitive-fallback.stderr
index 92c2a03..6d61d2f 100644
--- a/src/test/ui/resolve/resolve-primitive-fallback.stderr
+++ b/src/test/ui/resolve/resolve-primitive-fallback.stderr
@@ -10,11 +10,13 @@
LL | let _: ::u8;
| ^^ not found in the crate root
-error[E0061]: this function takes 0 parameters but 1 parameter was supplied
+error[E0061]: this function takes 0 arguments but 1 argument was supplied
--> $DIR/resolve-primitive-fallback.rs:3:5
|
LL | std::mem::size_of(u16);
- | ^^^^^^^^^^^^^^^^^^^^^^ expected 0 parameters
+ | ^^^^^^^^^^^^^^^^^ --- supplied 1 argument
+ | |
+ | expected 0 arguments
error: aborting due to 3 previous errors
diff --git a/src/test/ui/rfc-2093-infer-outlives/dont-infer-static.stderr b/src/test/ui/rfc-2093-infer-outlives/dont-infer-static.stderr
index b049d8a..c3cfc5a 100644
--- a/src/test/ui/rfc-2093-infer-outlives/dont-infer-static.stderr
+++ b/src/test/ui/rfc-2093-infer-outlives/dont-infer-static.stderr
@@ -2,7 +2,7 @@
--> $DIR/dont-infer-static.rs:8:5
|
LL | struct Foo<U> {
- | - help: consider adding an explicit lifetime bound `U: 'static`...
+ | - help: consider adding an explicit lifetime bound...: `U: 'static`
LL | bar: Bar<U>
| ^^^^^^^^^^^
|
diff --git a/src/test/ui/rfc-2093-infer-outlives/regions-enum-not-wf.stderr b/src/test/ui/rfc-2093-infer-outlives/regions-enum-not-wf.stderr
index 8701408..297fcb0 100644
--- a/src/test/ui/rfc-2093-infer-outlives/regions-enum-not-wf.stderr
+++ b/src/test/ui/rfc-2093-infer-outlives/regions-enum-not-wf.stderr
@@ -2,7 +2,7 @@
--> $DIR/regions-enum-not-wf.rs:18:18
|
LL | enum Ref1<'a, T> {
- | - help: consider adding an explicit lifetime bound `T: 'a`...
+ | - help: consider adding an explicit lifetime bound...: `T: 'a`
LL | Ref1Variant1(RequireOutlives<'a, T>)
| ^^^^^^^^^^^^^^^^^^^^^^
|
@@ -16,7 +16,7 @@
--> $DIR/regions-enum-not-wf.rs:23:25
|
LL | enum Ref2<'a, T> {
- | - help: consider adding an explicit lifetime bound `T: 'a`...
+ | - help: consider adding an explicit lifetime bound...: `T: 'a`
LL | Ref2Variant1,
LL | Ref2Variant2(isize, RequireOutlives<'a, T>),
| ^^^^^^^^^^^^^^^^^^^^^^
@@ -31,7 +31,7 @@
--> $DIR/regions-enum-not-wf.rs:35:1
|
LL | enum RefDouble<'a, 'b, T> {
- | ^ - help: consider adding an explicit lifetime bound `T: 'b`...
+ | ^ - help: consider adding an explicit lifetime bound...: `T: 'b`
| _|
| |
LL | | RefDoubleVariant1(&'a RequireOutlives<'b, T>)
@@ -52,7 +52,7 @@
--> $DIR/regions-enum-not-wf.rs:36:23
|
LL | enum RefDouble<'a, 'b, T> {
- | - help: consider adding an explicit lifetime bound `T: 'b`...
+ | - help: consider adding an explicit lifetime bound...: `T: 'b`
LL | RefDoubleVariant1(&'a RequireOutlives<'b, T>)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
diff --git a/src/test/ui/rfc-2093-infer-outlives/regions-struct-not-wf.stderr b/src/test/ui/rfc-2093-infer-outlives/regions-struct-not-wf.stderr
index 825c101..f665889 100644
--- a/src/test/ui/rfc-2093-infer-outlives/regions-struct-not-wf.stderr
+++ b/src/test/ui/rfc-2093-infer-outlives/regions-struct-not-wf.stderr
@@ -2,7 +2,7 @@
--> $DIR/regions-struct-not-wf.rs:13:5
|
LL | impl<'a, T> Trait<'a, T> for usize {
- | - help: consider adding an explicit lifetime bound `T: 'a`...
+ | - help: consider adding an explicit lifetime bound...: `T: 'a`
LL | type Out = &'a T;
| ^^^^^^^^^^^^^^^^^
|
@@ -16,7 +16,7 @@
--> $DIR/regions-struct-not-wf.rs:21:5
|
LL | impl<'a, T> Trait<'a, T> for u32 {
- | - help: consider adding an explicit lifetime bound `T: 'a`...
+ | - help: consider adding an explicit lifetime bound...: `T: 'a`
LL | type Out = RefOk<'a, T>;
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
diff --git a/src/test/ui/span/E0057.stderr b/src/test/ui/span/E0057.stderr
index 6b5890c..31579e2 100644
--- a/src/test/ui/span/E0057.stderr
+++ b/src/test/ui/span/E0057.stderr
@@ -1,14 +1,18 @@
-error[E0057]: this function takes 1 parameter but 0 parameters were supplied
+error[E0057]: this function takes 1 argument but 0 arguments were supplied
--> $DIR/E0057.rs:3:13
|
LL | let a = f();
- | ^^^ expected 1 parameter
+ | ^-- supplied 0 arguments
+ | |
+ | expected 1 argument
-error[E0057]: this function takes 1 parameter but 2 parameters were supplied
+error[E0057]: this function takes 1 argument but 2 arguments were supplied
--> $DIR/E0057.rs:5:13
|
LL | let c = f(2, 3);
- | ^^^^^^^ expected 1 parameter
+ | ^ - - supplied 2 arguments
+ | |
+ | expected 1 argument
error: aborting due to 2 previous errors
diff --git a/src/test/ui/span/issue-34264.stderr b/src/test/ui/span/issue-34264.stderr
index 80a237a..116f5dd 100644
--- a/src/test/ui/span/issue-34264.stderr
+++ b/src/test/ui/span/issue-34264.stderr
@@ -50,14 +50,16 @@
LL | fn bar(_: x, y: usize) {}
| ^^^^
-error[E0061]: this function takes 2 parameters but 3 parameters were supplied
+error[E0061]: this function takes 2 arguments but 3 arguments were supplied
--> $DIR/issue-34264.rs:7:5
|
LL | fn foo(Option<i32>, String) {}
| --------------------------- defined here
...
LL | foo(Some(42), 2, "");
- | ^^^^^^^^^^^^^^^^^^^^ expected 2 parameters
+ | ^^^ -------- - -- supplied 3 arguments
+ | |
+ | expected 2 arguments
error[E0308]: mismatched types
--> $DIR/issue-34264.rs:8:13
@@ -65,14 +67,16 @@
LL | bar("", "");
| ^^ expected `usize`, found `&str`
-error[E0061]: this function takes 2 parameters but 3 parameters were supplied
+error[E0061]: this function takes 2 arguments but 3 arguments were supplied
--> $DIR/issue-34264.rs:10:5
|
LL | fn bar(x, y: usize) {}
| ------------------- defined here
...
LL | bar(1, 2, 3);
- | ^^^^^^^^^^^^ expected 2 parameters
+ | ^^^ - - - supplied 3 arguments
+ | |
+ | expected 2 arguments
error: aborting due to 6 previous errors
diff --git a/src/test/ui/span/missing-unit-argument.stderr b/src/test/ui/span/missing-unit-argument.stderr
index 90a96e3..f6344fb 100644
--- a/src/test/ui/span/missing-unit-argument.stderr
+++ b/src/test/ui/span/missing-unit-argument.stderr
@@ -1,68 +1,72 @@
-error[E0061]: this function takes 1 parameter but 0 parameters were supplied
+error[E0061]: this function takes 1 argument but 0 arguments were supplied
--> $DIR/missing-unit-argument.rs:11:33
|
LL | let _: Result<(), String> = Ok();
- | ^^^^
+ | ^^-- supplied 0 arguments
|
help: expected the unit value `()`; create it with empty parentheses
|
LL | let _: Result<(), String> = Ok(());
| ^^
-error[E0061]: this function takes 2 parameters but 0 parameters were supplied
+error[E0061]: this function takes 2 arguments but 0 arguments were supplied
--> $DIR/missing-unit-argument.rs:12:5
|
LL | fn foo(():(), ():()) {}
| -------------------- defined here
...
LL | foo();
- | ^^^^^ expected 2 parameters
+ | ^^^-- supplied 0 arguments
+ | |
+ | expected 2 arguments
-error[E0061]: this function takes 2 parameters but 1 parameter was supplied
+error[E0061]: this function takes 2 arguments but 1 argument was supplied
--> $DIR/missing-unit-argument.rs:13:5
|
LL | fn foo(():(), ():()) {}
| -------------------- defined here
...
LL | foo(());
- | ^^^^^^^ expected 2 parameters
+ | ^^^ -- supplied 1 argument
+ | |
+ | expected 2 arguments
-error[E0061]: this function takes 1 parameter but 0 parameters were supplied
+error[E0061]: this function takes 1 argument but 0 arguments were supplied
--> $DIR/missing-unit-argument.rs:14:5
|
LL | fn bar(():()) {}
| ------------- defined here
...
LL | bar();
- | ^^^^^
+ | ^^^-- supplied 0 arguments
|
help: expected the unit value `()`; create it with empty parentheses
|
LL | bar(());
| ^^
-error[E0061]: this function takes 1 parameter but 0 parameters were supplied
+error[E0061]: this function takes 1 argument but 0 arguments were supplied
--> $DIR/missing-unit-argument.rs:15:7
|
LL | fn baz(self, (): ()) { }
| -------------------- defined here
...
LL | S.baz();
- | ^^^
+ | ^^^- supplied 0 arguments
|
help: expected the unit value `()`; create it with empty parentheses
|
LL | S.baz(());
| ^^
-error[E0061]: this function takes 1 parameter but 0 parameters were supplied
+error[E0061]: this function takes 1 argument but 0 arguments were supplied
--> $DIR/missing-unit-argument.rs:16:7
|
LL | fn generic<T>(self, _: T) { }
| ------------------------- defined here
...
LL | S.generic::<()>();
- | ^^^^^^^
+ | ^^^^^^^------ supplied 0 arguments
|
help: expected the unit value `()`; create it with empty parentheses
|
diff --git a/src/test/ui/suggestions/suggest-impl-trait-lifetime.fixed b/src/test/ui/suggestions/suggest-impl-trait-lifetime.fixed
index 8592af1..589ee1a 100644
--- a/src/test/ui/suggestions/suggest-impl-trait-lifetime.fixed
+++ b/src/test/ui/suggestions/suggest-impl-trait-lifetime.fixed
@@ -3,7 +3,7 @@
use std::fmt::Debug;
fn foo(d: impl Debug + 'static) {
-//~^ HELP consider adding an explicit lifetime bound `'static` to `impl Debug`
+//~^ HELP consider adding an explicit lifetime bound...
bar(d);
//~^ ERROR the parameter type `impl Debug` may not live long enough
//~| NOTE ...so that the type `impl Debug` will meet its required lifetime bounds
diff --git a/src/test/ui/suggestions/suggest-impl-trait-lifetime.rs b/src/test/ui/suggestions/suggest-impl-trait-lifetime.rs
index c67d78e..9a87129 100644
--- a/src/test/ui/suggestions/suggest-impl-trait-lifetime.rs
+++ b/src/test/ui/suggestions/suggest-impl-trait-lifetime.rs
@@ -3,7 +3,7 @@
use std::fmt::Debug;
fn foo(d: impl Debug) {
-//~^ HELP consider adding an explicit lifetime bound `'static` to `impl Debug`
+//~^ HELP consider adding an explicit lifetime bound...
bar(d);
//~^ ERROR the parameter type `impl Debug` may not live long enough
//~| NOTE ...so that the type `impl Debug` will meet its required lifetime bounds
diff --git a/src/test/ui/suggestions/suggest-impl-trait-lifetime.stderr b/src/test/ui/suggestions/suggest-impl-trait-lifetime.stderr
index cba231d..b6e6c0b 100644
--- a/src/test/ui/suggestions/suggest-impl-trait-lifetime.stderr
+++ b/src/test/ui/suggestions/suggest-impl-trait-lifetime.stderr
@@ -1,6 +1,9 @@
error[E0310]: the parameter type `impl Debug` may not live long enough
--> $DIR/suggest-impl-trait-lifetime.rs:7:5
|
+LL | fn foo(d: impl Debug) {
+ | ---------- help: consider adding an explicit lifetime bound...: `impl Debug + 'static`
+LL |
LL | bar(d);
| ^^^
|
@@ -9,10 +12,6 @@
|
LL | bar(d);
| ^^^
-help: consider adding an explicit lifetime bound `'static` to `impl Debug`...
- |
-LL | fn foo(d: impl Debug + 'static) {
- | ^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.rs b/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.rs
index fa3e1a3..d012687 100644
--- a/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.rs
+++ b/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.rs
@@ -18,6 +18,6 @@
}
fn main() {
- <E>::V(); //~ ERROR this function takes 1 parameter but 0 parameters were supplied
+ <E>::V(); //~ ERROR this function takes 1 argument but 0 arguments were supplied
let _: u8 = <E2>::V; //~ ERROR mismatched types
}
diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr b/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr
index 95c3a08..46e7dd0 100644
--- a/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr
+++ b/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr
@@ -1,11 +1,13 @@
-error[E0061]: this function takes 1 parameter but 0 parameters were supplied
+error[E0061]: this function takes 1 argument but 0 arguments were supplied
--> $DIR/enum-variant-priority-higher-than-other-inherent.rs:21:5
|
LL | V(u8)
| ----- defined here
...
LL | <E>::V();
- | ^^^^^^^^ expected 1 parameter
+ | ^^^^^^-- supplied 0 arguments
+ | |
+ | expected 1 argument
error[E0308]: mismatched types
--> $DIR/enum-variant-priority-higher-than-other-inherent.rs:22:17
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 5a7f9d7..22e2391 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
@@ -25,7 +25,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
LL | fn wrong_generic<T>(t: T) -> WrongGeneric<T> {
- | - help: consider adding an explicit lifetime bound `T: 'static`...
+ | - help: consider adding an explicit lifetime bound...: `T: 'static`
|
note: ...so that the type `T` will meet its required lifetime bounds
--> $DIR/generic_type_does_not_live_long_enough.rs:9:1
diff --git a/src/test/ui/type/type-ascription-instead-of-initializer.rs b/src/test/ui/type/type-ascription-instead-of-initializer.rs
index aef2525..9f9b6f0 100644
--- a/src/test/ui/type/type-ascription-instead-of-initializer.rs
+++ b/src/test/ui/type/type-ascription-instead-of-initializer.rs
@@ -1,4 +1,4 @@
fn main() {
let x: Vec::with_capacity(10, 20); //~ ERROR expected type, found `10`
- //~^ ERROR this function takes 1 parameter
+ //~^ ERROR this function takes 1 argument
}
diff --git a/src/test/ui/type/type-ascription-instead-of-initializer.stderr b/src/test/ui/type/type-ascription-instead-of-initializer.stderr
index 3fe676d..530f77e 100644
--- a/src/test/ui/type/type-ascription-instead-of-initializer.stderr
+++ b/src/test/ui/type/type-ascription-instead-of-initializer.stderr
@@ -7,11 +7,13 @@
| |help: use `=` if you meant to assign
| while parsing the type for `x`
-error[E0061]: this function takes 1 parameter but 2 parameters were supplied
+error[E0061]: this function takes 1 argument but 2 arguments were supplied
--> $DIR/type-ascription-instead-of-initializer.rs:2:12
|
LL | let x: Vec::with_capacity(10, 20);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected 1 parameter
+ | ^^^^^^^^^^^^^^^^^^ -- -- supplied 2 arguments
+ | |
+ | expected 1 argument
error: aborting due to 2 previous errors
diff --git a/src/test/ui/wf/wf-impl-associated-type-region.stderr b/src/test/ui/wf/wf-impl-associated-type-region.stderr
index 9cc3602..9942c80 100644
--- a/src/test/ui/wf/wf-impl-associated-type-region.stderr
+++ b/src/test/ui/wf/wf-impl-associated-type-region.stderr
@@ -2,7 +2,7 @@
--> $DIR/wf-impl-associated-type-region.rs:10:5
|
LL | impl<'a, T> Foo<'a> for T {
- | - help: consider adding an explicit lifetime bound `T: 'a`...
+ | - help: consider adding an explicit lifetime bound...: `T: 'a`
LL | type Bar = &'a T;
| ^^^^^^^^^^^^^^^^^
|
diff --git a/src/test/ui/wf/wf-in-fn-type-static.stderr b/src/test/ui/wf/wf-in-fn-type-static.stderr
index 8952c78..7dc8f5a 100644
--- a/src/test/ui/wf/wf-in-fn-type-static.stderr
+++ b/src/test/ui/wf/wf-in-fn-type-static.stderr
@@ -2,7 +2,7 @@
--> $DIR/wf-in-fn-type-static.rs:13:5
|
LL | struct Foo<T> {
- | - help: consider adding an explicit lifetime bound `T: 'static`...
+ | - help: consider adding an explicit lifetime bound...: `T: 'static`
LL | // needs T: 'static
LL | x: fn() -> &'static T
| ^^^^^^^^^^^^^^^^^^^^^
@@ -17,7 +17,7 @@
--> $DIR/wf-in-fn-type-static.rs:18:5
|
LL | struct Bar<T> {
- | - help: consider adding an explicit lifetime bound `T: 'static`...
+ | - help: consider adding an explicit lifetime bound...: `T: 'static`
LL | // needs T: Copy
LL | x: fn(&'static T)
| ^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/wf/wf-in-obj-type-static.stderr b/src/test/ui/wf/wf-in-obj-type-static.stderr
index c461da7..32c3198 100644
--- a/src/test/ui/wf/wf-in-obj-type-static.stderr
+++ b/src/test/ui/wf/wf-in-obj-type-static.stderr
@@ -2,7 +2,7 @@
--> $DIR/wf-in-obj-type-static.rs:14:5
|
LL | struct Foo<T> {
- | - help: consider adding an explicit lifetime bound `T: 'static`...
+ | - help: consider adding an explicit lifetime bound...: `T: 'static`
LL | // needs T: 'static
LL | x: dyn Object<&'static T>
| ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/wf/wf-outlives-ty-in-fn-or-trait.stderr b/src/test/ui/wf/wf-outlives-ty-in-fn-or-trait.stderr
index f1cf514..52786fb 100644
--- a/src/test/ui/wf/wf-outlives-ty-in-fn-or-trait.stderr
+++ b/src/test/ui/wf/wf-outlives-ty-in-fn-or-trait.stderr
@@ -2,7 +2,7 @@
--> $DIR/wf-outlives-ty-in-fn-or-trait.rs:9:5
|
LL | impl<'a, T> Trait<'a, T> for usize {
- | - help: consider adding an explicit lifetime bound `T: 'a`...
+ | - help: consider adding an explicit lifetime bound...: `T: 'a`
LL | type Out = &'a fn(T);
| ^^^^^^^^^^^^^^^^^^^^^
|
@@ -16,7 +16,7 @@
--> $DIR/wf-outlives-ty-in-fn-or-trait.rs:19:5
|
LL | impl<'a, T> Trait<'a, T> for u32 {
- | - help: consider adding an explicit lifetime bound `T: 'a`...
+ | - help: consider adding an explicit lifetime bound...: `T: 'a`
LL | type Out = &'a dyn Baz<T>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
diff --git a/src/tools/clippy b/src/tools/clippy
index 2855b21..8fbb23f 160000
--- a/src/tools/clippy
+++ b/src/tools/clippy
@@ -1 +1 @@
-Subproject commit 2855b2143972df7102333193aa3c83ddce227e36
+Subproject commit 8fbb23f2549e75b89967f09b9293607bd3bb96a6
diff --git a/src/tools/rls b/src/tools/rls
index 0100ac8..10bf331 160000
--- a/src/tools/rls
+++ b/src/tools/rls
@@ -1 +1 @@
-Subproject commit 0100ac87b4ce5bbed6e56a62f313fbc3ff037a89
+Subproject commit 10bf331d4d1280d773045e57d65031969c51dec6