diff --git a/src/bootstrap/bin/rustdoc.rs b/src/bootstrap/bin/rustdoc.rs index 36beec3a944a0..085f243785cbe 100644 --- a/src/bootstrap/bin/rustdoc.rs +++ b/src/bootstrap/bin/rustdoc.rs @@ -35,7 +35,7 @@ fn main() { .arg("--cfg") .arg("dox") .arg("--sysroot") - .arg(sysroot) + .arg(&sysroot) .env(bootstrap::util::dylib_path_var(), env::join_paths(&dylib_path).unwrap()); @@ -72,7 +72,13 @@ fn main() { } if verbose > 1 { - eprintln!("rustdoc command: {:?}", cmd); + eprintln!( + "rustdoc command: {:?}={:?} {:?}", + bootstrap::util::dylib_path_var(), + env::join_paths(&dylib_path).unwrap(), + cmd, + ); + eprintln!("sysroot: {:?}", sysroot); eprintln!("libdir: {:?}", libdir); } diff --git a/src/liballoc/tests/binary_heap.rs b/src/liballoc/tests/binary_heap.rs index 1d4a3edc1ac42..0930f8dacd494 100644 --- a/src/liballoc/tests/binary_heap.rs +++ b/src/liballoc/tests/binary_heap.rs @@ -282,7 +282,7 @@ fn assert_covariance() { // // Destructors must be called exactly once per element. #[test] -#[cfg(not(miri))] // Miri does not support panics +#[cfg(not(miri))] // Miri does not support panics nor entropy fn panic_safe() { static DROP_COUNTER: AtomicUsize = AtomicUsize::new(0); diff --git a/src/liballoc/tests/btree/map.rs b/src/liballoc/tests/btree/map.rs index f14750089c956..844afe870766b 100644 --- a/src/liballoc/tests/btree/map.rs +++ b/src/liballoc/tests/btree/map.rs @@ -226,7 +226,6 @@ fn test_range_equal_empty_cases() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_range_equal_excluded() { let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect(); map.range((Excluded(2), Excluded(2))); @@ -234,7 +233,6 @@ fn test_range_equal_excluded() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_range_backwards_1() { let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect(); map.range((Included(3), Included(2))); @@ -242,7 +240,6 @@ fn test_range_backwards_1() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_range_backwards_2() { let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect(); map.range((Included(3), Excluded(2))); @@ -250,7 +247,6 @@ fn test_range_backwards_2() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_range_backwards_3() { let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect(); map.range((Excluded(3), Included(2))); @@ -258,7 +254,6 @@ fn test_range_backwards_3() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_range_backwards_4() { let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect(); map.range((Excluded(3), Excluded(2))); diff --git a/src/liballoc/tests/slice.rs b/src/liballoc/tests/slice.rs index feba46b0fad78..b54c128a0249a 100644 --- a/src/liballoc/tests/slice.rs +++ b/src/liballoc/tests/slice.rs @@ -258,7 +258,6 @@ fn test_swap_remove() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_swap_remove_fail() { let mut v = vec![1]; let _ = v.swap_remove(0); @@ -632,7 +631,6 @@ fn test_insert() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_insert_oob() { let mut a = vec![1, 2, 3]; a.insert(4, 5); @@ -657,7 +655,6 @@ fn test_remove() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_remove_fail() { let mut a = vec![1]; let _ = a.remove(0); @@ -939,7 +936,6 @@ fn test_windowsator() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_windowsator_0() { let v = &[1, 2, 3, 4]; let _it = v.windows(0); @@ -964,7 +960,6 @@ fn test_chunksator() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_chunksator_0() { let v = &[1, 2, 3, 4]; let _it = v.chunks(0); @@ -989,7 +984,6 @@ fn test_chunks_exactator() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_chunks_exactator_0() { let v = &[1, 2, 3, 4]; let _it = v.chunks_exact(0); @@ -1014,7 +1008,6 @@ fn test_rchunksator() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_rchunksator_0() { let v = &[1, 2, 3, 4]; let _it = v.rchunks(0); @@ -1039,7 +1032,6 @@ fn test_rchunks_exactator() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_rchunks_exactator_0() { let v = &[1, 2, 3, 4]; let _it = v.rchunks_exact(0); @@ -1092,7 +1084,6 @@ fn test_vec_default() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_overflow_does_not_cause_segfault() { let mut v = vec![]; v.reserve_exact(!0); @@ -1102,7 +1093,6 @@ fn test_overflow_does_not_cause_segfault() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_overflow_does_not_cause_segfault_managed() { let mut v = vec![Rc::new(1)]; v.reserve_exact(!0); @@ -1278,7 +1268,6 @@ fn test_mut_chunks_rev() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mut_chunks_0() { let mut v = [1, 2, 3, 4]; let _it = v.chunks_mut(0); @@ -1311,7 +1300,6 @@ fn test_mut_chunks_exact_rev() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mut_chunks_exact_0() { let mut v = [1, 2, 3, 4]; let _it = v.chunks_exact_mut(0); @@ -1344,7 +1332,6 @@ fn test_mut_rchunks_rev() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mut_rchunks_0() { let mut v = [1, 2, 3, 4]; let _it = v.rchunks_mut(0); @@ -1377,7 +1364,6 @@ fn test_mut_rchunks_exact_rev() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mut_rchunks_exact_0() { let mut v = [1, 2, 3, 4]; let _it = v.rchunks_exact_mut(0); @@ -1411,7 +1397,7 @@ fn test_box_slice_clone() { #[test] #[allow(unused_must_use)] // here, we care about the side effects of `.clone()` #[cfg_attr(target_os = "emscripten", ignore)] -#[cfg(not(miri))] // Miri does not support panics +#[cfg(not(miri))] // Miri does not support threads nor entropy fn test_box_slice_clone_panics() { use std::sync::Arc; use std::sync::atomic::{AtomicUsize, Ordering}; @@ -1476,7 +1462,6 @@ fn test_copy_from_slice() { #[test] #[should_panic(expected = "destination and source slices have different lengths")] -#[cfg(not(miri))] // Miri does not support panics fn test_copy_from_slice_dst_longer() { let src = [0, 1, 2, 3]; let mut dst = [0; 5]; @@ -1485,7 +1470,6 @@ fn test_copy_from_slice_dst_longer() { #[test] #[should_panic(expected = "destination and source slices have different lengths")] -#[cfg(not(miri))] // Miri does not support panics fn test_copy_from_slice_dst_shorter() { let src = [0, 1, 2, 3]; let mut dst = [0; 3]; @@ -1605,7 +1589,7 @@ thread_local!(static SILENCE_PANIC: Cell = Cell::new(false)); #[test] #[cfg_attr(target_os = "emscripten", ignore)] // no threads -#[cfg(not(miri))] // Miri does not support panics +#[cfg(not(miri))] // Miri does not support threads nor entropy fn panic_safe() { let prev = panic::take_hook(); panic::set_hook(Box::new(move |info| { diff --git a/src/liballoc/tests/str.rs b/src/liballoc/tests/str.rs index b33a564218888..b197516403f78 100644 --- a/src/liballoc/tests/str.rs +++ b/src/liballoc/tests/str.rs @@ -7,7 +7,7 @@ fn test_le() { assert!("" <= ""); assert!("" <= "foo"); assert!("foo" <= "foo"); - assert!("foo" != "bar"); + assert_ne!("foo", "bar"); } #[test] @@ -351,7 +351,6 @@ mod slice_index { // to be used in `should_panic`) #[test] #[should_panic(expected = "out of bounds")] - #[cfg(not(miri))] // Miri does not support panics fn assert_range_eq_can_fail_by_panic() { assert_range_eq!("abc", 0..5, "abc"); } @@ -361,7 +360,6 @@ mod slice_index { // to be used in `should_panic`) #[test] #[should_panic(expected = "==")] - #[cfg(not(miri))] // Miri does not support panics fn assert_range_eq_can_fail_by_inequality() { assert_range_eq!("abc", 0..2, "abc"); } @@ -409,7 +407,6 @@ mod slice_index { #[test] #[should_panic(expected = $expect_msg)] - #[cfg(not(miri))] // Miri does not support panics fn index_fail() { let v: String = $data.into(); let v: &str = &v; @@ -418,7 +415,6 @@ mod slice_index { #[test] #[should_panic(expected = $expect_msg)] - #[cfg(not(miri))] // Miri does not support panics fn index_mut_fail() { let mut v: String = $data.into(); let v: &mut str = &mut v; @@ -514,7 +510,6 @@ mod slice_index { #[test] #[should_panic] - #[cfg(not(miri))] // Miri does not support panics fn test_slice_fail() { &"中华Việt Nam"[0..2]; } @@ -666,14 +661,12 @@ mod slice_index { // check the panic includes the prefix of the sliced string #[test] #[should_panic(expected="byte index 1024 is out of bounds of `Lorem ipsum dolor sit amet")] - #[cfg(not(miri))] // Miri does not support panics fn test_slice_fail_truncated_1() { &LOREM_PARAGRAPH[..1024]; } // check the truncation in the panic message #[test] #[should_panic(expected="luctus, im`[...]")] - #[cfg(not(miri))] // Miri does not support panics fn test_slice_fail_truncated_2() { &LOREM_PARAGRAPH[..1024]; } @@ -688,7 +681,6 @@ fn test_str_slice_rangetoinclusive_ok() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_str_slice_rangetoinclusive_notok() { let s = "abcαβγ"; &s[..=3]; @@ -704,7 +696,6 @@ fn test_str_slicemut_rangetoinclusive_ok() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_str_slicemut_rangetoinclusive_notok() { let mut s = "abcαβγ".to_owned(); let s: &mut str = &mut s; @@ -894,7 +885,6 @@ fn test_as_bytes() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_as_bytes_fail() { // Don't double free. (I'm not sure if this exercises the // original problem code path anymore.) @@ -984,7 +974,6 @@ fn test_split_at_mut() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_split_at_boundscheck() { let s = "ศไทย中华Việt Nam"; s.split_at(1); diff --git a/src/liballoc/tests/string.rs b/src/liballoc/tests/string.rs index 7e93d84fe3b97..7e75b8c4f28c8 100644 --- a/src/liballoc/tests/string.rs +++ b/src/liballoc/tests/string.rs @@ -231,7 +231,6 @@ fn test_split_off_empty() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_split_off_past_end() { let orig = "Hello, world!"; let mut split = String::from(orig); @@ -240,7 +239,6 @@ fn test_split_off_past_end() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_split_off_mid_char() { let mut orig = String::from("山"); orig.split_off(1); @@ -289,7 +287,6 @@ fn test_str_truncate_invalid_len() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_str_truncate_split_codepoint() { let mut s = String::from("\u{FC}"); // ü s.truncate(1); @@ -324,7 +321,6 @@ fn remove() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn remove_bad() { "ศ".to_string().remove(1); } @@ -360,13 +356,11 @@ fn insert() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn insert_bad1() { "".to_string().insert(1, 't'); } #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn insert_bad2() { "ệ".to_string().insert(1, 't'); } @@ -447,7 +441,6 @@ fn test_replace_range() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_replace_range_char_boundary() { let mut s = "Hello, 世界!".to_owned(); s.replace_range(..8, ""); @@ -464,7 +457,6 @@ fn test_replace_range_inclusive_range() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_replace_range_out_of_bounds() { let mut s = String::from("12345"); s.replace_range(5..6, "789"); @@ -472,7 +464,6 @@ fn test_replace_range_out_of_bounds() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_replace_range_inclusive_out_of_bounds() { let mut s = String::from("12345"); s.replace_range(5..=5, "789"); diff --git a/src/liballoc/tests/vec.rs b/src/liballoc/tests/vec.rs index 6e4ca1d90e642..545332bcd6a2f 100644 --- a/src/liballoc/tests/vec.rs +++ b/src/liballoc/tests/vec.rs @@ -368,7 +368,6 @@ fn test_vec_truncate_drop() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_vec_truncate_fail() { struct BadElem(i32); impl Drop for BadElem { @@ -392,7 +391,6 @@ fn test_index() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_index_out_of_bounds() { let vec = vec![1, 2, 3]; let _ = vec[3]; @@ -400,7 +398,6 @@ fn test_index_out_of_bounds() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_slice_out_of_bounds_1() { let x = vec![1, 2, 3, 4, 5]; &x[!0..]; @@ -408,7 +405,6 @@ fn test_slice_out_of_bounds_1() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_slice_out_of_bounds_2() { let x = vec![1, 2, 3, 4, 5]; &x[..6]; @@ -416,7 +412,6 @@ fn test_slice_out_of_bounds_2() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_slice_out_of_bounds_3() { let x = vec![1, 2, 3, 4, 5]; &x[!0..4]; @@ -424,7 +419,6 @@ fn test_slice_out_of_bounds_3() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_slice_out_of_bounds_4() { let x = vec![1, 2, 3, 4, 5]; &x[1..6]; @@ -432,7 +426,6 @@ fn test_slice_out_of_bounds_4() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_slice_out_of_bounds_5() { let x = vec![1, 2, 3, 4, 5]; &x[3..2]; @@ -440,7 +433,6 @@ fn test_slice_out_of_bounds_5() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_swap_remove_empty() { let mut vec = Vec::::new(); vec.swap_remove(0); @@ -511,7 +503,6 @@ fn test_drain_items_zero_sized() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_drain_out_of_bounds() { let mut v = vec![1, 2, 3, 4, 5]; v.drain(5..6); @@ -585,7 +576,6 @@ fn test_drain_max_vec_size() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_drain_inclusive_out_of_bounds() { let mut v = vec![1, 2, 3, 4, 5]; v.drain(5..=5); @@ -615,7 +605,6 @@ fn test_splice_inclusive_range() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_splice_out_of_bounds() { let mut v = vec![1, 2, 3, 4, 5]; let a = [10, 11, 12]; @@ -624,7 +613,6 @@ fn test_splice_out_of_bounds() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_splice_inclusive_out_of_bounds() { let mut v = vec![1, 2, 3, 4, 5]; let a = [10, 11, 12]; diff --git a/src/liballoc/tests/vec_deque.rs b/src/liballoc/tests/vec_deque.rs index 16ddc1444fcf9..e0fe10a55f55c 100644 --- a/src/liballoc/tests/vec_deque.rs +++ b/src/liballoc/tests/vec_deque.rs @@ -108,7 +108,6 @@ fn test_index() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_index_out_of_bounds() { let mut deq = VecDeque::new(); for i in 1..4 { diff --git a/src/libcore/iter/sources.rs b/src/libcore/iter/sources.rs index 74ff7f41d76fa..ffc24df3ed42e 100644 --- a/src/libcore/iter/sources.rs +++ b/src/libcore/iter/sources.rs @@ -39,8 +39,7 @@ unsafe impl TrustedLen for Repeat {} /// Creates a new iterator that endlessly repeats a single element. /// -/// The `repeat()` function repeats a single value over and over and over and -/// over and over and 🔁. +/// The `repeat()` function repeats a single value over and over again. /// /// Infinite iterators like `repeat()` are often used with adapters like /// [`take`], in order to make them finite. @@ -128,8 +127,7 @@ unsafe impl A> TrustedLen for RepeatWith {} /// Creates a new iterator that repeats elements of type `A` endlessly by /// applying the provided closure, the repeater, `F: FnMut() -> A`. /// -/// The `repeat_with()` function calls the repeater over and over and over and -/// over and over and 🔁. +/// The `repeat_with()` function calls the repeater over and over again. /// /// Infinite iterators like `repeat_with()` are often used with adapters like /// [`take`], in order to make them finite. diff --git a/src/libcore/ops/range.rs b/src/libcore/ops/range.rs index 81a8d001dd9cb..4f71c8e794954 100644 --- a/src/libcore/ops/range.rs +++ b/src/libcore/ops/range.rs @@ -71,7 +71,7 @@ impl fmt::Debug for RangeFull { /// assert_eq!(arr[1..=3], [ 1,2,3 ]); /// ``` #[doc(alias = "..")] -#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 +#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 #[stable(feature = "rust1", since = "1.0.0")] pub struct Range { /// The lower bound of the range (inclusive). @@ -95,8 +95,6 @@ impl> Range { /// # Examples /// /// ``` - /// #![feature(range_contains)] - /// /// use std::f32; /// /// assert!(!(3..5).contains(&2)); @@ -112,7 +110,7 @@ impl> Range { /// assert!(!(0.0..f32::NAN).contains(&0.5)); /// assert!(!(f32::NAN..1.0).contains(&0.5)); /// ``` - #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] + #[stable(feature = "range_contains", since = "1.35.0")] pub fn contains(&self, item: &U) -> bool where Idx: PartialOrd, @@ -175,7 +173,7 @@ impl> Range { /// /// [`Iterator`]: ../iter/trait.IntoIterator.html #[doc(alias = "..")] -#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 +#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 #[stable(feature = "rust1", since = "1.0.0")] pub struct RangeFrom { /// The lower bound of the range (inclusive). @@ -196,8 +194,6 @@ impl> RangeFrom { /// # Examples /// /// ``` - /// #![feature(range_contains)] - /// /// use std::f32; /// /// assert!(!(3..).contains(&2)); @@ -208,7 +204,7 @@ impl> RangeFrom { /// assert!(!(0.0..).contains(&f32::NAN)); /// assert!(!(f32::NAN..).contains(&0.5)); /// ``` - #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] + #[stable(feature = "range_contains", since = "1.35.0")] pub fn contains(&self, item: &U) -> bool where Idx: PartialOrd, @@ -280,8 +276,6 @@ impl> RangeTo { /// # Examples /// /// ``` - /// #![feature(range_contains)] - /// /// use std::f32; /// /// assert!( (..5).contains(&-1_000_000_000)); @@ -292,7 +286,7 @@ impl> RangeTo { /// assert!(!(..1.0).contains(&f32::NAN)); /// assert!(!(..f32::NAN).contains(&0.5)); /// ``` - #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] + #[stable(feature = "range_contains", since = "1.35.0")] pub fn contains(&self, item: &U) -> bool where Idx: PartialOrd, @@ -329,7 +323,7 @@ impl> RangeTo { /// assert_eq!(arr[1..=3], [ 1,2,3 ]); // RangeInclusive /// ``` #[doc(alias = "..=")] -#[derive(Clone)] // not Copy -- see #27186 +#[derive(Clone)] // not Copy -- see #27186 #[stable(feature = "inclusive_range", since = "1.26.0")] pub struct RangeInclusive { pub(crate) start: Idx, @@ -365,7 +359,8 @@ impl RangeInclusiveEquality for T { impl PartialEq for RangeInclusive { #[inline] fn eq(&self, other: &Self) -> bool { - self.start == other.start && self.end == other.end + self.start == other.start + && self.end == other.end && RangeInclusiveEquality::canonicalized_is_empty(self) == RangeInclusiveEquality::canonicalized_is_empty(other) } @@ -397,7 +392,11 @@ impl RangeInclusive { #[inline] #[rustc_promotable] pub const fn new(start: Idx, end: Idx) -> Self { - Self { start, end, is_empty: None } + Self { + start, + end, + is_empty: None, + } } /// Returns the lower bound of the range (inclusive). @@ -478,8 +477,6 @@ impl> RangeInclusive { /// # Examples /// /// ``` - /// #![feature(range_contains)] - /// /// use std::f32; /// /// assert!(!(3..=5).contains(&2)); @@ -496,7 +493,7 @@ impl> RangeInclusive { /// assert!(!(0.0..=f32::NAN).contains(&0.0)); /// assert!(!(f32::NAN..=1.0).contains(&1.0)); /// ``` - #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] + #[stable(feature = "range_contains", since = "1.35.0")] pub fn contains(&self, item: &U) -> bool where Idx: PartialOrd, @@ -609,15 +606,12 @@ impl fmt::Debug for RangeToInclusive { } } -#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] impl> RangeToInclusive { /// Returns `true` if `item` is contained in the range. /// /// # Examples /// /// ``` - /// #![feature(range_contains)] - /// /// use std::f32; /// /// assert!( (..=5).contains(&-1_000_000_000)); @@ -628,7 +622,7 @@ impl> RangeToInclusive { /// assert!(!(..=1.0).contains(&f32::NAN)); /// assert!(!(..=f32::NAN).contains(&0.5)); /// ``` - #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] + #[stable(feature = "range_contains", since = "1.35.0")] pub fn contains(&self, item: &U) -> bool where Idx: PartialOrd, @@ -730,14 +724,11 @@ pub trait RangeBounds { #[stable(feature = "collections_range", since = "1.28.0")] fn end_bound(&self) -> Bound<&T>; - /// Returns `true` if `item` is contained in the range. /// /// # Examples /// /// ``` - /// #![feature(range_contains)] - /// /// use std::f32; /// /// assert!( (3..5).contains(&4)); @@ -747,7 +738,7 @@ pub trait RangeBounds { /// assert!(!(0.0..1.0).contains(&f32::NAN)); /// assert!(!(0.0..f32::NAN).contains(&0.5)); /// assert!(!(f32::NAN..1.0).contains(&0.5)); - #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] + #[stable(feature = "range_contains", since = "1.35.0")] fn contains(&self, item: &U) -> bool where T: PartialOrd, @@ -757,9 +748,7 @@ pub trait RangeBounds { Included(ref start) => *start <= item, Excluded(ref start) => *start < item, Unbounded => true, - }) - && - (match self.end_bound() { + }) && (match self.end_bound() { Included(ref end) => item <= *end, Excluded(ref end) => item < *end, Unbounded => true, @@ -835,7 +824,7 @@ impl RangeBounds for (Bound, Bound) { match *self { (Included(ref start), _) => Included(start), (Excluded(ref start), _) => Excluded(start), - (Unbounded, _) => Unbounded, + (Unbounded, _) => Unbounded, } } @@ -843,7 +832,7 @@ impl RangeBounds for (Bound, Bound) { match *self { (_, Included(ref end)) => Included(end), (_, Excluded(ref end)) => Excluded(end), - (_, Unbounded) => Unbounded, + (_, Unbounded) => Unbounded, } } } diff --git a/src/libcore/tests/cell.rs b/src/libcore/tests/cell.rs index b16416022c04e..7bd7d1874101a 100644 --- a/src/libcore/tests/cell.rs +++ b/src/libcore/tests/cell.rs @@ -5,15 +5,15 @@ use std::mem::drop; #[test] fn smoketest_cell() { let x = Cell::new(10); - assert!(x == Cell::new(10)); - assert!(x.get() == 10); + assert_eq!(x, Cell::new(10)); + assert_eq!(x.get(), 10); x.set(20); - assert!(x == Cell::new(20)); - assert!(x.get() == 20); + assert_eq!(x, Cell::new(20)); + assert_eq!(x.get(), 20); let y = Cell::new((30, 40)); - assert!(y == Cell::new((30, 40))); - assert!(y.get() == (30, 40)); + assert_eq!(y, Cell::new((30, 40))); + assert_eq!(y.get(), (30, 40)); } #[test] @@ -109,7 +109,6 @@ fn double_borrow_single_release_no_borrow_mut() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn discard_doesnt_unborrow() { let x = RefCell::new(0); let _b = x.borrow(); @@ -350,7 +349,6 @@ fn refcell_ref_coercion() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn refcell_swap_borrows() { let x = RefCell::new(0); let _b = x.borrow(); @@ -360,7 +358,6 @@ fn refcell_swap_borrows() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn refcell_replace_borrows() { let x = RefCell::new(0); let _b = x.borrow(); diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index a9db9b35d8d80..a3f0b02e2fe33 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -253,7 +253,6 @@ fn test_iterator_step_by_nth_overflow() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_iterator_step_by_zero() { let mut it = (0..).step_by(0); it.next(); @@ -1442,7 +1441,6 @@ fn test_rposition() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_rposition_panic() { let v: [(Box<_>, Box<_>); 4] = [(box 0, box 0), (box 0, box 0), diff --git a/src/libcore/tests/num/bignum.rs b/src/libcore/tests/num/bignum.rs index 956c22c998219..b873f1dd0652f 100644 --- a/src/libcore/tests/num/bignum.rs +++ b/src/libcore/tests/num/bignum.rs @@ -3,7 +3,6 @@ use core::num::bignum::tests::Big8x3 as Big; #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_from_u64_overflow() { Big::from_u64(0x1000000); } @@ -20,14 +19,12 @@ fn test_add() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_add_overflow_1() { Big::from_small(1).add(&Big::from_u64(0xffffff)); } #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_add_overflow_2() { Big::from_u64(0xffffff).add(&Big::from_small(1)); } @@ -45,7 +42,6 @@ fn test_add_small() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_add_small_overflow() { Big::from_u64(0xffffff).add_small(1); } @@ -61,14 +57,12 @@ fn test_sub() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_sub_underflow_1() { Big::from_u64(0x10665).sub(&Big::from_u64(0x10666)); } #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_sub_underflow_2() { Big::from_small(0).sub(&Big::from_u64(0x123456)); } @@ -82,7 +76,6 @@ fn test_mul_small() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mul_small_overflow() { Big::from_u64(0x800000).mul_small(2); } @@ -101,14 +94,12 @@ fn test_mul_pow2() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mul_pow2_overflow_1() { Big::from_u64(0x1).mul_pow2(24); } #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mul_pow2_overflow_2() { Big::from_u64(0x123).mul_pow2(16); } @@ -127,14 +118,12 @@ fn test_mul_pow5() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mul_pow5_overflow_1() { Big::from_small(1).mul_pow5(12); } #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mul_pow5_overflow_2() { Big::from_small(230).mul_pow5(8); } @@ -152,14 +141,12 @@ fn test_mul_digits() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mul_digits_overflow_1() { Big::from_u64(0x800000).mul_digits(&[2]); } #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mul_digits_overflow_2() { Big::from_u64(0x1000).mul_digits(&[0, 0x10]); } @@ -219,7 +206,6 @@ fn test_get_bit() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_get_bit_out_of_range() { Big::from_small(42).get_bit(24); } diff --git a/src/libcore/tests/num/int_macros.rs b/src/libcore/tests/num/int_macros.rs index 5c6ee8f8ba038..4881f79ec248a 100644 --- a/src/libcore/tests/num/int_macros.rs +++ b/src/libcore/tests/num/int_macros.rs @@ -12,7 +12,7 @@ mod tests { fn test_overflows() { assert!(MAX > 0); assert!(MIN <= 0); - assert!(MIN + MAX + 1 == 0); + assert_eq!(MIN + MAX + 1, 0); } #[test] @@ -22,22 +22,22 @@ mod tests { #[test] fn test_rem_euclid() { - assert!((-1 as $T).rem_euclid(MIN) == MAX); + assert_eq!((-1 as $T).rem_euclid(MIN), MAX); } #[test] pub fn test_abs() { - assert!((1 as $T).abs() == 1 as $T); - assert!((0 as $T).abs() == 0 as $T); - assert!((-1 as $T).abs() == 1 as $T); + assert_eq!((1 as $T).abs(), 1 as $T); + assert_eq!((0 as $T).abs(), 0 as $T); + assert_eq!((-1 as $T).abs(), 1 as $T); } #[test] fn test_signum() { - assert!((1 as $T).signum() == 1 as $T); - assert!((0 as $T).signum() == 0 as $T); - assert!((-0 as $T).signum() == 0 as $T); - assert!((-1 as $T).signum() == -1 as $T); + assert_eq!((1 as $T).signum(), 1 as $T); + assert_eq!((0 as $T).signum(), 0 as $T); + assert_eq!((-0 as $T).signum(), 0 as $T); + assert_eq!((-1 as $T).signum(), -1 as $T); } #[test] @@ -58,12 +58,12 @@ mod tests { #[test] fn test_bitwise_operators() { - assert!(0b1110 as $T == (0b1100 as $T).bitor(0b1010 as $T)); - assert!(0b1000 as $T == (0b1100 as $T).bitand(0b1010 as $T)); - assert!(0b0110 as $T == (0b1100 as $T).bitxor(0b1010 as $T)); - assert!(0b1110 as $T == (0b0111 as $T).shl(1)); - assert!(0b0111 as $T == (0b1110 as $T).shr(1)); - assert!(-(0b11 as $T) - (1 as $T) == (0b11 as $T).not()); + assert_eq!(0b1110 as $T, (0b1100 as $T).bitor(0b1010 as $T)); + assert_eq!(0b1000 as $T, (0b1100 as $T).bitand(0b1010 as $T)); + assert_eq!(0b0110 as $T, (0b1100 as $T).bitxor(0b1010 as $T)); + assert_eq!(0b1110 as $T, (0b0111 as $T).shl(1)); + assert_eq!(0b0111 as $T, (0b1110 as $T).shr(1)); + assert_eq!(-(0b11 as $T) - (1 as $T), (0b11 as $T).not()); } const A: $T = 0b0101100; @@ -75,17 +75,17 @@ mod tests { #[test] fn test_count_ones() { - assert!(A.count_ones() == 3); - assert!(B.count_ones() == 2); - assert!(C.count_ones() == 5); + assert_eq!(A.count_ones(), 3); + assert_eq!(B.count_ones(), 2); + assert_eq!(C.count_ones(), 5); } #[test] fn test_count_zeros() { let bits = mem::size_of::<$T>() * 8; - assert!(A.count_zeros() == bits as u32 - 3); - assert!(B.count_zeros() == bits as u32 - 2); - assert!(C.count_zeros() == bits as u32 - 5); + assert_eq!(A.count_zeros(), bits as u32 - 3); + assert_eq!(B.count_zeros(), bits as u32 - 2); + assert_eq!(C.count_zeros(), bits as u32 - 5); } #[test] @@ -148,9 +148,9 @@ mod tests { #[test] fn test_signed_checked_div() { - assert!((10 as $T).checked_div(2) == Some(5)); - assert!((5 as $T).checked_div(0) == None); - assert!(isize::MIN.checked_div(-1) == None); + assert_eq!((10 as $T).checked_div(2), Some(5)); + assert_eq!((5 as $T).checked_div(0), None); + assert_eq!(isize::MIN.checked_div(-1), None); } #[test] diff --git a/src/libcore/tests/ops.rs b/src/libcore/tests/ops.rs index 401644e120d16..78cf07119e729 100644 --- a/src/libcore/tests/ops.rs +++ b/src/libcore/tests/ops.rs @@ -7,11 +7,11 @@ fn test_range() { let r = Range { start: 2, end: 10 }; let mut count = 0; for (i, ri) in r.enumerate() { - assert!(ri == i + 2); + assert_eq!(ri, i + 2); assert!(ri >= 2 && ri < 10); count += 1; } - assert!(count == 8); + assert_eq!(count, 8); } #[test] @@ -19,11 +19,11 @@ fn test_range_from() { let r = RangeFrom { start: 2 }; let mut count = 0; for (i, ri) in r.take(10).enumerate() { - assert!(ri == i + 2); + assert_eq!(ri, i + 2); assert!(ri >= 2 && ri < 12); count += 1; } - assert!(count == 10); + assert_eq!(count, 10); } #[test] diff --git a/src/libcore/tests/option.rs b/src/libcore/tests/option.rs index 87ce2720c5918..b059b134868d9 100644 --- a/src/libcore/tests/option.rs +++ b/src/libcore/tests/option.rs @@ -69,7 +69,6 @@ fn test_option_dance() { } #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_option_too_much_dance() { struct A; let mut y = Some(A); @@ -130,7 +129,6 @@ fn test_unwrap() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_unwrap_panic1() { let x: Option = None; x.unwrap(); @@ -138,7 +136,6 @@ fn test_unwrap_panic1() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_unwrap_panic2() { let x: Option = None; x.unwrap(); diff --git a/src/libcore/tests/result.rs b/src/libcore/tests/result.rs index bbc8568517667..1fab07526a07f 100644 --- a/src/libcore/tests/result.rs +++ b/src/libcore/tests/result.rs @@ -117,7 +117,6 @@ fn test_unwrap_or_else() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics pub fn test_unwrap_or_else_panic() { fn handler(msg: &'static str) -> isize { if msg == "I got this." { @@ -139,7 +138,6 @@ pub fn test_expect_ok() { } #[test] #[should_panic(expected="Got expected error: \"All good\"")] -#[cfg(not(miri))] // Miri does not support panics pub fn test_expect_err() { let err: Result = Err("All good"); err.expect("Got expected error"); @@ -153,7 +151,6 @@ pub fn test_expect_err_err() { } #[test] #[should_panic(expected="Got expected ok: \"All good\"")] -#[cfg(not(miri))] // Miri does not support panics pub fn test_expect_err_ok() { let err: Result<&'static str, isize> = Ok("All good"); err.expect_err("Got expected ok"); diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs index 31d16e0e32057..ac9c17a0f7c35 100644 --- a/src/libcore/tests/slice.rs +++ b/src/libcore/tests/slice.rs @@ -782,7 +782,6 @@ mod slice_index { // to be used in `should_panic`) #[test] #[should_panic(expected = "out of range")] - #[cfg(not(miri))] // Miri does not support panics fn assert_range_eq_can_fail_by_panic() { assert_range_eq!([0, 1, 2], 0..5, [0, 1, 2]); } @@ -792,7 +791,6 @@ mod slice_index { // to be used in `should_panic`) #[test] #[should_panic(expected = "==")] - #[cfg(not(miri))] // Miri does not support panics fn assert_range_eq_can_fail_by_inequality() { assert_range_eq!([0, 1, 2], 0..2, [0, 1, 2]); } @@ -842,7 +840,6 @@ mod slice_index { #[test] #[should_panic(expected = $expect_msg)] - #[cfg(not(miri))] // Miri does not support panics fn index_fail() { let v = $data; let v: &[_] = &v; @@ -851,7 +848,6 @@ mod slice_index { #[test] #[should_panic(expected = $expect_msg)] - #[cfg(not(miri))] // Miri does not support panics fn index_mut_fail() { let mut v = $data; let v: &mut [_] = &mut v; @@ -1304,7 +1300,6 @@ fn test_copy_within() { #[test] #[should_panic(expected = "src is out of bounds")] -#[cfg(not(miri))] // Miri does not support panics fn test_copy_within_panics_src_too_long() { let mut bytes = *b"Hello, World!"; // The length is only 13, so 14 is out of bounds. @@ -1313,7 +1308,6 @@ fn test_copy_within_panics_src_too_long() { #[test] #[should_panic(expected = "dest is out of bounds")] -#[cfg(not(miri))] // Miri does not support panics fn test_copy_within_panics_dest_too_long() { let mut bytes = *b"Hello, World!"; // The length is only 13, so a slice of length 4 starting at index 10 is out of bounds. @@ -1321,7 +1315,6 @@ fn test_copy_within_panics_dest_too_long() { } #[test] #[should_panic(expected = "src end is before src start")] -#[cfg(not(miri))] // Miri does not support panics fn test_copy_within_panics_src_inverted() { let mut bytes = *b"Hello, World!"; // 2 is greater than 1, so this range is invalid. diff --git a/src/libcore/tests/time.rs b/src/libcore/tests/time.rs index 09aae4583482f..6efd22572dc18 100644 --- a/src/libcore/tests/time.rs +++ b/src/libcore/tests/time.rs @@ -107,14 +107,12 @@ fn checked_sub() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn sub_bad1() { let _ = Duration::new(0, 0) - Duration::new(0, 1); } #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn sub_bad2() { let _ = Duration::new(0, 0) - Duration::new(1, 0); } diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 96f0beafa005f..ab10536038872 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -2299,6 +2299,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { let span = lifetime_refs[0].span; let mut late_depth = 0; let mut scope = self.scope; + let mut lifetime_names = FxHashSet::default(); let error = loop { match *scope { // Do not assign any resolution, it will be inferred. @@ -2306,12 +2307,18 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { Scope::Root => break None, - Scope::Binder { s, .. } => { + Scope::Binder { s, ref lifetimes, .. } => { + // collect named lifetimes for suggestions + for name in lifetimes.keys() { + if let hir::ParamName::Plain(name) = name { + lifetime_names.insert(*name); + } + } late_depth += 1; scope = s; } - Scope::Elision { ref elide, .. } => { + Scope::Elision { ref elide, ref s, .. } => { let lifetime = match *elide { Elide::FreshLateAnon(ref counter) => { for lifetime_ref in lifetime_refs { @@ -2321,7 +2328,17 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { return; } Elide::Exact(l) => l.shifted(late_depth), - Elide::Error(ref e) => break Some(e), + Elide::Error(ref e) => { + if let Scope::Binder { ref lifetimes, .. } = s { + // collect named lifetimes for suggestions + for name in lifetimes.keys() { + if let hir::ParamName::Plain(name) = name { + lifetime_names.insert(*name); + } + } + } + break Some(e); + } }; for lifetime_ref in lifetime_refs { self.insert_lifetime(lifetime_ref, lifetime); @@ -2344,7 +2361,13 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } } if add_label { - add_missing_lifetime_specifiers_label(&mut err, span, lifetime_refs.len()); + add_missing_lifetime_specifiers_label( + &mut err, + span, + lifetime_refs.len(), + &lifetime_names, + self.tcx.sess.source_map().span_to_snippet(span).ok().as_ref().map(|s| s.as_str()), + ); } err.emit(); @@ -2885,10 +2908,23 @@ fn add_missing_lifetime_specifiers_label( err: &mut DiagnosticBuilder<'_>, span: Span, count: usize, + lifetime_names: &FxHashSet, + snippet: Option<&str>, ) { if count > 1 { err.span_label(span, format!("expected {} lifetime parameters", count)); + } else if let (1, Some(name), Some("&")) = ( + lifetime_names.len(), + lifetime_names.iter().next(), + snippet, + ) { + err.span_suggestion( + span, + "consider using the named lifetime", + format!("&{} ", name), + Applicability::MaybeIncorrect, + ); } else { err.span_label(span, "expected lifetime parameter"); - }; + } } diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 55c4b0e54b822..ff18678f091b9 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -800,6 +800,7 @@ macro_rules! options { pub const parse_opt_pathbuf: Option<&str> = Some("a path"); pub const parse_list: Option<&str> = Some("a space-separated list of strings"); pub const parse_opt_list: Option<&str> = Some("a space-separated list of strings"); + pub const parse_opt_comma_list: Option<&str> = Some("a comma-separated list of strings"); pub const parse_uint: Option<&str> = Some("a number"); pub const parse_passes: Option<&str> = Some("a space-separated list of passes, or `all`"); @@ -926,6 +927,18 @@ macro_rules! options { } } + fn parse_opt_comma_list(slot: &mut Option>, v: Option<&str>) + -> bool { + match v { + Some(s) => { + let v = s.split(',').map(|s| s.to_string()).collect(); + *slot = Some(v); + true + }, + None => false, + } + } + fn parse_uint(slot: &mut usize, v: Option<&str>) -> bool { match v.and_then(|s| s.parse().ok()) { Some(i) => { *slot = i; true }, @@ -1427,6 +1440,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, merge_functions: Option = (None, parse_merge_functions, [TRACKED], "control the operation of the MergeFunctions LLVM pass, taking the same values as the target option of the same name"), + allow_features: Option> = (None, parse_opt_comma_list, [TRACKED], + "only allow the listed language features to be enabled in code (space separated)"), } pub fn default_lib_output() -> CrateType { @@ -3273,6 +3288,10 @@ mod tests { opts = reference.clone(); opts.debugging_opts.merge_functions = Some(MergeFunctions::Disabled); assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); + + opts = reference.clone(); + opts.debugging_opts.allow_features = Some(vec![String::from("lang_items")]); + assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); } #[test] diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index dfe87242c7128..7b6a51c018459 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -1911,7 +1911,6 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { pub fn is_machine(&self) -> bool { match self.sty { - Int(ast::IntTy::Isize) | Uint(ast::UintTy::Usize) => false, Int(..) | Uint(..) | Float(..) => true, _ => false, } diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index 0a295c202e655..c75788ecb4fbd 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -15,7 +15,6 @@ #![allow(unused_attributes)] #![feature(libc)] #![feature(nll)] -#![feature(range_contains)] #![feature(rustc_diagnostic_macros)] #![feature(optin_builtin_traits)] #![feature(concat_idents)] diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs index 1f4c5543fa9aa..e6470dbb61ce1 100644 --- a/src/librustc_codegen_ssa/back/linker.rs +++ b/src/librustc_codegen_ssa/back/linker.rs @@ -382,20 +382,19 @@ impl<'a> Linker for GccLinker<'a> { if self.sess.target.target.options.is_like_osx { // Write a plain, newline-separated list of symbols - let res = (|| -> io::Result<()> { + let res: io::Result<()> = try { let mut f = BufWriter::new(File::create(&path)?); for sym in self.info.exports[&crate_type].iter() { debug!(" _{}", sym); writeln!(f, "_{}", sym)?; } - Ok(()) - })(); + }; if let Err(e) = res { self.sess.fatal(&format!("failed to write lib.def file: {}", e)); } } else { // Write an LD version script - let res = (|| -> io::Result<()> { + let res: io::Result<()> = try { let mut f = BufWriter::new(File::create(&path)?); writeln!(f, "{{\n global:")?; for sym in self.info.exports[&crate_type].iter() { @@ -403,8 +402,7 @@ impl<'a> Linker for GccLinker<'a> { writeln!(f, " {};", sym)?; } writeln!(f, "\n local:\n *;\n}};")?; - Ok(()) - })(); + }; if let Err(e) = res { self.sess.fatal(&format!("failed to write version script: {}", e)); } @@ -644,7 +642,7 @@ impl<'a> Linker for MsvcLinker<'a> { tmpdir: &Path, crate_type: CrateType) { let path = tmpdir.join("lib.def"); - let res = (|| -> io::Result<()> { + let res: io::Result<()> = try { let mut f = BufWriter::new(File::create(&path)?); // Start off with the standard module name header and then go @@ -655,8 +653,7 @@ impl<'a> Linker for MsvcLinker<'a> { debug!(" _{}", symbol); writeln!(f, " {}", symbol)?; } - Ok(()) - })(); + }; if let Err(e) = res { self.sess.fatal(&format!("failed to write lib.def file: {}", e)); } diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs index fec41936a2384..fe9b88c85f009 100644 --- a/src/librustc_codegen_ssa/lib.rs +++ b/src/librustc_codegen_ssa/lib.rs @@ -7,6 +7,7 @@ #![feature(libc)] #![feature(rustc_diagnostic_macros)] #![feature(stmt_expr_attributes)] +#![feature(try_blocks)] #![feature(in_band_lifetimes)] #![feature(nll)] #![allow(unused_attributes)] diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 7c7698ddd3d73..6b4b437930d26 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -2,7 +2,6 @@ #![feature(custom_attribute)] #![allow(unused_attributes)] -#![feature(range_contains)] #![cfg_attr(unix, feature(libc))] #![feature(nll)] #![feature(optin_builtin_traits)] diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 5bb47bda17b33..0c710fd283be8 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -243,6 +243,7 @@ pub fn register_plugins<'a>( krate, &sess.parse_sess, sess.edition(), + &sess.opts.debugging_opts.allow_features, ); // these need to be set "early" so that expansion sees `quote` if enabled. sess.init_features(features); diff --git a/src/librustc_mir/build/matches/simplify.rs b/src/librustc_mir/build/matches/simplify.rs index d60a0941b5979..77978d7d38ff7 100644 --- a/src/librustc_mir/build/matches/simplify.rs +++ b/src/librustc_mir/build/matches/simplify.rs @@ -114,14 +114,12 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { (Some(('\u{0000}' as u128, '\u{10FFFF}' as u128, Size::from_bits(32))), 0) } ty::Int(ity) => { - // FIXME(49937): refactor these bit manipulations into interpret. let size = Integer::from_attr(&tcx, SignedInt(ity)).size(); let max = truncate(u128::max_value(), size); let bias = 1u128 << (size.bits() - 1); (Some((0, max, size)), bias) } ty::Uint(uty) => { - // FIXME(49937): refactor these bit manipulations into interpret. let size = Integer::from_attr(&tcx, UnsignedInt(uty)).size(); let max = truncate(u128::max_value(), size); (Some((0, max, size)), 0) diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs index 586a3fdb907ee..44bcb9de0e157 100644 --- a/src/librustc_mir/hair/pattern/_match.rs +++ b/src/librustc_mir/hair/pattern/_match.rs @@ -172,7 +172,7 @@ use rustc::ty::{self, subst::SubstsRef, Ty, TyCtxt, TypeFoldable, Const}; use rustc::ty::layout::{Integer, IntegerExt, VariantIdx, Size}; use rustc::mir::Field; -use rustc::mir::interpret::{ConstValue, Scalar}; +use rustc::mir::interpret::{ConstValue, Scalar, truncate}; use rustc::util::common::ErrorReported; use syntax::attr::{SignedInt, UnsignedInt}; @@ -678,16 +678,14 @@ fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>, ] } ty::Int(ity) => { - // FIXME(49937): refactor these bit manipulations into interpret. let bits = Integer::from_attr(&cx.tcx, SignedInt(ity)).size().bits() as u128; let min = 1u128 << (bits - 1); - let max = (1u128 << (bits - 1)) - 1; + let max = min - 1; vec![ConstantRange(min, max, pcx.ty, RangeEnd::Included)] } ty::Uint(uty) => { - // FIXME(49937): refactor these bit manipulations into interpret. - let bits = Integer::from_attr(&cx.tcx, UnsignedInt(uty)).size().bits() as u128; - let max = !0u128 >> (128 - bits); + let size = Integer::from_attr(&cx.tcx, UnsignedInt(uty)).size(); + let max = truncate(u128::max_value(), size); vec![ConstantRange(0, max, pcx.ty, RangeEnd::Included)] } _ => { diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index 0b735b4b39cf5..c45e694ebf832 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -14,7 +14,6 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![feature(const_fn)] #![feature(decl_macro)] #![feature(exhaustive_patterns)] -#![feature(range_contains)] #![feature(rustc_diagnostic_macros)] #![feature(rustc_attrs)] #![feature(never_type)] diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 5c9927011a707..895e92a97f3da 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -636,10 +636,9 @@ impl<'a> Resolver<'a> { // but metadata cannot encode gensyms currently, so we create it here. // This is only a guess, two equivalent idents may incorrectly get different gensyms here. let ident = ident.gensym_if_underscore(); - let def_id = def.def_id(); let expansion = Mark::root(); // FIXME(jseyfried) intercrate hygiene match def { - Def::Mod(..) | Def::Enum(..) => { + Def::Mod(def_id) | Def::Enum(def_id) => { let module = self.new_module(parent, ModuleKind::Def(def, ident.name), def_id, @@ -647,13 +646,14 @@ impl<'a> Resolver<'a> { span); self.define(parent, ident, TypeNS, (module, vis, DUMMY_SP, expansion)); } - Def::Variant(..) | Def::TyAlias(..) | Def::ForeignTy(..) => { + Def::Variant(..) | Def::TyAlias(..) | Def::ForeignTy(..) | Def::Existential(..) | + Def::TraitAlias(..) | Def::PrimTy(..) | Def::ToolMod => { self.define(parent, ident, TypeNS, (def, vis, DUMMY_SP, expansion)); } Def::Fn(..) | Def::Static(..) | Def::Const(..) | Def::VariantCtor(..) => { self.define(parent, ident, ValueNS, (def, vis, DUMMY_SP, expansion)); } - Def::StructCtor(..) => { + Def::StructCtor(def_id, ..) => { self.define(parent, ident, ValueNS, (def, vis, DUMMY_SP, expansion)); if let Some(struct_def_id) = @@ -662,7 +662,7 @@ impl<'a> Resolver<'a> { self.struct_constructors.insert(struct_def_id, (def, vis)); } } - Def::Trait(..) => { + Def::Trait(def_id) => { let module_kind = ModuleKind::Def(def, ident.name); let module = self.new_module(parent, module_kind, @@ -683,18 +683,14 @@ impl<'a> Resolver<'a> { } module.populated.set(true); } - Def::Existential(..) | - Def::TraitAlias(..) => { - self.define(parent, ident, TypeNS, (def, vis, DUMMY_SP, expansion)); - } - Def::Struct(..) | Def::Union(..) => { + Def::Struct(def_id) | Def::Union(def_id) => { self.define(parent, ident, TypeNS, (def, vis, DUMMY_SP, expansion)); // Record field names for error reporting. let field_names = self.cstore.struct_field_names_untracked(def_id); self.insert_field_names(def_id, field_names); } - Def::Macro(..) => { + Def::Macro(..) | Def::NonMacroAttr(..) => { self.define(parent, ident, MacroNS, (def, vis, DUMMY_SP, expansion)); } _ => bug!("unexpected definition: {:?}", def) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 1383bf28113d8..fa4bb02189f20 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -5288,6 +5288,53 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { Some(original_span.with_lo(original_span.hi() - BytePos(1))) } + // Rewrite `SelfCtor` to `StructCtor` + pub fn rewrite_self_ctor(&self, def: Def, span: Span) -> (Def, DefId, Ty<'tcx>) { + let tcx = self.tcx; + if let Def::SelfCtor(impl_def_id) = def { + let ty = self.impl_self_ty(span, impl_def_id).ty; + let adt_def = ty.ty_adt_def(); + + match adt_def { + Some(adt_def) if adt_def.has_ctor() => { + let variant = adt_def.non_enum_variant(); + let def = Def::StructCtor(variant.did, variant.ctor_kind); + (def, variant.did, tcx.type_of(variant.did)) + } + _ => { + let mut err = tcx.sess.struct_span_err(span, + "the `Self` constructor can only be used with tuple or unit structs"); + if let Some(adt_def) = adt_def { + match adt_def.adt_kind() { + AdtKind::Enum => { + err.help("did you mean to use one of the enum's variants?"); + }, + AdtKind::Struct | + AdtKind::Union => { + err.span_suggestion( + span, + "use curly brackets", + String::from("Self { /* fields */ }"), + Applicability::HasPlaceholders, + ); + } + } + } + err.emit(); + + (def, impl_def_id, tcx.types.err) + } + } + } else { + let def_id = def.def_id(); + + // The things we are substituting into the type should not contain + // escaping late-bound regions, and nor should the base type scheme. + let ty = tcx.type_of(def_id); + (def, def_id, ty) + } + } + // Instantiates the given path, which must refer to an item with the given // number of type parameters and type. pub fn instantiate_value_path(&self, @@ -5307,6 +5354,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let tcx = self.tcx; + match def { + Def::Local(nid) | Def::Upvar(nid, ..) => { + let hid = self.tcx.hir().node_to_hir_id(nid); + let ty = self.local_ty(span, hid).decl_ty; + let ty = self.normalize_associated_types_in(span, &ty); + self.write_ty(hir_id, ty); + return (ty, def); + } + _ => {} + } + + let (def, def_id, ty) = self.rewrite_self_ctor(def, span); let path_segs = AstConv::def_ids_for_path_segments(self, segments, self_ty, def); let mut user_self_ty = None; @@ -5368,17 +5427,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { user_self_ty = None; } - match def { - Def::Local(nid) | Def::Upvar(nid, ..) => { - let hid = self.tcx.hir().node_to_hir_id(nid); - let ty = self.local_ty(span, hid).decl_ty; - let ty = self.normalize_associated_types_in(span, &ty); - self.write_ty(hir_id, ty); - return (ty, def); - } - _ => {} - } - // Now we have to compare the types that the user *actually* // provided against the types that were *expected*. If the user // did not provide any types, then we want to substitute inference @@ -5411,53 +5459,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { tcx.generics_of(*def_id).has_self }).unwrap_or(false); - let mut new_def = def; - let (def_id, ty) = match def { - Def::SelfCtor(impl_def_id) => { - let ty = self.impl_self_ty(span, impl_def_id).ty; - let adt_def = ty.ty_adt_def(); - - match adt_def { - Some(adt_def) if adt_def.has_ctor() => { - let variant = adt_def.non_enum_variant(); - new_def = Def::StructCtor(variant.did, variant.ctor_kind); - (variant.did, tcx.type_of(variant.did)) - } - _ => { - let mut err = tcx.sess.struct_span_err(span, - "the `Self` constructor can only be used with tuple or unit structs"); - if let Some(adt_def) = adt_def { - match adt_def.adt_kind() { - AdtKind::Enum => { - err.help("did you mean to use one of the enum's variants?"); - }, - AdtKind::Struct | - AdtKind::Union => { - err.span_suggestion( - span, - "use curly brackets", - String::from("Self { /* fields */ }"), - Applicability::HasPlaceholders, - ); - } - } - } - err.emit(); - - (impl_def_id, tcx.types.err) - } - } - } - _ => { - let def_id = def.def_id(); - - // The things we are substituting into the type should not contain - // escaping late-bound regions, and nor should the base type scheme. - let ty = tcx.type_of(def_id); - (def_id, ty) - } - }; - let substs = AstConv::create_substs_for_generic_args( tcx, def_id, @@ -5573,7 +5574,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ty_substituted); self.write_substs(hir_id, substs); - (ty_substituted, new_def) + (ty_substituted, def) } fn check_rustc_args_require_const(&self, diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index b830c90cc434b..fc8ac9a0b3e00 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -221,7 +221,7 @@ #![cfg_attr(test, feature(print_internals, set_stdio, test, update_panic_count))] #![cfg_attr(all(target_vendor = "fortanix", target_env = "sgx"), - feature(global_asm, range_contains, slice_index_methods, + feature(global_asm, slice_index_methods, decl_macro, coerce_unsized, sgx_platform, ptr_wrapping_offset_from))] // std is implemented with unstable features, many of which are internal diff --git a/src/libstd/time.rs b/src/libstd/time.rs index 6d7093ac33ea7..4c86f70ad871d 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -712,13 +712,6 @@ mod tests { assert_almost_eq!(a - second + second, a); assert_almost_eq!(a.checked_sub(second).unwrap().checked_add(second).unwrap(), a); - // A difference of 80 and 800 years cannot fit inside a 32-bit time_t - if !(cfg!(unix) && crate::mem::size_of::() <= 4) { - let eighty_years = second * 60 * 60 * 24 * 365 * 80; - assert_almost_eq!(a - eighty_years + eighty_years, a); - assert_almost_eq!(a - (eighty_years * 10) + (eighty_years * 10), a); - } - let one_second_from_epoch = UNIX_EPOCH + Duration::new(1, 0); let one_second_from_epoch2 = UNIX_EPOCH + Duration::new(0, 500_000_000) + Duration::new(0, 500_000_000); @@ -747,8 +740,8 @@ mod tests { #[test] fn since_epoch() { let ts = SystemTime::now(); - let a = ts.duration_since(UNIX_EPOCH).unwrap(); - let b = ts.duration_since(UNIX_EPOCH - Duration::new(1, 0)).unwrap(); + let a = ts.duration_since(UNIX_EPOCH + Duration::new(1, 0)).unwrap(); + let b = ts.duration_since(UNIX_EPOCH).unwrap(); assert!(b > a); assert_eq!(b - a, Duration::new(1, 0)); diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs index 4e4432a3f334d..2abb7e407eb02 100644 --- a/src/libsyntax/config.rs +++ b/src/libsyntax/config.rs @@ -24,8 +24,8 @@ pub struct StripUnconfigured<'a> { } // `cfg_attr`-process the crate's attributes and compute the crate's features. -pub fn features(mut krate: ast::Crate, sess: &ParseSess, edition: Edition) - -> (ast::Crate, Features) { +pub fn features(mut krate: ast::Crate, sess: &ParseSess, edition: Edition, + allow_features: &Option>) -> (ast::Crate, Features) { let features; { let mut strip_unconfigured = StripUnconfigured { @@ -43,7 +43,7 @@ pub fn features(mut krate: ast::Crate, sess: &ParseSess, edition: Edition) return (krate, Features::new()); } - features = get_features(&sess.span_diagnostic, &krate.attrs, edition); + features = get_features(&sess.span_diagnostic, &krate.attrs, edition, allow_features); // Avoid reconfiguring malformed `cfg_attr`s if err_count == sess.span_diagnostic.err_count() { diff --git a/src/libsyntax/diagnostic_list.rs b/src/libsyntax/diagnostic_list.rs index 2c367f1f40242..ac24475cab89f 100644 --- a/src/libsyntax/diagnostic_list.rs +++ b/src/libsyntax/diagnostic_list.rs @@ -378,6 +378,21 @@ Erroneous code example: "##, +E0725: r##" +A feature attribute named a feature that was disallowed in the compiler +command line flags. + +Erroneous code example: + +```ignore (can't specify compiler flags from doctests) +#![feature(never_type)] // error: the feature `never_type` is not in + // the list of allowed features +``` + +Delete the offending feature attribute, or add it to the list of allowed +features in the `-Z allow_features` flag. +"##, + } register_diagnostics! { diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index b2982629fe6b2..280b17da0be3f 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -2008,7 +2008,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], - crate_edition: Edition) -> Features { + crate_edition: Edition, allow_features: &Option>) -> Features { fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) { let mut err = struct_span_err!(span_handler, span, E0557, "feature has been removed"); if let Some(reason) = reason { @@ -2127,6 +2127,15 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], } if let Some((.., set)) = ACTIVE_FEATURES.iter().find(|f| name == f.0) { + if let Some(allowed) = allow_features.as_ref() { + if allowed.iter().find(|f| *f == name.as_str()).is_none() { + span_err!(span_handler, mi.span, E0725, + "the feature `{}` is not in the list of allowed features", + name); + continue; + } + } + set(&mut features, mi.span); features.declared_lang_features.push((name, mi.span, None)); continue diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index fe31311094b89..22af7d47fd0a1 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -5116,12 +5116,8 @@ impl<'a> Parser<'a> { let ident = self.parse_ident()?; let (delim, tokens) = self.expect_delimited_token_tree()?; - if delim != MacDelimiter::Brace { - if !self.eat(&token::Semi) { - let msg = "macros that expand to items must either \ - be surrounded with braces or followed by a semicolon"; - self.span_err(self.prev_span, msg); - } + if delim != MacDelimiter::Brace && !self.eat(&token::Semi) { + self.report_invalid_macro_expansion_item(); } (ident, ast::MacroDef { tokens: tokens, legacy: true }) @@ -5264,13 +5260,8 @@ impl<'a> Parser<'a> { // if it has a special ident, it's definitely an item // // Require a semicolon or braces. - if style != MacStmtStyle::Braces { - if !self.eat(&token::Semi) { - self.span_err(self.prev_span, - "macros that expand to items must \ - either be surrounded with braces or \ - followed by a semicolon"); - } + if style != MacStmtStyle::Braces && !self.eat(&token::Semi) { + self.report_invalid_macro_expansion_item(); } let span = lo.to(hi); Stmt { @@ -8360,13 +8351,8 @@ impl<'a> Parser<'a> { }; // eat a matched-delimiter token tree: let (delim, tts) = self.expect_delimited_token_tree()?; - if delim != MacDelimiter::Brace { - if !self.eat(&token::Semi) { - self.span_err(self.prev_span, - "macros that expand to items must either \ - be surrounded with braces or followed by \ - a semicolon"); - } + if delim != MacDelimiter::Brace && !self.eat(&token::Semi) { + self.report_invalid_macro_expansion_item(); } let hi = self.prev_span; @@ -8597,6 +8583,25 @@ impl<'a> Parser<'a> { } } } + + fn report_invalid_macro_expansion_item(&self) { + self.struct_span_err( + self.prev_span, + "macros that expand to items must be delimited with braces or followed by a semicolon", + ).multipart_suggestion( + "change the delimiters to curly braces", + vec![ + (self.prev_span.with_hi(self.prev_span.lo() + BytePos(1)), String::from(" {")), + (self.prev_span.with_lo(self.prev_span.hi() - BytePos(1)), '}'.to_string()), + ], + Applicability::MaybeIncorrect, + ).span_suggestion( + self.sess.source_map.next_point(self.prev_span), + "add a semicolon", + ';'.to_string(), + Applicability::MaybeIncorrect, + ).emit(); + } } pub fn emit_unclosed_delims(unclosed_delims: &mut Vec, handler: &errors::Handler) { diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs index 4ce308d015c00..80a7bde606afa 100644 --- a/src/libsyntax/tokenstream.rs +++ b/src/libsyntax/tokenstream.rs @@ -178,9 +178,11 @@ impl TokenStream { while let Some((pos, ts)) = iter.next() { if let Some((_, next)) = iter.peek() { let sp = match (&ts, &next) { - ((TokenTree::Token(_, token::Token::Comma), NonJoint), _) | - (_, (TokenTree::Token(_, token::Token::Comma), NonJoint)) => continue, - ((TokenTree::Token(sp, _), NonJoint), _) => *sp, + (_, (TokenTree::Token(_, token::Token::Comma), _)) => continue, + ((TokenTree::Token(sp, token_left), NonJoint), + (TokenTree::Token(_, token_right), _)) + if (token_left.is_ident() || token_left.is_lit()) && + (token_right.is_ident() || token_right.is_lit()) => *sp, ((TokenTree::Delimited(sp, ..), NonJoint), _) => sp.entire(), _ => continue, }; diff --git a/src/test/run-pass/array-slice-vec/estr-slice.rs b/src/test/run-pass/array-slice-vec/estr-slice.rs index 02b88f6a7abfc..cd2c17220655a 100644 --- a/src/test/run-pass/array-slice-vec/estr-slice.rs +++ b/src/test/run-pass/array-slice-vec/estr-slice.rs @@ -14,7 +14,7 @@ pub fn main() { let z : &str = "thing"; assert_eq!(v, x); - assert!(x != z); + assert_ne!(x, z); let a = "aaaa"; let b = "bbbb"; @@ -26,7 +26,7 @@ pub fn main() { assert!(a < b); assert!(a <= b); - assert!(a != b); + assert_ne!(a, b); assert!(b >= a); assert!(b > a); @@ -34,7 +34,7 @@ pub fn main() { assert!(a < c); assert!(a <= c); - assert!(a != c); + assert_ne!(a, c); assert!(c >= a); assert!(c > a); @@ -42,7 +42,7 @@ pub fn main() { assert!(c < cc); assert!(c <= cc); - assert!(c != cc); + assert_ne!(c, cc); assert!(cc >= c); assert!(cc > c); diff --git a/src/test/run-pass/issue-55809.rs b/src/test/run-pass/issue-55809.rs new file mode 100644 index 0000000000000..86b0977bebe1d --- /dev/null +++ b/src/test/run-pass/issue-55809.rs @@ -0,0 +1,30 @@ +// edition:2018 +// run-pass + +#![feature(async_await, await_macro, futures_api)] + +trait Foo { } + +impl Foo for () { } + +impl<'a, T> Foo for &'a mut T where T: Foo { } + +async fn foo_async(_v: T) -> u8 where T: Foo { + 0 +} + +async fn bad(v: T) -> u8 where T: Foo { + await!(foo_async(v)) +} + +async fn async_main() { + let mut v = (); + + let _ = await!(bad(&mut v)); + let _ = await!(foo_async(&mut v)); + let _ = await!(bad(v)); +} + +fn main() { + let _ = async_main(); +} diff --git a/src/test/run-pass/issues/issue-57924.rs b/src/test/run-pass/issues/issue-57924.rs new file mode 100644 index 0000000000000..232596334b0ed --- /dev/null +++ b/src/test/run-pass/issues/issue-57924.rs @@ -0,0 +1,9 @@ +pub struct Gcm(E); + +impl Gcm { + pub fn crash(e: E) -> Self { + Self::(e) + } +} + +fn main() {} diff --git a/src/test/run-pass/simd/simd-size-align.rs b/src/test/run-pass/simd/simd-size-align.rs index 0a537071a3c63..556013788c335 100644 --- a/src/test/run-pass/simd/simd-size-align.rs +++ b/src/test/run-pass/simd/simd-size-align.rs @@ -37,6 +37,22 @@ fn main() { check::(); check::(); check::(); + + check::(); + check::(); + check::(); + check::(); + check::(); + check::(); + check::(); + + check::(); + check::(); + check::(); + check::(); + check::(); + check::(); + check::(); } #[repr(simd)] struct u8x2(u8, u8); @@ -62,3 +78,19 @@ fn main() { #[repr(simd)] struct f32x6(f32, f32, f32, f32, f32, f32); #[repr(simd)] struct f32x7(f32, f32, f32, f32, f32, f32, f32); #[repr(simd)] struct f32x8(f32, f32, f32, f32, f32, f32, f32, f32); + +#[repr(simd)] struct usizex2(usize, usize); +#[repr(simd)] struct usizex3(usize, usize, usize); +#[repr(simd)] struct usizex4(usize, usize, usize, usize); +#[repr(simd)] struct usizex5(usize, usize, usize, usize, usize); +#[repr(simd)] struct usizex6(usize, usize, usize, usize, usize, usize); +#[repr(simd)] struct usizex7(usize, usize, usize, usize, usize, usize, usize); +#[repr(simd)] struct usizex8(usize, usize, usize, usize, usize, usize, usize, usize); + +#[repr(simd)] struct isizex2(isize, isize); +#[repr(simd)] struct isizex3(isize, isize, isize); +#[repr(simd)] struct isizex4(isize, isize, isize, isize); +#[repr(simd)] struct isizex5(isize, isize, isize, isize, isize); +#[repr(simd)] struct isizex6(isize, isize, isize, isize, isize, isize); +#[repr(simd)] struct isizex7(isize, isize, isize, isize, isize, isize, isize); +#[repr(simd)] struct isizex8(isize, isize, isize, isize, isize, isize, isize, isize); diff --git a/src/test/ui/feature-gate/allow-features-empty.rs b/src/test/ui/feature-gate/allow-features-empty.rs new file mode 100644 index 0000000000000..83250052cb506 --- /dev/null +++ b/src/test/ui/feature-gate/allow-features-empty.rs @@ -0,0 +1,10 @@ +// compile-flags: -Z allow_features= +// Note: This test uses rustc internal flags because they will never stabilize. + +#![feature(rustc_diagnostic_macros)] //~ ERROR + +#![feature(rustc_const_unstable)] //~ ERROR + +#![feature(lang_items)] //~ ERROR + +fn main() {} diff --git a/src/test/ui/feature-gate/allow-features-empty.stderr b/src/test/ui/feature-gate/allow-features-empty.stderr new file mode 100644 index 0000000000000..cce2c4078c242 --- /dev/null +++ b/src/test/ui/feature-gate/allow-features-empty.stderr @@ -0,0 +1,21 @@ +error[E0725]: the feature `rustc_diagnostic_macros` is not in the list of allowed features + --> $DIR/allow-features-empty.rs:4:12 + | +LL | #![feature(rustc_diagnostic_macros)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0725]: the feature `rustc_const_unstable` is not in the list of allowed features + --> $DIR/allow-features-empty.rs:6:12 + | +LL | #![feature(rustc_const_unstable)] + | ^^^^^^^^^^^^^^^^^^^^ + +error[E0725]: the feature `lang_items` is not in the list of allowed features + --> $DIR/allow-features-empty.rs:8:12 + | +LL | #![feature(lang_items)] + | ^^^^^^^^^^ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0725`. diff --git a/src/test/ui/feature-gate/allow-features.rs b/src/test/ui/feature-gate/allow-features.rs new file mode 100644 index 0000000000000..1cebc8f34f26f --- /dev/null +++ b/src/test/ui/feature-gate/allow-features.rs @@ -0,0 +1,10 @@ +// compile-flags: -Z allow_features=rustc_diagnostic_macros,lang_items +// Note: This test uses rustc internal flags because they will never stabilize. + +#![feature(rustc_diagnostic_macros)] + +#![feature(rustc_const_unstable)] //~ ERROR + +#![feature(lang_items)] + +fn main() {} diff --git a/src/test/ui/feature-gate/allow-features.stderr b/src/test/ui/feature-gate/allow-features.stderr new file mode 100644 index 0000000000000..b13560fb81c6a --- /dev/null +++ b/src/test/ui/feature-gate/allow-features.stderr @@ -0,0 +1,9 @@ +error[E0725]: the feature `rustc_const_unstable` is not in the list of allowed features + --> $DIR/allow-features.rs:6:12 + | +LL | #![feature(rustc_const_unstable)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0725`. diff --git a/src/test/ui/issues/issue-10536.rs b/src/test/ui/issues/issue-10536.rs index 95c8c2b0585b6..ceb44ecf7f583 100644 --- a/src/test/ui/issues/issue-10536.rs +++ b/src/test/ui/issues/issue-10536.rs @@ -12,7 +12,7 @@ pub fn main() { foo!(); assert!({one! two()}); - //~^ ERROR macros that expand to items must either be surrounded with braces or followed by a + //~^ ERROR macros that expand to items //~| ERROR cannot find macro `one!` in this scope //~| ERROR mismatched types diff --git a/src/test/ui/issues/issue-10536.stderr b/src/test/ui/issues/issue-10536.stderr index d5caf777cd45e..584cdf43a8f4b 100644 --- a/src/test/ui/issues/issue-10536.stderr +++ b/src/test/ui/issues/issue-10536.stderr @@ -1,8 +1,16 @@ -error: macros that expand to items must either be surrounded with braces or followed by a semicolon +error: macros that expand to items must be delimited with braces or followed by a semicolon --> $DIR/issue-10536.rs:14:22 | LL | assert!({one! two()}); | ^^ +help: change the delimiters to curly braces + | +LL | assert!({one! two {}}); + | ^^ +help: add a semicolon + | +LL | assert!({one! two();}); + | ^ error: expected `(` or `{`, found `}` --> $DIR/issue-10536.rs:21:22 diff --git a/src/test/ui/macros/missing-comma.rs b/src/test/ui/macros/missing-comma.rs index 1e146875bcc76..2b411aba8a2ee 100644 --- a/src/test/ui/macros/missing-comma.rs +++ b/src/test/ui/macros/missing-comma.rs @@ -6,6 +6,11 @@ macro_rules! foo { ($a:ident, $b:ident, $c:ident, $d:ident, $e:ident) => (); } +macro_rules! bar { + ($lvl:expr, $($arg:tt)+) => {} +} + + fn main() { println!("{}" a); //~^ ERROR expected token: `,` @@ -17,4 +22,6 @@ fn main() { //~^ ERROR no rules expected the token `d` foo!(a, b, c d e); //~^ ERROR no rules expected the token `d` + bar!(Level::Error, ); + //~^ ERROR unexpected end of macro invocation } diff --git a/src/test/ui/macros/missing-comma.stderr b/src/test/ui/macros/missing-comma.stderr index 5881e0b7b68c6..424fefd00f873 100644 --- a/src/test/ui/macros/missing-comma.stderr +++ b/src/test/ui/macros/missing-comma.stderr @@ -1,11 +1,11 @@ error: expected token: `,` - --> $DIR/missing-comma.rs:10:19 + --> $DIR/missing-comma.rs:15:19 | LL | println!("{}" a); | ^ error: no rules expected the token `b` - --> $DIR/missing-comma.rs:12:12 + --> $DIR/missing-comma.rs:17:12 | LL | macro_rules! foo { | ---------------- when calling this macro @@ -16,7 +16,7 @@ LL | foo!(a b); | help: missing comma here error: no rules expected the token `e` - --> $DIR/missing-comma.rs:14:21 + --> $DIR/missing-comma.rs:19:21 | LL | macro_rules! foo { | ---------------- when calling this macro @@ -27,7 +27,7 @@ LL | foo!(a, b, c, d e); | help: missing comma here error: no rules expected the token `d` - --> $DIR/missing-comma.rs:16:18 + --> $DIR/missing-comma.rs:21:18 | LL | macro_rules! foo { | ---------------- when calling this macro @@ -38,7 +38,7 @@ LL | foo!(a, b, c d, e); | help: missing comma here error: no rules expected the token `d` - --> $DIR/missing-comma.rs:18:18 + --> $DIR/missing-comma.rs:23:18 | LL | macro_rules! foo { | ---------------- when calling this macro @@ -46,5 +46,14 @@ LL | macro_rules! foo { LL | foo!(a, b, c d e); | ^ no rules expected this token in macro call -error: aborting due to 5 previous errors +error: unexpected end of macro invocation + --> $DIR/missing-comma.rs:25:23 + | +LL | macro_rules! bar { + | ---------------- when calling this macro +... +LL | bar!(Level::Error, ); + | ^ missing tokens in macro arguments + +error: aborting due to 6 previous errors diff --git a/src/test/ui/nll/user-annotations/issue-55748-pat-types-constrain-bindings.rs b/src/test/ui/nll/user-annotations/issue-55748-pat-types-constrain-bindings.rs new file mode 100644 index 0000000000000..3d042d442d531 --- /dev/null +++ b/src/test/ui/nll/user-annotations/issue-55748-pat-types-constrain-bindings.rs @@ -0,0 +1,70 @@ +// This test is ensuring that type ascriptions on let bindings +// constrain both: +// +// 1. the input expression on the right-hand side (after any potential +// coercion, and allowing for covariance), *and* +// +// 2. the bindings (if any) nested within the pattern on the left-hand +// side (and here, the type-constraint is *invariant*). + +#![feature(nll)] + +#![allow(dead_code, unused_mut)] +type PairUncoupled<'a, 'b, T> = (&'a T, &'b T); +type PairCoupledRegions<'a, T> = (&'a T, &'a T); +type PairCoupledTypes = (T, T); + +fn uncoupled_lhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + let ((mut y, mut _z),): (PairUncoupled,) = ((s, &_x),); // ok + // Above compiling does *not* imply below would compile. + // ::std::mem::swap(&mut y, &mut _z); + y +} + +fn swap_regions((mut y, mut _z): PairCoupledRegions) { + ::std::mem::swap(&mut y, &mut _z); +} + +fn coupled_regions_lhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + let ((y, _z),): (PairCoupledRegions,) = ((s, &_x),); + // If above line compiled, so should line below ... + + // swap_regions((y, _z)); + + // ... but the ascribed type also invalidates this use of `y` + y //~ ERROR lifetime may not live long enough +} + +fn swap_types((mut y, mut _z): PairCoupledTypes<&u32>) { + ::std::mem::swap(&mut y, &mut _z); +} + +fn coupled_types_lhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + let ((y, _z),): (PairCoupledTypes<&u32>,) = ((s, &_x),); + // If above line compiled, so should line below ... + + // swap_types((y, _z)); + + // ... but the ascribed type also invalidates this use of `y` + y //~ ERROR lifetime may not live long enough +} + +fn swap_wilds((mut y, mut _z): PairCoupledTypes<&u32>) { + ::std::mem::swap(&mut y, &mut _z); +} + +fn coupled_wilds_lhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + let ((y, _z),): (PairCoupledTypes<_>,) = ((s, &_x),); + // If above line compiled, so should line below + // swap_wilds((y, _z)); + + // ... but the ascribed type also invalidates this use of `y` + y //~ ERROR lifetime may not live long enough +} + +fn main() { + uncoupled_lhs(&3, &4); + coupled_regions_lhs(&3, &4); + coupled_types_lhs(&3, &4); + coupled_wilds_lhs(&3, &4); +} diff --git a/src/test/ui/nll/user-annotations/issue-55748-pat-types-constrain-bindings.stderr b/src/test/ui/nll/user-annotations/issue-55748-pat-types-constrain-bindings.stderr new file mode 100644 index 0000000000000..5929707e41e10 --- /dev/null +++ b/src/test/ui/nll/user-annotations/issue-55748-pat-types-constrain-bindings.stderr @@ -0,0 +1,29 @@ +error: lifetime may not live long enough + --> $DIR/issue-55748-pat-types-constrain-bindings.rs:35:5 + | +LL | fn coupled_regions_lhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + | -- lifetime `'a` defined here +... +LL | y + | ^ returning this value requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/issue-55748-pat-types-constrain-bindings.rs:49:5 + | +LL | fn coupled_types_lhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + | -- lifetime `'a` defined here +... +LL | y + | ^ returning this value requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/issue-55748-pat-types-constrain-bindings.rs:62:5 + | +LL | fn coupled_wilds_lhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + | -- lifetime `'a` defined here +... +LL | y + | ^ returning this value requires that `'a` must outlive `'static` + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/parser/macros-no-semicolon-items.rs b/src/test/ui/parser/macros-no-semicolon-items.rs index a727cafcab023..3afc275d61a2b 100644 --- a/src/test/ui/parser/macros-no-semicolon-items.rs +++ b/src/test/ui/parser/macros-no-semicolon-items.rs @@ -1,4 +1,15 @@ macro_rules! foo() //~ ERROR semicolon + //~| ERROR unexpected end of macro + +macro_rules! bar { + ($($tokens:tt)*) => {} +} + +bar!( //~ ERROR semicolon + blah + blah + blah +) fn main() { } diff --git a/src/test/ui/parser/macros-no-semicolon-items.stderr b/src/test/ui/parser/macros-no-semicolon-items.stderr index a869a53c1eee2..5276aa6f5e9e9 100644 --- a/src/test/ui/parser/macros-no-semicolon-items.stderr +++ b/src/test/ui/parser/macros-no-semicolon-items.stderr @@ -1,8 +1,45 @@ -error: macros that expand to items must either be surrounded with braces or followed by a semicolon +error: macros that expand to items must be delimited with braces or followed by a semicolon --> $DIR/macros-no-semicolon-items.rs:1:17 | LL | macro_rules! foo() | ^^ +help: change the delimiters to curly braces + | +LL | macro_rules! foo {} + | ^^ +help: add a semicolon + | +LL | macro_rules! foo(); + | ^ + +error: macros that expand to items must be delimited with braces or followed by a semicolon + --> $DIR/macros-no-semicolon-items.rs:8:5 + | +LL | bar!( + | _____^ +LL | | blah +LL | | blah +LL | | blah +LL | | ) + | |_^ +help: change the delimiters to curly braces + | +LL | bar! { +LL | blah +LL | blah +LL | blah +LL | } + | +help: add a semicolon + | +LL | ); + | ^ + +error: unexpected end of macro invocation + --> $DIR/macros-no-semicolon-items.rs:1:1 + | +LL | macro_rules! foo() + | ^^^^^^^^^^^^^^^^^^ missing tokens in macro arguments -error: aborting due to previous error +error: aborting due to 3 previous errors diff --git a/src/test/ui/rust-2018/uniform-paths/auxiliary/cross-crate.rs b/src/test/ui/rust-2018/uniform-paths/auxiliary/cross-crate.rs new file mode 100644 index 0000000000000..4aa5d1870000d --- /dev/null +++ b/src/test/ui/rust-2018/uniform-paths/auxiliary/cross-crate.rs @@ -0,0 +1,5 @@ +// edition:2018 + +pub use ignore as built_in_attr; +pub use u8 as built_in_type; +pub use rustfmt as tool_mod; diff --git a/src/test/ui/rust-2018/uniform-paths/cross-crate.rs b/src/test/ui/rust-2018/uniform-paths/cross-crate.rs new file mode 100644 index 0000000000000..27d6dbf4683e3 --- /dev/null +++ b/src/test/ui/rust-2018/uniform-paths/cross-crate.rs @@ -0,0 +1,11 @@ +// edition:2018 +// aux-build:cross-crate.rs + +extern crate cross_crate; +use cross_crate::*; + +#[built_in_attr] //~ ERROR cannot use a built-in attribute through an import +#[tool_mod::skip] //~ ERROR cannot use a tool module through an import +fn main() { + let _: built_in_type; // OK +} diff --git a/src/test/ui/rust-2018/uniform-paths/cross-crate.stderr b/src/test/ui/rust-2018/uniform-paths/cross-crate.stderr new file mode 100644 index 0000000000000..ccf66b54c529c --- /dev/null +++ b/src/test/ui/rust-2018/uniform-paths/cross-crate.stderr @@ -0,0 +1,26 @@ +error: cannot use a built-in attribute through an import + --> $DIR/cross-crate.rs:7:3 + | +LL | #[built_in_attr] //~ ERROR cannot use a built-in attribute through an import + | ^^^^^^^^^^^^^ + | +note: the built-in attribute imported here + --> $DIR/cross-crate.rs:5:5 + | +LL | use cross_crate::*; + | ^^^^^^^^^^^^^^ + +error: cannot use a tool module through an import + --> $DIR/cross-crate.rs:8:3 + | +LL | #[tool_mod::skip] //~ ERROR cannot use a tool module through an import + | ^^^^^^^^ + | +note: the tool module imported here + --> $DIR/cross-crate.rs:5:5 + | +LL | use cross_crate::*; + | ^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/simd-type.rs b/src/test/ui/simd-type.rs index d1e2efa6a3331..9e4b7e7656055 100644 --- a/src/test/ui/simd-type.rs +++ b/src/test/ui/simd-type.rs @@ -7,7 +7,4 @@ struct empty; //~ ERROR SIMD vector cannot be empty #[repr(simd)] struct i64f64(i64, f64); //~ ERROR SIMD vector should be homogeneous -#[repr(simd)] -struct int4(isize, isize, isize, isize); //~ ERROR SIMD vector element type should be machine type - fn main() {} diff --git a/src/test/ui/simd-type.stderr b/src/test/ui/simd-type.stderr index 027afcb981a0d..48b9916e89d98 100644 --- a/src/test/ui/simd-type.stderr +++ b/src/test/ui/simd-type.stderr @@ -10,13 +10,7 @@ error[E0076]: SIMD vector should be homogeneous LL | struct i64f64(i64, f64); | ^^^^^^^^^^^^^^^^^^^^^^^^ SIMD elements must have the same type -error[E0077]: SIMD vector element type should be machine type - --> $DIR/simd-type.rs:11:1 - | -LL | struct int4(isize, isize, isize, isize); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors occurred: E0075, E0076, E0077. +Some errors occurred: E0075, E0076. For more information about an error, try `rustc --explain E0075`. diff --git a/src/test/ui/suggestions/return-without-lifetime.rs b/src/test/ui/suggestions/return-without-lifetime.rs new file mode 100644 index 0000000000000..9bfce11be9ea3 --- /dev/null +++ b/src/test/ui/suggestions/return-without-lifetime.rs @@ -0,0 +1,10 @@ +struct Thing<'a>(&'a ()); +struct Foo<'a>(&usize); +//~^ ERROR missing lifetime specifier + +fn func1<'a>(_arg: &'a Thing) -> &() { unimplemented!() } +//~^ ERROR missing lifetime specifier +fn func2<'a>(_arg: &Thing<'a>) -> &() { unimplemented!() } +//~^ ERROR missing lifetime specifier + +fn main() {} diff --git a/src/test/ui/suggestions/return-without-lifetime.stderr b/src/test/ui/suggestions/return-without-lifetime.stderr new file mode 100644 index 0000000000000..7f5ff95938e30 --- /dev/null +++ b/src/test/ui/suggestions/return-without-lifetime.stderr @@ -0,0 +1,25 @@ +error[E0106]: missing lifetime specifier + --> $DIR/return-without-lifetime.rs:2:16 + | +LL | struct Foo<'a>(&usize); + | ^ help: consider using the named lifetime: `&'a` + +error[E0106]: missing lifetime specifier + --> $DIR/return-without-lifetime.rs:5:34 + | +LL | fn func1<'a>(_arg: &'a Thing) -> &() { unimplemented!() } + | ^ help: consider using the named lifetime: `&'a` + | + = help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from + +error[E0106]: missing lifetime specifier + --> $DIR/return-without-lifetime.rs:7:35 + | +LL | fn func2<'a>(_arg: &Thing<'a>) -> &() { unimplemented!() } + | ^ help: consider using the named lifetime: `&'a` + | + = help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0106`. diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index d44a51a9635e9..f0b8ab13dc567 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -32,6 +32,7 @@ static HOSTS: &'static [&'static str] = &[ "x86_64-pc-windows-msvc", "x86_64-unknown-freebsd", "x86_64-unknown-linux-gnu", + "x86_64-unknown-linux-musl", "x86_64-unknown-netbsd", ];