From 4837fb45ff41ad8ff4c6dfc9bd3f8056959f3d4e Mon Sep 17 00:00:00 2001 From: Adrian Friedli Date: Sat, 16 Feb 2019 22:34:28 +0100 Subject: implement nth_back for Box --- src/liballoc/boxed.rs | 3 +++ src/liballoc/lib.rs | 1 + 2 files changed, 4 insertions(+) (limited to 'src/liballoc') diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 51549f92d4d..1e3ccf90eb8 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -662,6 +662,9 @@ impl DoubleEndedIterator for Box { fn next_back(&mut self) -> Option { (**self).next_back() } + fn nth_back(&mut self, n: usize) -> Option { + (**self).nth_back(n) + } } #[stable(feature = "rust1", since = "1.0.0")] impl ExactSizeIterator for Box { diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 95b9dacf856..da1afc2ff8a 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -115,6 +115,7 @@ #![feature(maybe_uninit)] #![feature(alloc_layout_extra)] #![feature(try_trait)] +#![feature(iter_nth_back)] // Allow testing this library -- cgit 1.4.1-3-g733a5 From 2b49ec0bb676f324806bb271f4115c3a1c0afaf3 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Tue, 5 Mar 2019 09:58:47 +0100 Subject: Move alloc::prelude::* to alloc::prelude::v1, make alloc a subset of std This was one of the unresolved questions of https://github.com/rust-lang/rfcs/pull/2480. As the RFC says this is maybe not useful in the sense that we are unlikely to ever have a second version, but making the crate a true subset makes one less issue to think about if we stabilize it and later want to merge standard library crates and have Cargo feature flags to enable or disable parts of the `std` crate. See also discussion in https://github.com/rust-lang/rust/pull/58175 --- src/liballoc/prelude.rs | 19 ------------------- src/liballoc/prelude/mod.rs | 15 +++++++++++++++ src/liballoc/prelude/v1.rs | 11 +++++++++++ 3 files changed, 26 insertions(+), 19 deletions(-) delete mode 100644 src/liballoc/prelude.rs create mode 100644 src/liballoc/prelude/mod.rs create mode 100644 src/liballoc/prelude/v1.rs (limited to 'src/liballoc') diff --git a/src/liballoc/prelude.rs b/src/liballoc/prelude.rs deleted file mode 100644 index 6767cf89f73..00000000000 --- a/src/liballoc/prelude.rs +++ /dev/null @@ -1,19 +0,0 @@ -//! The alloc Prelude -//! -//! The purpose of this module is to alleviate imports of commonly-used -//! items of the `alloc` crate by adding a glob import to the top of modules: -//! -//! ``` -//! # #![allow(unused_imports)] -//! # #![feature(alloc)] -//! extern crate alloc; -//! use alloc::prelude::*; -//! ``` - -#![unstable(feature = "alloc", issue = "27783")] - -#[unstable(feature = "alloc", issue = "27783")] pub use crate::borrow::ToOwned; -#[unstable(feature = "alloc", issue = "27783")] pub use crate::boxed::Box; -#[unstable(feature = "alloc", issue = "27783")] pub use crate::slice::SliceConcatExt; -#[unstable(feature = "alloc", issue = "27783")] pub use crate::string::{String, ToString}; -#[unstable(feature = "alloc", issue = "27783")] pub use crate::vec::Vec; diff --git a/src/liballoc/prelude/mod.rs b/src/liballoc/prelude/mod.rs new file mode 100644 index 00000000000..44a859d31ec --- /dev/null +++ b/src/liballoc/prelude/mod.rs @@ -0,0 +1,15 @@ +//! The alloc Prelude +//! +//! The purpose of this module is to alleviate imports of commonly-used +//! items of the `alloc` crate by adding a glob import to the top of modules: +//! +//! ``` +//! # #![allow(unused_imports)] +//! # #![feature(alloc)] +//! extern crate alloc; +//! use alloc::prelude::v1::*; +//! ``` + +#![unstable(feature = "alloc", issue = "27783")] + +pub mod v1; diff --git a/src/liballoc/prelude/v1.rs b/src/liballoc/prelude/v1.rs new file mode 100644 index 00000000000..2df330d19f8 --- /dev/null +++ b/src/liballoc/prelude/v1.rs @@ -0,0 +1,11 @@ +//! The first version of the prelude of `alloc` crate. +//! +//! See the [module-level documentation](../index.html) for more. + +#![unstable(feature = "alloc", issue = "27783")] + +#[unstable(feature = "alloc", issue = "27783")] pub use crate::borrow::ToOwned; +#[unstable(feature = "alloc", issue = "27783")] pub use crate::boxed::Box; +#[unstable(feature = "alloc", issue = "27783")] pub use crate::slice::SliceConcatExt; +#[unstable(feature = "alloc", issue = "27783")] pub use crate::string::{String, ToString}; +#[unstable(feature = "alloc", issue = "27783")] pub use crate::vec::Vec; -- cgit 1.4.1-3-g733a5 From 5d1022ad7b82168aee243d2adcbd83d1e886586f Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Tue, 5 Mar 2019 11:47:52 +0100 Subject: Rename the feature gate for alloc::prelude MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … to separate it from that of the crate. New tracking issue: https://github.com/rust-lang/rust/issues/58935 --- src/liballoc/prelude/mod.rs | 3 ++- src/liballoc/prelude/v1.rs | 12 ++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/prelude/mod.rs b/src/liballoc/prelude/mod.rs index 44a859d31ec..33cc51d1732 100644 --- a/src/liballoc/prelude/mod.rs +++ b/src/liballoc/prelude/mod.rs @@ -6,10 +6,11 @@ //! ``` //! # #![allow(unused_imports)] //! # #![feature(alloc)] +//! #![feature(alloc_prelude)] //! extern crate alloc; //! use alloc::prelude::v1::*; //! ``` -#![unstable(feature = "alloc", issue = "27783")] +#![unstable(feature = "alloc_prelude", issue = "58935")] pub mod v1; diff --git a/src/liballoc/prelude/v1.rs b/src/liballoc/prelude/v1.rs index 2df330d19f8..b6b01395ad6 100644 --- a/src/liballoc/prelude/v1.rs +++ b/src/liballoc/prelude/v1.rs @@ -2,10 +2,10 @@ //! //! See the [module-level documentation](../index.html) for more. -#![unstable(feature = "alloc", issue = "27783")] +#![unstable(feature = "alloc_prelude", issue = "58935")] -#[unstable(feature = "alloc", issue = "27783")] pub use crate::borrow::ToOwned; -#[unstable(feature = "alloc", issue = "27783")] pub use crate::boxed::Box; -#[unstable(feature = "alloc", issue = "27783")] pub use crate::slice::SliceConcatExt; -#[unstable(feature = "alloc", issue = "27783")] pub use crate::string::{String, ToString}; -#[unstable(feature = "alloc", issue = "27783")] pub use crate::vec::Vec; +#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::borrow::ToOwned; +#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::boxed::Box; +#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::slice::SliceConcatExt; +#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::string::{String, ToString}; +#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::vec::Vec; -- cgit 1.4.1-3-g733a5 From 4888b1fb99f1bf6a58bebaededdfbf4477383634 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 10 Mar 2019 17:45:45 +0100 Subject: we can now skip should_panic tests with the libtest harness --- src/liballoc/tests/binary_heap.rs | 2 +- src/liballoc/tests/btree/map.rs | 5 ----- src/liballoc/tests/slice.rs | 18 ------------------ src/liballoc/tests/str.rs | 11 ----------- src/liballoc/tests/string.rs | 9 --------- src/liballoc/tests/vec.rs | 12 ------------ src/liballoc/tests/vec_deque.rs | 1 - src/libcore/tests/cell.rs | 3 --- src/libcore/tests/iter.rs | 2 -- src/libcore/tests/num/bignum.rs | 14 -------------- src/libcore/tests/option.rs | 3 --- src/libcore/tests/result.rs | 3 --- src/libcore/tests/slice.rs | 7 ------- src/libcore/tests/time.rs | 2 -- 14 files changed, 1 insertion(+), 91 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/tests/binary_heap.rs b/src/liballoc/tests/binary_heap.rs index 1d4a3edc1ac..a97a790f5a2 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 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 f14750089c9..844afe87076 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 feba46b0fad..fb99c95fc68 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,6 @@ 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 fn test_box_slice_clone_panics() { use std::sync::Arc; use std::sync::atomic::{AtomicUsize, Ordering}; @@ -1476,7 +1461,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 +1469,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 +1588,6 @@ 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 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 b33a5642188..f2dc19a4229 100644 --- a/src/liballoc/tests/str.rs +++ b/src/liballoc/tests/str.rs @@ -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 7e93d84fe3b..7e75b8c4f28 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 6e4ca1d90e6..545332bcd6a 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 16ddc1444fc..e0fe10a55f5 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/tests/cell.rs b/src/libcore/tests/cell.rs index b16416022c0..56f295dff8e 100644 --- a/src/libcore/tests/cell.rs +++ b/src/libcore/tests/cell.rs @@ -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 d880abb181c..4652fc329dc 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(); @@ -1414,7 +1413,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 956c22c9982..b873f1dd065 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/option.rs b/src/libcore/tests/option.rs index 87ce2720c59..b059b134868 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 bbc85685176..1fab07526a0 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 31d16e0e320..ac9c17a0f7c 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 09aae458348..6efd22572dc 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); } -- cgit 1.4.1-3-g733a5 From 52d9fa827d3cf5ef5fc0e2042ca1fc7f6dc391ed Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 10 Mar 2019 17:52:45 +0100 Subject: enabled too many tests --- src/liballoc/tests/binary_heap.rs | 2 +- src/liballoc/tests/slice.rs | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'src/liballoc') diff --git a/src/liballoc/tests/binary_heap.rs b/src/liballoc/tests/binary_heap.rs index a97a790f5a2..0930f8dacd4 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 entropy +#[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/slice.rs b/src/liballoc/tests/slice.rs index fb99c95fc68..b54c128a024 100644 --- a/src/liballoc/tests/slice.rs +++ b/src/liballoc/tests/slice.rs @@ -1397,6 +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 threads nor entropy fn test_box_slice_clone_panics() { use std::sync::Arc; use std::sync::atomic::{AtomicUsize, Ordering}; @@ -1588,6 +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 threads nor entropy fn panic_safe() { let prev = panic::take_hook(); panic::set_hook(Box::new(move |info| { -- cgit 1.4.1-3-g733a5 From 0e0383abc6d1f7d1edc456f66a2e3f4082e9a0a8 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 18 Mar 2019 22:45:02 +0100 Subject: adjust MaybeUninit API to discussions uninitialized -> uninit into_initialized -> assume_init read_initialized -> read set -> write --- src/liballoc/collections/btree/node.rs | 10 +-- src/libcore/fmt/float.rs | 16 ++--- src/libcore/fmt/num.rs | 4 +- src/libcore/macros.rs | 4 +- src/libcore/mem.rs | 110 +++++++++++++++++++++------------ src/libcore/ptr.rs | 14 ++--- src/libcore/slice/rotate.rs | 2 +- 7 files changed, 97 insertions(+), 63 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/collections/btree/node.rs b/src/liballoc/collections/btree/node.rs index 66d619b1298..581c66c7086 100644 --- a/src/liballoc/collections/btree/node.rs +++ b/src/liballoc/collections/btree/node.rs @@ -109,7 +109,7 @@ impl LeafNode { keys: uninitialized_array![_; CAPACITY], vals: uninitialized_array![_; CAPACITY], parent: ptr::null(), - parent_idx: MaybeUninit::uninitialized(), + parent_idx: MaybeUninit::uninit(), len: 0 } } @@ -129,7 +129,7 @@ unsafe impl Sync for NodeHeader<(), ()> {} // ever take a pointer past the first key. static EMPTY_ROOT_NODE: NodeHeader<(), ()> = NodeHeader { parent: ptr::null(), - parent_idx: MaybeUninit::uninitialized(), + parent_idx: MaybeUninit::uninit(), len: 0, keys_start: [], }; @@ -261,7 +261,7 @@ impl Root { -> NodeRef, K, V, marker::Internal> { debug_assert!(!self.is_shared_root()); let mut new_node = Box::new(unsafe { InternalNode::new() }); - new_node.edges[0].set(unsafe { BoxedNode::from_ptr(self.node.as_ptr()) }); + new_node.edges[0].write(unsafe { BoxedNode::from_ptr(self.node.as_ptr()) }); self.node = BoxedNode::from_internal(new_node); self.height += 1; @@ -737,7 +737,7 @@ impl<'a, K, V> NodeRef, K, V, marker::Internal> { unsafe { ptr::write(self.keys_mut().get_unchecked_mut(idx), key); ptr::write(self.vals_mut().get_unchecked_mut(idx), val); - self.as_internal_mut().edges.get_unchecked_mut(idx + 1).set(edge.node); + self.as_internal_mut().edges.get_unchecked_mut(idx + 1).write(edge.node); (*self.as_leaf_mut()).len += 1; @@ -1080,7 +1080,7 @@ impl<'a, K, V> Handle, K, V, marker::Internal>, marker:: let mut child = self.descend(); unsafe { (*child.as_leaf_mut()).parent = ptr; - (*child.as_leaf_mut()).parent_idx.set(idx); + (*child.as_leaf_mut()).parent_idx.write(idx); } } diff --git a/src/libcore/fmt/float.rs b/src/libcore/fmt/float.rs index edeb65afd67..5f4c6f7b0a3 100644 --- a/src/libcore/fmt/float.rs +++ b/src/libcore/fmt/float.rs @@ -10,8 +10,8 @@ fn float_to_decimal_common_exact(fmt: &mut Formatter, num: &T, where T: flt2dec::DecodableFloat { unsafe { - let mut buf = MaybeUninit::<[u8; 1024]>::uninitialized(); // enough for f32 and f64 - let mut parts = MaybeUninit::<[flt2dec::Part; 4]>::uninitialized(); + let mut buf = MaybeUninit::<[u8; 1024]>::uninit(); // enough for f32 and f64 + let mut parts = MaybeUninit::<[flt2dec::Part; 4]>::uninit(); // FIXME(#53491): Technically, this is calling `get_mut` on an uninitialized // `MaybeUninit` (here and elsewhere in this file). Revisit this once // we decided whether that is valid or not. @@ -32,8 +32,8 @@ fn float_to_decimal_common_shortest(fmt: &mut Formatter, num: &T, { unsafe { // enough for f32 and f64 - let mut buf = MaybeUninit::<[u8; flt2dec::MAX_SIG_DIGITS]>::uninitialized(); - let mut parts = MaybeUninit::<[flt2dec::Part; 4]>::uninitialized(); + let mut buf = MaybeUninit::<[u8; flt2dec::MAX_SIG_DIGITS]>::uninit(); + let mut parts = MaybeUninit::<[flt2dec::Part; 4]>::uninit(); // FIXME(#53491) let formatted = flt2dec::to_shortest_str(flt2dec::strategy::grisu::format_shortest, *num, sign, precision, false, buf.get_mut(), @@ -71,8 +71,8 @@ fn float_to_exponential_common_exact(fmt: &mut Formatter, num: &T, where T: flt2dec::DecodableFloat { unsafe { - let mut buf = MaybeUninit::<[u8; 1024]>::uninitialized(); // enough for f32 and f64 - let mut parts = MaybeUninit::<[flt2dec::Part; 6]>::uninitialized(); + let mut buf = MaybeUninit::<[u8; 1024]>::uninit(); // enough for f32 and f64 + let mut parts = MaybeUninit::<[flt2dec::Part; 6]>::uninit(); // FIXME(#53491) let formatted = flt2dec::to_exact_exp_str(flt2dec::strategy::grisu::format_exact, *num, sign, precision, @@ -91,8 +91,8 @@ fn float_to_exponential_common_shortest(fmt: &mut Formatter, { unsafe { // enough for f32 and f64 - let mut buf = MaybeUninit::<[u8; flt2dec::MAX_SIG_DIGITS]>::uninitialized(); - let mut parts = MaybeUninit::<[flt2dec::Part; 6]>::uninitialized(); + let mut buf = MaybeUninit::<[u8; flt2dec::MAX_SIG_DIGITS]>::uninit(); + let mut parts = MaybeUninit::<[flt2dec::Part; 6]>::uninit(); // FIXME(#53491) let formatted = flt2dec::to_shortest_exp_str(flt2dec::strategy::grisu::format_shortest, *num, sign, (0, 0), upper, diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs index b9fa3640371..e96dbcaa144 100644 --- a/src/libcore/fmt/num.rs +++ b/src/libcore/fmt/num.rs @@ -60,7 +60,7 @@ trait GenericRadix { for byte in buf.iter_mut().rev() { let n = x % base; // Get the current place value. x = x / base; // Deaccumulate the number. - byte.set(Self::digit(n.to_u8())); // Store the digit in the buffer. + byte.write(Self::digit(n.to_u8())); // Store the digit in the buffer. curr -= 1; if x == zero { // No more digits left to accumulate. @@ -72,7 +72,7 @@ trait GenericRadix { for byte in buf.iter_mut().rev() { let n = zero - (x % base); // Get the current place value. x = x / base; // Deaccumulate the number. - byte.set(Self::digit(n.to_u8())); // Store the digit in the buffer. + byte.write(Self::digit(n.to_u8())); // Store the digit in the buffer. curr -= 1; if x == zero { // No more digits left to accumulate. diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index d77936c7ddd..ad8ce1af1f6 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -626,12 +626,12 @@ macro_rules! todo { #[macro_export] #[unstable(feature = "maybe_uninit_array", issue = "53491")] macro_rules! uninitialized_array { - // This `into_initialized` is safe because an array of `MaybeUninit` does not + // This `assume_init` is safe because an array of `MaybeUninit` does not // require initialization. // FIXME(#49147): Could be replaced by an array initializer, once those can // be any const expression. ($t:ty; $size:expr) => (unsafe { - MaybeUninit::<[MaybeUninit<$t>; $size]>::uninitialized().into_initialized() + MaybeUninit::<[MaybeUninit<$t>; $size]>::uninit().assume_init() }); } diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 3d2fcdc9793..66bcf1f7d01 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -622,7 +622,7 @@ pub unsafe fn zeroed() -> T { /// [copy_no]: ../intrinsics/fn.copy_nonoverlapping.html /// [`Drop`]: ../ops/trait.Drop.html #[inline] -#[rustc_deprecated(since = "2.0.0", reason = "use `mem::MaybeUninit::uninitialized` instead")] +#[rustc_deprecated(since = "2.0.0", reason = "use `mem::MaybeUninit::uninit` instead")] #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn uninitialized() -> T { intrinsics::panic_if_uninhabited::(); @@ -1058,7 +1058,7 @@ impl DerefMut for ManuallyDrop { /// /// let x: &i32 = unsafe { mem::zeroed() }; // undefined behavior! /// // The equivalent code with `MaybeUninit<&i32>`: -/// let x: &i32 = unsafe { MaybeUninit::zeroed().into_initialized() }; // undefined behavior! +/// let x: &i32 = unsafe { MaybeUninit::zeroed().assume_init() }; // undefined behavior! /// ``` /// /// This is exploited by the compiler for various optimizations, such as eliding @@ -1073,7 +1073,7 @@ impl DerefMut for ManuallyDrop { /// /// let b: bool = unsafe { mem::uninitialized() }; // undefined behavior! /// // The equivalent code with `MaybeUninit`: -/// let b: bool = unsafe { MaybeUninit::uninitialized().into_initialized() }; // undefined behavior! +/// let b: bool = unsafe { MaybeUninit::uninit().assume_init() }; // undefined behavior! /// ``` /// /// Moreover, uninitialized memory is special in that the compiler knows that @@ -1087,7 +1087,7 @@ impl DerefMut for ManuallyDrop { /// /// let x: i32 = unsafe { mem::uninitialized() }; // undefined behavior! /// // The equivalent code with `MaybeUninit`: -/// let x: i32 = unsafe { MaybeUninit::uninitialized().into_initialized() }; // undefined behavior! +/// let x: i32 = unsafe { MaybeUninit::uninit().assume_init() }; // undefined behavior! /// ``` /// (Notice that the rules around uninitialized integers are not finalized yet, but /// until they are, it is advisable to avoid them.) @@ -1102,12 +1102,12 @@ impl DerefMut for ManuallyDrop { /// /// // Create an explicitly uninitialized reference. The compiler knows that data inside /// // a `MaybeUninit` may be invalid, and hence this is not UB: -/// let mut x = MaybeUninit::<&i32>::uninitialized(); +/// let mut x = MaybeUninit::<&i32>::uninit(); /// // Set it to a valid value. -/// x.set(&0); +/// x.write(&0); /// // Extract the initialized data -- this is only allowed *after* properly /// // initializing `x`! -/// let x = unsafe { x.into_initialized() }; +/// let x = unsafe { x.assume_init() }; /// ``` /// /// The compiler then knows to not make any incorrect assumptions or optimizations on this code. @@ -1148,10 +1148,19 @@ impl MaybeUninit { /// It is your responsibility to make sure `T` gets dropped if it got initialized. #[unstable(feature = "maybe_uninit", issue = "53491")] #[inline(always)] - pub const fn uninitialized() -> MaybeUninit { + pub const fn uninit() -> MaybeUninit { MaybeUninit { uninit: () } } + /// Deprecated before stabilization. + #[unstable(feature = "maybe_uninit", issue = "53491")] + #[inline(always)] + // FIXME: still used by stdsimd + // #[rustc_deprecated(since = "1.35.0", reason = "use `uninit` instead")] + pub const fn uninitialized() -> MaybeUninit { + Self::uninit() + } + /// Creates a new `MaybeUninit` in an uninitialized state, with the memory being /// filled with `0` bytes. It depends on `T` whether that already makes for /// proper initialization. For example, `MaybeUninit::zeroed()` is initialized, @@ -1171,7 +1180,7 @@ impl MaybeUninit { /// use std::mem::MaybeUninit; /// /// let x = MaybeUninit::<(u8, bool)>::zeroed(); - /// let x = unsafe { x.into_initialized() }; + /// let x = unsafe { x.assume_init() }; /// assert_eq!(x, (0, false)); /// ``` /// @@ -1185,14 +1194,14 @@ impl MaybeUninit { /// enum NotZero { One = 1, Two = 2 }; /// /// let x = MaybeUninit::<(u8, NotZero)>::zeroed(); - /// let x = unsafe { x.into_initialized() }; + /// let x = unsafe { x.assume_init() }; /// // Inside a pair, we create a `NotZero` that does not have a valid discriminant. /// // This is undefined behavior. /// ``` #[unstable(feature = "maybe_uninit", issue = "53491")] #[inline] pub fn zeroed() -> MaybeUninit { - let mut u = MaybeUninit::::uninitialized(); + let mut u = MaybeUninit::::uninit(); unsafe { u.as_mut_ptr().write_bytes(0u8, 1); } @@ -1205,13 +1214,21 @@ impl MaybeUninit { /// reference to the (now safely initialized) contents of `self`. #[unstable(feature = "maybe_uninit", issue = "53491")] #[inline(always)] - pub fn set(&mut self, val: T) -> &mut T { + pub fn write(&mut self, val: T) -> &mut T { unsafe { self.value = ManuallyDrop::new(val); self.get_mut() } } + /// Deprecated before stabilization. + #[unstable(feature = "maybe_uninit", issue = "53491")] + #[inline(always)] + #[rustc_deprecated(since = "1.35.0", reason = "use `write` instead")] + pub fn set(&mut self, val: T) -> &mut T { + self.write(val) + } + /// Gets a pointer to the contained value. Reading from this pointer or turning it /// into a reference is undefined behavior unless the `MaybeUninit` is initialized. /// @@ -1223,7 +1240,7 @@ impl MaybeUninit { /// #![feature(maybe_uninit)] /// use std::mem::MaybeUninit; /// - /// let mut x = MaybeUninit::>::uninitialized(); + /// let mut x = MaybeUninit::>::uninit(); /// unsafe { x.as_mut_ptr().write(vec![0,1,2]); } /// // Create a reference into the `MaybeUninit`. This is okay because we initialized it. /// let x_vec = unsafe { &*x.as_ptr() }; @@ -1236,7 +1253,7 @@ impl MaybeUninit { /// #![feature(maybe_uninit)] /// use std::mem::MaybeUninit; /// - /// let x = MaybeUninit::>::uninitialized(); + /// let x = MaybeUninit::>::uninit(); /// let x_vec = unsafe { &*x.as_ptr() }; /// // We have created a reference to an uninitialized vector! This is undefined behavior. /// ``` @@ -1260,7 +1277,7 @@ impl MaybeUninit { /// #![feature(maybe_uninit)] /// use std::mem::MaybeUninit; /// - /// let mut x = MaybeUninit::>::uninitialized(); + /// let mut x = MaybeUninit::>::uninit(); /// unsafe { x.as_mut_ptr().write(vec![0,1,2]); } /// // Create a reference into the `MaybeUninit>`. /// // This is okay because we initialized it. @@ -1275,7 +1292,7 @@ impl MaybeUninit { /// #![feature(maybe_uninit)] /// use std::mem::MaybeUninit; /// - /// let mut x = MaybeUninit::>::uninitialized(); + /// let mut x = MaybeUninit::>::uninit(); /// let x_vec = unsafe { &mut *x.as_mut_ptr() }; /// // We have created a reference to an uninitialized vector! This is undefined behavior. /// ``` @@ -1306,9 +1323,9 @@ impl MaybeUninit { /// #![feature(maybe_uninit)] /// use std::mem::MaybeUninit; /// - /// let mut x = MaybeUninit::::uninitialized(); + /// let mut x = MaybeUninit::::uninit(); /// unsafe { x.as_mut_ptr().write(true); } - /// let x_init = unsafe { x.into_initialized() }; + /// let x_init = unsafe { x.assume_init() }; /// assert_eq!(x_init, true); /// ``` /// @@ -1318,21 +1335,30 @@ impl MaybeUninit { /// #![feature(maybe_uninit)] /// use std::mem::MaybeUninit; /// - /// let x = MaybeUninit::>::uninitialized(); - /// let x_init = unsafe { x.into_initialized() }; + /// let x = MaybeUninit::>::uninit(); + /// let x_init = unsafe { x.assume_init() }; /// // `x` had not been initialized yet, so this last line caused undefined behavior. /// ``` #[unstable(feature = "maybe_uninit", issue = "53491")] #[inline(always)] - pub unsafe fn into_initialized(self) -> T { + pub unsafe fn assume_init(self) -> T { intrinsics::panic_if_uninhabited::(); ManuallyDrop::into_inner(self.value) } + /// Deprecated before stabilization. + #[unstable(feature = "maybe_uninit", issue = "53491")] + #[inline(always)] + // FIXME: still used by stdsimd + // #[rustc_deprecated(since = "1.35.0", reason = "use `assume_init` instead")] + pub unsafe fn into_initialized(self) -> T { + self.assume_init() + } + /// Reads the value from the `MaybeUninit` container. The resulting `T` is subject /// to the usual drop handling. /// - /// Whenever possible, it is preferrable to use [`into_initialized`] instead, which + /// Whenever possible, it is preferrable to use [`assume_init`] instead, which /// prevents duplicating the content of the `MaybeUninit`. /// /// # Safety @@ -1342,11 +1368,11 @@ impl MaybeUninit { /// behavior. /// /// Moreover, this leaves a copy of the same data behind in the `MaybeUninit`. When using - /// multiple copies of the data (by calling `read_initialized` multiple times, or first - /// calling `read_initialized` and then [`into_initialized`]), it is your responsibility + /// multiple copies of the data (by calling `read` multiple times, or first + /// calling `read` and then [`assume_init`]), it is your responsibility /// to ensure that that data may indeed be duplicated. /// - /// [`into_initialized`]: #method.into_initialized + /// [`assume_init`]: #method.assume_init /// /// # Examples /// @@ -1356,18 +1382,18 @@ impl MaybeUninit { /// #![feature(maybe_uninit)] /// use std::mem::MaybeUninit; /// - /// let mut x = MaybeUninit::::uninitialized(); - /// x.set(13); - /// let x1 = unsafe { x.read_initialized() }; + /// let mut x = MaybeUninit::::uninit(); + /// x.write(13); + /// let x1 = unsafe { x.read() }; /// // `u32` is `Copy`, so we may read multiple times. - /// let x2 = unsafe { x.read_initialized() }; + /// let x2 = unsafe { x.read() }; /// assert_eq!(x1, x2); /// - /// let mut x = MaybeUninit::>>::uninitialized(); - /// x.set(None); - /// let x1 = unsafe { x.read_initialized() }; + /// let mut x = MaybeUninit::>>::uninit(); + /// x.write(None); + /// let x1 = unsafe { x.read() }; /// // Duplicating a `None` value is okay, so we may read multiple times. - /// let x2 = unsafe { x.read_initialized() }; + /// let x2 = unsafe { x.read() }; /// assert_eq!(x1, x2); /// ``` /// @@ -1377,20 +1403,28 @@ impl MaybeUninit { /// #![feature(maybe_uninit)] /// use std::mem::MaybeUninit; /// - /// let mut x = MaybeUninit::>>::uninitialized(); - /// x.set(Some(vec![0,1,2])); - /// let x1 = unsafe { x.read_initialized() }; - /// let x2 = unsafe { x.read_initialized() }; + /// let mut x = MaybeUninit::>>::uninit(); + /// x.write(Some(vec![0,1,2])); + /// let x1 = unsafe { x.read() }; + /// let x2 = unsafe { x.read() }; /// // We now created two copies of the same vector, leading to a double-free when /// // they both get dropped! /// ``` #[unstable(feature = "maybe_uninit", issue = "53491")] #[inline(always)] - pub unsafe fn read_initialized(&self) -> T { + pub unsafe fn read(&self) -> T { intrinsics::panic_if_uninhabited::(); self.as_ptr().read() } + /// Deprecated before stabilization. + #[unstable(feature = "maybe_uninit", issue = "53491")] + #[inline(always)] + #[rustc_deprecated(since = "1.35.0", reason = "use `read` instead")] + pub unsafe fn read_initialized(&self) -> T { + self.read() + } + /// Gets a reference to the contained value. /// /// # Safety diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index a9a029d606d..1cb21aa6be0 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -296,7 +296,7 @@ pub const fn null_mut() -> *mut T { 0 as *mut T } pub unsafe fn swap(x: *mut T, y: *mut T) { // Give ourselves some scratch space to work with. // We do not have to worry about drops: `MaybeUninit` does nothing when dropped. - let mut tmp = MaybeUninit::::uninitialized(); + let mut tmp = MaybeUninit::::uninit(); // Perform the swap copy_nonoverlapping(x, tmp.as_mut_ptr(), 1); @@ -388,7 +388,7 @@ unsafe fn swap_nonoverlapping_bytes(x: *mut u8, y: *mut u8, len: usize) { while i + block_size <= len { // Create some uninitialized memory as scratch space // Declaring `t` here avoids aligning the stack when this loop is unused - let mut t = mem::MaybeUninit::::uninitialized(); + let mut t = mem::MaybeUninit::::uninit(); let t = t.as_mut_ptr() as *mut u8; let x = x.add(i); let y = y.add(i); @@ -403,7 +403,7 @@ unsafe fn swap_nonoverlapping_bytes(x: *mut u8, y: *mut u8, len: usize) { if i < len { // Swap any remaining bytes - let mut t = mem::MaybeUninit::::uninitialized(); + let mut t = mem::MaybeUninit::::uninit(); let rem = len - i; let t = t.as_mut_ptr() as *mut u8; @@ -571,9 +571,9 @@ pub unsafe fn replace(dst: *mut T, mut src: T) -> T { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn read(src: *const T) -> T { - let mut tmp = MaybeUninit::::uninitialized(); + let mut tmp = MaybeUninit::::uninit(); copy_nonoverlapping(src, tmp.as_mut_ptr(), 1); - tmp.into_initialized() + tmp.assume_init() } /// Reads the value from `src` without moving it. This leaves the @@ -638,11 +638,11 @@ pub unsafe fn read(src: *const T) -> T { #[inline] #[stable(feature = "ptr_unaligned", since = "1.17.0")] pub unsafe fn read_unaligned(src: *const T) -> T { - let mut tmp = MaybeUninit::::uninitialized(); + let mut tmp = MaybeUninit::::uninit(); copy_nonoverlapping(src as *const u8, tmp.as_mut_ptr() as *mut u8, mem::size_of::()); - tmp.into_initialized() + tmp.assume_init() } /// Overwrites a memory location with the given value without reading or diff --git a/src/libcore/slice/rotate.rs b/src/libcore/slice/rotate.rs index 9b35b51349a..8f10c3576a7 100644 --- a/src/libcore/slice/rotate.rs +++ b/src/libcore/slice/rotate.rs @@ -72,7 +72,7 @@ pub unsafe fn ptr_rotate(mut left: usize, mid: *mut T, mut right: usize) { } } - let mut rawarray = MaybeUninit::>::uninitialized(); + let mut rawarray = MaybeUninit::>::uninit(); let buf = &mut (*rawarray.as_mut_ptr()).typed as *mut [T; 2] as *mut T; let dim = mid.sub(left).add(right); -- cgit 1.4.1-3-g733a5 From f5fee8fd7d2bd25ac63b9ea44925f9ac2f61c3d2 Mon Sep 17 00:00:00 2001 From: Stein Somers Date: Wed, 13 Mar 2019 23:01:12 +0100 Subject: improve worst-case performance of BTreeSet difference and intersection --- src/liballoc/benches/btree/set.rs | 114 ++++++------- src/liballoc/collections/btree/set.rs | 298 ++++++++++++++++++++++++++-------- src/liballoc/tests/btree/set.rs | 61 +++++++ 3 files changed, 351 insertions(+), 122 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/benches/btree/set.rs b/src/liballoc/benches/btree/set.rs index 08e1db5fbb7..6357ea3ea11 100644 --- a/src/liballoc/benches/btree/set.rs +++ b/src/liballoc/benches/btree/set.rs @@ -3,59 +3,49 @@ use std::collections::BTreeSet; use rand::{thread_rng, Rng}; use test::{black_box, Bencher}; -fn random(n1: u32, n2: u32) -> [BTreeSet; 2] { +fn random(n: usize) -> BTreeSet { let mut rng = thread_rng(); - let mut set1 = BTreeSet::new(); - let mut set2 = BTreeSet::new(); - for _ in 0..n1 { - let i = rng.gen::(); - set1.insert(i); + let mut set = BTreeSet::new(); + while set.len() < n { + set.insert(rng.gen()); } - for _ in 0..n2 { - let i = rng.gen::(); - set2.insert(i); - } - [set1, set2] + assert_eq!(set.len(), n); + set } -fn staggered(n1: u32, n2: u32) -> [BTreeSet; 2] { - let mut even = BTreeSet::new(); - let mut odd = BTreeSet::new(); - for i in 0..n1 { - even.insert(i * 2); - } - for i in 0..n2 { - odd.insert(i * 2 + 1); +fn neg(n: usize) -> BTreeSet { + let mut set = BTreeSet::new(); + for i in -(n as i32)..=-1 { + set.insert(i); } - [even, odd] + assert_eq!(set.len(), n); + set } -fn neg_vs_pos(n1: u32, n2: u32) -> [BTreeSet; 2] { - let mut neg = BTreeSet::new(); - let mut pos = BTreeSet::new(); - for i in -(n1 as i32)..=-1 { - neg.insert(i); - } - for i in 1..=(n2 as i32) { - pos.insert(i); +fn pos(n: usize) -> BTreeSet { + let mut set = BTreeSet::new(); + for i in 1..=(n as i32) { + set.insert(i); } - [neg, pos] + assert_eq!(set.len(), n); + set } -fn pos_vs_neg(n1: u32, n2: u32) -> [BTreeSet; 2] { - let mut neg = BTreeSet::new(); - let mut pos = BTreeSet::new(); - for i in -(n1 as i32)..=-1 { - neg.insert(i); - } - for i in 1..=(n2 as i32) { - pos.insert(i); + +fn stagger(n1: usize, factor: usize) -> [BTreeSet; 2] { + let n2 = n1 * factor; + let mut sets = [BTreeSet::new(), BTreeSet::new()]; + for i in 0..(n1 + n2) { + let b = i % (factor + 1) != 0; + sets[b as usize].insert(i as u32); } - [pos, neg] + assert_eq!(sets[0].len(), n1); + assert_eq!(sets[1].len(), n2); + sets } -macro_rules! set_intersection_bench { - ($name: ident, $sets: expr) => { +macro_rules! set_bench { + ($name: ident, $set_func: ident, $result_func: ident, $sets: expr) => { #[bench] pub fn $name(b: &mut Bencher) { // setup @@ -63,26 +53,36 @@ macro_rules! set_intersection_bench { // measure b.iter(|| { - let x = sets[0].intersection(&sets[1]).count(); + let x = sets[0].$set_func(&sets[1]).$result_func(); black_box(x); }) } }; } -set_intersection_bench! {intersect_random_100, random(100, 100)} -set_intersection_bench! {intersect_random_10k, random(10_000, 10_000)} -set_intersection_bench! {intersect_random_10_vs_10k, random(10, 10_000)} -set_intersection_bench! {intersect_random_10k_vs_10, random(10_000, 10)} -set_intersection_bench! {intersect_staggered_100, staggered(100, 100)} -set_intersection_bench! {intersect_staggered_10k, staggered(10_000, 10_000)} -set_intersection_bench! {intersect_staggered_10_vs_10k, staggered(10, 10_000)} -set_intersection_bench! {intersect_staggered_10k_vs_10, staggered(10_000, 10)} -set_intersection_bench! {intersect_neg_vs_pos_100, neg_vs_pos(100, 100)} -set_intersection_bench! {intersect_neg_vs_pos_10k, neg_vs_pos(10_000, 10_000)} -set_intersection_bench! {intersect_neg_vs_pos_10_vs_10k,neg_vs_pos(10, 10_000)} -set_intersection_bench! {intersect_neg_vs_pos_10k_vs_10,neg_vs_pos(10_000, 10)} -set_intersection_bench! {intersect_pos_vs_neg_100, pos_vs_neg(100, 100)} -set_intersection_bench! {intersect_pos_vs_neg_10k, pos_vs_neg(10_000, 10_000)} -set_intersection_bench! {intersect_pos_vs_neg_10_vs_10k,pos_vs_neg(10, 10_000)} -set_intersection_bench! {intersect_pos_vs_neg_10k_vs_10,pos_vs_neg(10_000, 10)} +set_bench! {intersection_100_neg_vs_100_pos, intersection, count, [neg(100), pos(100)]} +set_bench! {intersection_100_neg_vs_10k_pos, intersection, count, [neg(100), pos(10_000)]} +set_bench! {intersection_100_pos_vs_100_neg, intersection, count, [pos(100), neg(100)]} +set_bench! {intersection_100_pos_vs_10k_neg, intersection, count, [pos(100), neg(10_000)]} +set_bench! {intersection_10k_neg_vs_100_pos, intersection, count, [neg(10_000), pos(100)]} +set_bench! {intersection_10k_neg_vs_10k_pos, intersection, count, [neg(10_000), pos(10_000)]} +set_bench! {intersection_10k_pos_vs_100_neg, intersection, count, [pos(10_000), neg(100)]} +set_bench! {intersection_10k_pos_vs_10k_neg, intersection, count, [pos(10_000), neg(10_000)]} +set_bench! {intersection_random_100_vs_100, intersection, count, [random(100), random(100)]} +set_bench! {intersection_random_100_vs_10k, intersection, count, [random(100), random(10_000)]} +set_bench! {intersection_random_10k_vs_100, intersection, count, [random(10_000), random(100)]} +set_bench! {intersection_random_10k_vs_10k, intersection, count, [random(10_000), random(10_000)]} +set_bench! {intersection_staggered_100_vs_100, intersection, count, stagger(100, 1)} +set_bench! {intersection_staggered_10k_vs_10k, intersection, count, stagger(10_000, 1)} +set_bench! {intersection_staggered_100_vs_10k, intersection, count, stagger(100, 100)} +set_bench! {difference_random_100_vs_100, difference, count, [random(100), random(100)]} +set_bench! {difference_random_100_vs_10k, difference, count, [random(100), random(10_000)]} +set_bench! {difference_random_10k_vs_100, difference, count, [random(10_000), random(100)]} +set_bench! {difference_random_10k_vs_10k, difference, count, [random(10_000), random(10_000)]} +set_bench! {difference_staggered_100_vs_100, difference, count, stagger(100, 1)} +set_bench! {difference_staggered_10k_vs_10k, difference, count, stagger(10_000, 1)} +set_bench! {difference_staggered_100_vs_10k, difference, count, stagger(100, 100)} +set_bench! {is_subset_100_vs_100, is_subset, clone, [pos(100), pos(100)]} +set_bench! {is_subset_100_vs_10k, is_subset, clone, [pos(100), pos(10_000)]} +set_bench! {is_subset_10k_vs_100, is_subset, clone, [pos(10_000), pos(100)]} +set_bench! {is_subset_10k_vs_10k, is_subset, clone, [pos(10_000), pos(10_000)]} diff --git a/src/liballoc/collections/btree/set.rs b/src/liballoc/collections/btree/set.rs index 2be6455ad59..e71767077ca 100644 --- a/src/liballoc/collections/btree/set.rs +++ b/src/liballoc/collections/btree/set.rs @@ -3,7 +3,7 @@ use core::borrow::Borrow; use core::cmp::Ordering::{self, Less, Greater, Equal}; -use core::cmp::{min, max}; +use core::cmp::max; use core::fmt::{self, Debug}; use core::iter::{Peekable, FromIterator, FusedIterator}; use core::ops::{BitOr, BitAnd, BitXor, Sub, RangeBounds}; @@ -118,17 +118,36 @@ pub struct Range<'a, T: 'a> { /// [`difference`]: struct.BTreeSet.html#method.difference #[stable(feature = "rust1", since = "1.0.0")] pub struct Difference<'a, T: 'a> { - a: Peekable>, - b: Peekable>, + inner: DifferenceInner<'a, T>, +} +enum DifferenceInner<'a, T: 'a> { + Stitch { + self_iter: Iter<'a, T>, + other_iter: Peekable>, + }, + Search { + self_iter: Iter<'a, T>, + other_set: &'a BTreeSet, + }, } #[stable(feature = "collection_debug", since = "1.17.0")] impl fmt::Debug for Difference<'_, T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("Difference") - .field(&self.a) - .field(&self.b) - .finish() + match &self.inner { + DifferenceInner::Stitch { + self_iter, + other_iter, + } => f + .debug_tuple("Difference") + .field(&self_iter) + .field(&other_iter) + .finish(), + DifferenceInner::Search { + self_iter, + other_set: _, + } => f.debug_tuple("Difference").field(&self_iter).finish(), + } } } @@ -164,17 +183,36 @@ impl fmt::Debug for SymmetricDifference<'_, T> { /// [`intersection`]: struct.BTreeSet.html#method.intersection #[stable(feature = "rust1", since = "1.0.0")] pub struct Intersection<'a, T: 'a> { - a: Peekable>, - b: Peekable>, + inner: IntersectionInner<'a, T>, +} +enum IntersectionInner<'a, T: 'a> { + Stitch { + small_iter: Iter<'a, T>, // for size_hint, should be the smaller of the sets + other_iter: Iter<'a, T>, + }, + Search { + small_iter: Iter<'a, T>, + large_set: &'a BTreeSet, + }, } #[stable(feature = "collection_debug", since = "1.17.0")] impl fmt::Debug for Intersection<'_, T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("Intersection") - .field(&self.a) - .field(&self.b) - .finish() + match &self.inner { + IntersectionInner::Stitch { + small_iter, + other_iter, + } => f + .debug_tuple("Intersection") + .field(&small_iter) + .field(&other_iter) + .finish(), + IntersectionInner::Search { + small_iter, + large_set: _, + } => f.debug_tuple("Intersection").field(&small_iter).finish(), + } } } @@ -201,6 +239,14 @@ impl fmt::Debug for Union<'_, T> { } } +// This constant is used by functions that compare two sets. +// It estimates the relative size at which searching performs better +// than iterating, based on the benchmarks in +// https://github.com/ssomers/rust_bench_btreeset_intersection; +// It's used to divide rather than multiply sizes, to rule out overflow, +// and it's a power of two to make that division cheap. +const ITER_PERFORMANCE_TIPPING_SIZE_DIFF: usize = 16; + impl BTreeSet { /// Makes a new `BTreeSet` with a reasonable choice of B. /// @@ -268,9 +314,24 @@ impl BTreeSet { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn difference<'a>(&'a self, other: &'a BTreeSet) -> Difference<'a, T> { - Difference { - a: self.iter().peekable(), - b: other.iter().peekable(), + if self.len() > other.len() / ITER_PERFORMANCE_TIPPING_SIZE_DIFF { + // Self is bigger than or not much smaller than other set. + // Iterate both sets jointly, spotting matches along the way. + Difference { + inner: DifferenceInner::Stitch { + self_iter: self.iter(), + other_iter: other.iter().peekable(), + }, + } + } else { + // Self is much smaller than other set, or both sets are empty. + // Iterate the small set, searching for matches in the large set. + Difference { + inner: DifferenceInner::Search { + self_iter: self.iter(), + other_set: other, + }, + } } } @@ -326,9 +387,29 @@ impl BTreeSet { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn intersection<'a>(&'a self, other: &'a BTreeSet) -> Intersection<'a, T> { - Intersection { - a: self.iter().peekable(), - b: other.iter().peekable(), + let (small, other) = if self.len() <= other.len() { + (self, other) + } else { + (other, self) + }; + if small.len() > other.len() / ITER_PERFORMANCE_TIPPING_SIZE_DIFF { + // Small set is not much smaller than other set. + // Iterate both sets jointly, spotting matches along the way. + Intersection { + inner: IntersectionInner::Stitch { + small_iter: small.iter(), + other_iter: other.iter(), + }, + } + } else { + // Big difference in number of elements, or both sets are empty. + // Iterate the small set, searching for matches in the large set. + Intersection { + inner: IntersectionInner::Search { + small_iter: small.iter(), + large_set: other, + }, + } } } @@ -462,28 +543,44 @@ impl BTreeSet { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn is_subset(&self, other: &BTreeSet) -> bool { - // Stolen from TreeMap - let mut x = self.iter(); - let mut y = other.iter(); - let mut a = x.next(); - let mut b = y.next(); - while a.is_some() { - if b.is_none() { - return false; - } + // Same result as self.difference(other).next().is_none() + // but the 3 paths below are faster (in order: hugely, 20%, 5%). + if self.len() > other.len() { + false + } else if self.len() > other.len() / ITER_PERFORMANCE_TIPPING_SIZE_DIFF { + // Self is not much smaller than other set. + // Stolen from TreeMap + let mut x = self.iter(); + let mut y = other.iter(); + let mut a = x.next(); + let mut b = y.next(); + while a.is_some() { + if b.is_none() { + return false; + } - let a1 = a.unwrap(); - let b1 = b.unwrap(); + let a1 = a.unwrap(); + let b1 = b.unwrap(); - match b1.cmp(a1) { - Less => (), - Greater => return false, - Equal => a = x.next(), - } + match b1.cmp(a1) { + Less => (), + Greater => return false, + Equal => a = x.next(), + } - b = y.next(); + b = y.next(); + } + true + } else { + // Big difference in number of elements, or both sets are empty. + // Iterate the small set, searching for matches in the large set. + for next in self { + if !other.contains(next) { + return false; + } + } + true } - true } /// Returns `true` if the set is a superset of another, @@ -1001,8 +1098,22 @@ fn cmp_opt(x: Option<&T>, y: Option<&T>, short: Ordering, long: Ordering impl Clone for Difference<'_, T> { fn clone(&self) -> Self { Difference { - a: self.a.clone(), - b: self.b.clone(), + inner: match &self.inner { + DifferenceInner::Stitch { + self_iter, + other_iter, + } => DifferenceInner::Stitch { + self_iter: self_iter.clone(), + other_iter: other_iter.clone(), + }, + DifferenceInner::Search { + self_iter, + other_set, + } => DifferenceInner::Search { + self_iter: self_iter.clone(), + other_set, + }, + }, } } } @@ -1011,24 +1122,52 @@ impl<'a, T: Ord> Iterator for Difference<'a, T> { type Item = &'a T; fn next(&mut self) -> Option<&'a T> { - loop { - match cmp_opt(self.a.peek(), self.b.peek(), Less, Less) { - Less => return self.a.next(), - Equal => { - self.a.next(); - self.b.next(); - } - Greater => { - self.b.next(); + match &mut self.inner { + DifferenceInner::Stitch { + self_iter, + other_iter, + } => { + let mut self_next = self_iter.next()?; + loop { + match other_iter + .peek() + .map_or(Less, |other_next| Ord::cmp(self_next, other_next)) + { + Less => return Some(self_next), + Equal => { + self_next = self_iter.next()?; + other_iter.next(); + } + Greater => { + other_iter.next(); + } + } } } + DifferenceInner::Search { + self_iter, + other_set, + } => loop { + let self_next = self_iter.next()?; + if !other_set.contains(&self_next) { + return Some(self_next); + } + }, } } fn size_hint(&self) -> (usize, Option) { - let a_len = self.a.len(); - let b_len = self.b.len(); - (a_len.saturating_sub(b_len), Some(a_len)) + let (self_len, other_len) = match &self.inner { + DifferenceInner::Stitch { + self_iter, + other_iter + } => (self_iter.len(), other_iter.len()), + DifferenceInner::Search { + self_iter, + other_set + } => (self_iter.len(), other_set.len()), + }; + (self_len.saturating_sub(other_len), Some(self_len)) } } @@ -1073,8 +1212,22 @@ impl FusedIterator for SymmetricDifference<'_, T> {} impl Clone for Intersection<'_, T> { fn clone(&self) -> Self { Intersection { - a: self.a.clone(), - b: self.b.clone(), + inner: match &self.inner { + IntersectionInner::Stitch { + small_iter, + other_iter, + } => IntersectionInner::Stitch { + small_iter: small_iter.clone(), + other_iter: other_iter.clone(), + }, + IntersectionInner::Search { + small_iter, + large_set, + } => IntersectionInner::Search { + small_iter: small_iter.clone(), + large_set, + }, + }, } } } @@ -1083,24 +1236,39 @@ impl<'a, T: Ord> Iterator for Intersection<'a, T> { type Item = &'a T; fn next(&mut self) -> Option<&'a T> { - loop { - match Ord::cmp(self.a.peek()?, self.b.peek()?) { - Less => { - self.a.next(); - } - Equal => { - self.b.next(); - return self.a.next(); - } - Greater => { - self.b.next(); + match &mut self.inner { + IntersectionInner::Stitch { + small_iter, + other_iter, + } => { + let mut small_next = small_iter.next()?; + let mut other_next = other_iter.next()?; + loop { + match Ord::cmp(small_next, other_next) { + Less => small_next = small_iter.next()?, + Greater => other_next = other_iter.next()?, + Equal => return Some(small_next), + } } } + IntersectionInner::Search { + small_iter, + large_set, + } => loop { + let small_next = small_iter.next()?; + if large_set.contains(&small_next) { + return Some(small_next); + } + }, } } fn size_hint(&self) -> (usize, Option) { - (0, Some(min(self.a.len(), self.b.len()))) + let min_len = match &self.inner { + IntersectionInner::Stitch { small_iter, .. } => small_iter.len(), + IntersectionInner::Search { small_iter, .. } => small_iter.len(), + }; + (0, Some(min_len)) } } diff --git a/src/liballoc/tests/btree/set.rs b/src/liballoc/tests/btree/set.rs index 4f5168f1ce5..d52814118b3 100644 --- a/src/liballoc/tests/btree/set.rs +++ b/src/liballoc/tests/btree/set.rs @@ -69,6 +69,20 @@ fn test_intersection() { check_intersection(&[11, 1, 3, 77, 103, 5, -5], &[2, 11, 77, -9, -42, 5, 3], &[3, 5, 11, 77]); + let large = (0..1000).collect::>(); + check_intersection(&[], &large, &[]); + check_intersection(&large, &[], &[]); + check_intersection(&[-1], &large, &[]); + check_intersection(&large, &[-1], &[]); + check_intersection(&[0], &large, &[0]); + check_intersection(&large, &[0], &[0]); + check_intersection(&[999], &large, &[999]); + check_intersection(&large, &[999], &[999]); + check_intersection(&[1000], &large, &[]); + check_intersection(&large, &[1000], &[]); + check_intersection(&[11, 5000, 1, 3, 77, 8924, 103], + &large, + &[1, 3, 11, 77, 103]); } #[test] @@ -84,6 +98,18 @@ fn test_difference() { check_difference(&[-5, 11, 22, 33, 40, 42], &[-12, -5, 14, 23, 34, 38, 39, 50], &[11, 22, 33, 40, 42]); + let large = (0..1000).collect::>(); + check_difference(&[], &large, &[]); + check_difference(&[-1], &large, &[-1]); + check_difference(&[0], &large, &[]); + check_difference(&[999], &large, &[]); + check_difference(&[1000], &large, &[1000]); + check_difference(&[11, 5000, 1, 3, 77, 8924, 103], + &large, + &[5000, 8924]); + check_difference(&large, &[], &large); + check_difference(&large, &[-1], &large); + check_difference(&large, &[1000], &large); } #[test] @@ -114,6 +140,41 @@ fn test_union() { &[-2, 1, 3, 5, 9, 11, 13, 16, 19, 24]); } +#[test] +// Only tests the simple function definition with respect to intersection +fn test_is_disjoint() { + let one = [1].into_iter().collect::>(); + let two = [2].into_iter().collect::>(); + assert!(one.is_disjoint(&two)); +} + +#[test] +// Also tests the trivial function definition of is_superset +fn test_is_subset() { + fn is_subset(a: &[i32], b: &[i32]) -> bool { + let set_a = a.iter().collect::>(); + let set_b = b.iter().collect::>(); + set_a.is_subset(&set_b) + } + + assert_eq!(is_subset(&[], &[]), true); + assert_eq!(is_subset(&[], &[1, 2]), true); + assert_eq!(is_subset(&[0], &[1, 2]), false); + assert_eq!(is_subset(&[1], &[1, 2]), true); + assert_eq!(is_subset(&[2], &[1, 2]), true); + assert_eq!(is_subset(&[3], &[1, 2]), false); + assert_eq!(is_subset(&[1, 2], &[1]), false); + assert_eq!(is_subset(&[1, 2], &[1, 2]), true); + assert_eq!(is_subset(&[1, 2], &[2, 3]), false); + let large = (0..1000).collect::>(); + assert_eq!(is_subset(&[], &large), true); + assert_eq!(is_subset(&large, &[]), false); + assert_eq!(is_subset(&[-1], &large), false); + assert_eq!(is_subset(&[0], &large), true); + assert_eq!(is_subset(&[1, 2], &large), true); + assert_eq!(is_subset(&[999, 1000], &large), false); +} + #[test] fn test_zip() { let mut x = BTreeSet::new(); -- cgit 1.4.1-3-g733a5 From 8fb05491514c5cfb3c3aa03e0266389fa0b29ed0 Mon Sep 17 00:00:00 2001 From: Fabian Drinck Date: Sun, 17 Mar 2019 17:40:25 +0100 Subject: Fix doc tests --- src/liballoc/borrow.rs | 2 +- src/libcore/cell.rs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/borrow.rs b/src/liballoc/borrow.rs index 74c80a08b12..ee1799fad8e 100644 --- a/src/liballoc/borrow.rs +++ b/src/liballoc/borrow.rs @@ -135,7 +135,7 @@ impl ToOwned for T /// Another example showing how to keep `Cow` in a struct: /// /// ``` -/// use std::borrow::{Cow, ToOwned}; +/// use std::borrow::Cow; /// /// struct Items<'a, X: 'a> where [X]: ToOwned> { /// values: Cow<'a, [X]>, diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 753f10e6a0a..3b888244341 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -1421,7 +1421,6 @@ impl fmt::Display for RefMut<'_, T> { /// /// ``` /// use std::cell::UnsafeCell; -/// use std::marker::Sync; /// /// # #[allow(dead_code)] /// struct NotThreadSafe { -- cgit 1.4.1-3-g733a5 From 79941973af54db7f7b941582fdc9537b2ee95a00 Mon Sep 17 00:00:00 2001 From: Masaki Hara Date: Sun, 28 Oct 2018 15:27:29 +0900 Subject: Make FnBox a subtrait of FnOnce. --- src/liballoc/boxed.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index b2315c6a739..9166f917293 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -735,9 +735,7 @@ impl FusedIterator for Box {} #[rustc_paren_sugar] #[unstable(feature = "fnbox", reason = "will be deprecated if and when `Box` becomes usable", issue = "28796")] -pub trait FnBox { - type Output; - +pub trait FnBox: FnOnce { fn call_box(self: Box, args: A) -> Self::Output; } @@ -746,8 +744,6 @@ pub trait FnBox { impl FnBox for F where F: FnOnce { - type Output = F::Output; - fn call_box(self: Box, args: A) -> F::Output { self.call_once(args) } -- cgit 1.4.1-3-g733a5 From 059ec76d9b2ba33be5d7b092ffeb401590a5d39d Mon Sep 17 00:00:00 2001 From: Masaki Hara Date: Sun, 28 Oct 2018 15:28:15 +0900 Subject: Add Fn* blanket impls for Box. --- src/liballoc/boxed.rs | 33 +++++++++++++++++++++++++++++++++ src/liballoc/lib.rs | 1 + 2 files changed, 34 insertions(+) (limited to 'src/liballoc') diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 9166f917293..09554a1a34d 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -694,6 +694,37 @@ impl ExactSizeIterator for Box { #[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for Box {} +#[cfg(not(stage0))] +#[unstable(feature = "boxed_closure_impls", + reason = "Box relies on unsized rvalues and needs to be tested more", + issue = "48055")] +impl + ?Sized> FnOnce for Box { + type Output = >::Output; + + default extern "rust-call" fn call_once(self, args: A) -> Self::Output { + >::call_once(*self, args) + } +} + +#[cfg(not(stage0))] +#[unstable(feature = "boxed_closure_impls", + reason = "Box relies on unsized rvalues and needs to be tested more", + issue = "48055")] +impl + ?Sized> FnMut for Box { + extern "rust-call" fn call_mut(&mut self, args: A) -> Self::Output { + >::call_mut(self, args) + } +} + +#[cfg(not(stage0))] +#[unstable(feature = "boxed_closure_impls", + reason = "Box relies on unsized rvalues and needs to be tested more", + issue = "48055")] +impl + ?Sized> Fn for Box { + extern "rust-call" fn call(&self, args: A) -> Self::Output { + >::call(self, args) + } +} /// `FnBox` is a version of the `FnOnce` intended for use with boxed /// closure objects. The idea is that where one would normally store a @@ -752,6 +783,7 @@ impl FnBox for F #[unstable(feature = "fnbox", reason = "will be deprecated if and when `Box` becomes usable", issue = "28796")] impl FnOnce for Box + '_> { + #[cfg(stage0)] type Output = R; extern "rust-call" fn call_once(self, args: A) -> R { @@ -762,6 +794,7 @@ impl FnOnce for Box + '_> { #[unstable(feature = "fnbox", reason = "will be deprecated if and when `Box` becomes usable", issue = "28796")] impl FnOnce for Box + Send + '_> { + #[cfg(stage0)] type Output = R; extern "rust-call" fn call_once(self, args: A) -> R { diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 90ff56814fb..9064b4ccd6a 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -107,6 +107,7 @@ #![feature(unboxed_closures)] #![feature(unicode_internals)] #![feature(unsize)] +#![feature(unsized_locals)] #![feature(allocator_internals)] #![feature(on_unimplemented)] #![feature(rustc_const_unstable)] -- cgit 1.4.1-3-g733a5 From a38f29272ef4d04f0cc77e4f8d4fa5fac7ed746d Mon Sep 17 00:00:00 2001 From: Masaki Hara Date: Sun, 10 Feb 2019 19:25:56 +0900 Subject: We already have unsized_locals in stage0. --- src/liballoc/boxed.rs | 9 --------- 1 file changed, 9 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 09554a1a34d..864add1ecfe 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -694,7 +694,6 @@ impl ExactSizeIterator for Box { #[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for Box {} -#[cfg(not(stage0))] #[unstable(feature = "boxed_closure_impls", reason = "Box relies on unsized rvalues and needs to be tested more", issue = "48055")] @@ -706,7 +705,6 @@ impl + ?Sized> FnOnce for Box { } } -#[cfg(not(stage0))] #[unstable(feature = "boxed_closure_impls", reason = "Box relies on unsized rvalues and needs to be tested more", issue = "48055")] @@ -716,7 +714,6 @@ impl + ?Sized> FnMut for Box { } } -#[cfg(not(stage0))] #[unstable(feature = "boxed_closure_impls", reason = "Box relies on unsized rvalues and needs to be tested more", issue = "48055")] @@ -783,9 +780,6 @@ impl FnBox for F #[unstable(feature = "fnbox", reason = "will be deprecated if and when `Box` becomes usable", issue = "28796")] impl FnOnce for Box + '_> { - #[cfg(stage0)] - type Output = R; - extern "rust-call" fn call_once(self, args: A) -> R { self.call_box(args) } @@ -794,9 +788,6 @@ impl FnOnce for Box + '_> { #[unstable(feature = "fnbox", reason = "will be deprecated if and when `Box` becomes usable", issue = "28796")] impl FnOnce for Box + Send + '_> { - #[cfg(stage0)] - type Output = R; - extern "rust-call" fn call_once(self, args: A) -> R { self.call_box(args) } -- cgit 1.4.1-3-g733a5 From 45c0b28bcb6e383cd9d24d3845ee8accda31c889 Mon Sep 17 00:00:00 2001 From: Masaki Hara Date: Mon, 11 Feb 2019 10:34:24 +0900 Subject: Remove FnBox specialization of impl FnOnce for Box. --- src/liballoc/boxed.rs | 18 +----------------- src/test/ui/unsized-locals/fnbox-compat.rs | 13 ------------- src/test/ui/unsized-locals/fnbox-compat.stderr | 11 ----------- 3 files changed, 1 insertion(+), 41 deletions(-) delete mode 100644 src/test/ui/unsized-locals/fnbox-compat.rs delete mode 100644 src/test/ui/unsized-locals/fnbox-compat.stderr (limited to 'src/liballoc') diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 864add1ecfe..d4fe8be36d6 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -700,7 +700,7 @@ impl FusedIterator for Box {} impl + ?Sized> FnOnce for Box { type Output = >::Output; - default extern "rust-call" fn call_once(self, args: A) -> Self::Output { + extern "rust-call" fn call_once(self, args: A) -> Self::Output { >::call_once(*self, args) } } @@ -777,22 +777,6 @@ impl FnBox for F } } -#[unstable(feature = "fnbox", - reason = "will be deprecated if and when `Box` becomes usable", issue = "28796")] -impl FnOnce for Box + '_> { - extern "rust-call" fn call_once(self, args: A) -> R { - self.call_box(args) - } -} - -#[unstable(feature = "fnbox", - reason = "will be deprecated if and when `Box` becomes usable", issue = "28796")] -impl FnOnce for Box + Send + '_> { - extern "rust-call" fn call_once(self, args: A) -> R { - self.call_box(args) - } -} - #[unstable(feature = "coerce_unsized", issue = "27732")] impl, U: ?Sized> CoerceUnsized> for Box {} diff --git a/src/test/ui/unsized-locals/fnbox-compat.rs b/src/test/ui/unsized-locals/fnbox-compat.rs deleted file mode 100644 index c2c385e9fea..00000000000 --- a/src/test/ui/unsized-locals/fnbox-compat.rs +++ /dev/null @@ -1,13 +0,0 @@ -#![feature(fnbox)] - -use std::boxed::FnBox; - -fn call_it(f: Box T>) -> T { - f(&42) - //~^ERROR implementation of `std::ops::FnOnce` is not general enough -} - -fn main() { - let s = "hello".to_owned(); - assert_eq!(&call_it(Box::new(|_| s)) as &str, "hello"); -} diff --git a/src/test/ui/unsized-locals/fnbox-compat.stderr b/src/test/ui/unsized-locals/fnbox-compat.stderr deleted file mode 100644 index c37bfaa47f7..00000000000 --- a/src/test/ui/unsized-locals/fnbox-compat.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error: implementation of `std::ops::FnOnce` is not general enough - --> $DIR/fnbox-compat.rs:6:5 - | -LL | f(&42) - | ^^^^^^ - | - = note: `std::ops::FnOnce<(&'0 i32,)>` would have to be implemented for the type `std::boxed::Box<(dyn for<'r> std::boxed::FnBox<(&'r i32,), Output=T> + 'static)>`, for some specific lifetime `'0` - = note: but `std::ops::FnOnce<(&'1 i32,)>` is actually implemented for the type `std::boxed::Box<(dyn std::boxed::FnBox<(&'1 i32,), Output=T> + '_)>`, for some specific lifetime `'1` - -error: aborting due to previous error - -- cgit 1.4.1-3-g733a5 From ecc3e89dd072ed20d9aa6d53be0ab1c44d160232 Mon Sep 17 00:00:00 2001 From: Charles Lew Date: Mon, 11 Feb 2019 11:09:26 +0900 Subject: Stabilize boxed_closure_impls in 1.35.0. --- .../src/library-features/boxed-closure-impls.md | 98 ---------------------- src/liballoc/boxed.rs | 12 +-- src/test/run-pass/unsized-locals/box-fnonce.rs | 2 - 3 files changed, 3 insertions(+), 109 deletions(-) delete mode 100644 src/doc/unstable-book/src/library-features/boxed-closure-impls.md (limited to 'src/liballoc') diff --git a/src/doc/unstable-book/src/library-features/boxed-closure-impls.md b/src/doc/unstable-book/src/library-features/boxed-closure-impls.md deleted file mode 100644 index 5ceb54ff3b9..00000000000 --- a/src/doc/unstable-book/src/library-features/boxed-closure-impls.md +++ /dev/null @@ -1,98 +0,0 @@ -# `boxed_closure_impls` - -The tracking issue for this feature is [#48055] - -[#48055]: https://github.com/rust-lang/rust/issues/48055 - ------------------------- - -This includes the following blanket impls for closure traits: - -```rust,ignore -impl + ?Sized> FnOnce for Box { - // ... -} -impl + ?Sized> FnMut for Box { - // ... -} -impl + ?Sized> Fn for Box { - // ... -} -``` - -## Usage - -`Box` can be used almost transparently. You can even use `Box` now. - -```rust -#![feature(boxed_closure_impls)] - -fn main() { - let resource = "hello".to_owned(); - // Create a boxed once-callable closure - let f: Box = Box::new(|x| { - let s = resource; - println!("{}", x); - println!("{}", s); - }); - - // Call it - f(&42); -} -``` - -## The reason for instability - -This is unstable because of the first impl. - -It would have been easy if we're allowed to tighten the bound: - -```rust,ignore -impl + ?Sized> FnOnce for Box { - // ... -} -``` - -However, `Box` drops out of the modified impl. -To rescue this, we had had a temporary solution called [`fnbox`][fnbox]. - -[fnbox]: library-features/fnbox.html - -Unfortunately, due to minor coherence reasons, `fnbox` and -`FnOnce for Box` had not been able to coexist. -We had preferred `fnbox` for the time being. - -Now, as [`unsized_locals`][unsized_locals] is implemented, we can just write the -original impl: - -[unsized_locals]: language-features/unsized-locals.html - -```rust,ignore -impl + ?Sized> FnOnce for Box { - type Output = >::Output; - - extern "rust-call" fn call_once(self, args: A) -> Self::Output { - // *self is an unsized rvalue - >::call_once(*self, args) - } -} -``` - -However, since `unsized_locals` is a very young feature, we're careful about -this `FnOnce` impl now. - -There's another reason for instability: for compatibility with `fnbox`, -we currently allow specialization of the `Box` impl: - -```rust,ignore -impl + ?Sized> FnOnce for Box { - type Output = >::Output; - - // we have "default" here - default extern "rust-call" fn call_once(self, args: A) -> Self::Output { - >::call_once(*self, args) - } -} -``` - -This isn't what we desire in the long term. diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index d4fe8be36d6..f6dee7c9eef 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -694,9 +694,7 @@ impl ExactSizeIterator for Box { #[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for Box {} -#[unstable(feature = "boxed_closure_impls", - reason = "Box relies on unsized rvalues and needs to be tested more", - issue = "48055")] +#[stable(feature = "boxed_closure_impls", since = "1.35.0")] impl + ?Sized> FnOnce for Box { type Output = >::Output; @@ -705,18 +703,14 @@ impl + ?Sized> FnOnce for Box { } } -#[unstable(feature = "boxed_closure_impls", - reason = "Box relies on unsized rvalues and needs to be tested more", - issue = "48055")] +#[stable(feature = "boxed_closure_impls", since = "1.35.0")] impl + ?Sized> FnMut for Box { extern "rust-call" fn call_mut(&mut self, args: A) -> Self::Output { >::call_mut(self, args) } } -#[unstable(feature = "boxed_closure_impls", - reason = "Box relies on unsized rvalues and needs to be tested more", - issue = "48055")] +#[stable(feature = "boxed_closure_impls", since = "1.35.0")] impl + ?Sized> Fn for Box { extern "rust-call" fn call(&self, args: A) -> Self::Output { >::call(self, args) diff --git a/src/test/run-pass/unsized-locals/box-fnonce.rs b/src/test/run-pass/unsized-locals/box-fnonce.rs index 97007a94239..16bdeae4fad 100644 --- a/src/test/run-pass/unsized-locals/box-fnonce.rs +++ b/src/test/run-pass/unsized-locals/box-fnonce.rs @@ -1,5 +1,3 @@ -#![feature(boxed_closure_impls)] - fn call_it(f: Box T>) -> T { f() } -- cgit 1.4.1-3-g733a5 From 0730a01c5ca3b0e8760d72a05c47d4199bd64728 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 5 Apr 2019 14:51:07 -0700 Subject: Use for_each to extend collections This updates the `Extend` implementations to use `for_each` for many collections: `BinaryHeap`, `BTreeMap`, `BTreeSet`, `LinkedList`, `Path`, `TokenStream`, `VecDeque`, and `Wtf8Buf`. Folding with `for_each` enables better performance than a `for`-loop for some iterators, especially if they can just forward to internal iterators, like `Chain` and `FlatMap` do. --- src/liballoc/collections/binary_heap.rs | 4 +--- src/liballoc/collections/btree/map.rs | 4 ++-- src/liballoc/collections/btree/set.rs | 4 ++-- src/liballoc/collections/linked_list.rs | 4 +--- src/liballoc/collections/vec_deque.rs | 4 +--- src/libproc_macro/lib.rs | 4 +--- src/libstd/path.rs | 4 +--- src/libstd/sys_common/wtf8.rs | 4 +--- 8 files changed, 10 insertions(+), 22 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/collections/binary_heap.rs b/src/liballoc/collections/binary_heap.rs index a171f128c24..8c142a3d317 100644 --- a/src/liballoc/collections/binary_heap.rs +++ b/src/liballoc/collections/binary_heap.rs @@ -1177,9 +1177,7 @@ impl BinaryHeap { self.reserve(lower); - for elem in iterator { - self.push(elem); - } + iterator.for_each(move |elem| self.push(elem)); } } diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs index ce29978856f..6b079fc87cc 100644 --- a/src/liballoc/collections/btree/map.rs +++ b/src/liballoc/collections/btree/map.rs @@ -1727,9 +1727,9 @@ impl FromIterator<(K, V)> for BTreeMap { impl Extend<(K, V)> for BTreeMap { #[inline] fn extend>(&mut self, iter: T) { - for (k, v) in iter { + iter.into_iter().for_each(move |(k, v)| { self.insert(k, v); - } + }); } } diff --git a/src/liballoc/collections/btree/set.rs b/src/liballoc/collections/btree/set.rs index e71767077ca..16a96ca19b8 100644 --- a/src/liballoc/collections/btree/set.rs +++ b/src/liballoc/collections/btree/set.rs @@ -883,9 +883,9 @@ impl<'a, T> IntoIterator for &'a BTreeSet { impl Extend for BTreeSet { #[inline] fn extend>(&mut self, iter: Iter) { - for elem in iter { + iter.into_iter().for_each(move |elem| { self.insert(elem); - } + }); } } diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs index c2ee2e63156..d6d84a4f083 100644 --- a/src/liballoc/collections/linked_list.rs +++ b/src/liballoc/collections/linked_list.rs @@ -1107,9 +1107,7 @@ impl Extend for LinkedList { impl SpecExtend for LinkedList { default fn spec_extend(&mut self, iter: I) { - for elt in iter { - self.push_back(elt); - } + iter.into_iter().for_each(move |elt| self.push_back(elt)); } } diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index 4e90f783ec6..4bea615ab86 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -2677,9 +2677,7 @@ impl<'a, T> IntoIterator for &'a mut VecDeque { #[stable(feature = "rust1", since = "1.0.0")] impl Extend for VecDeque { fn extend>(&mut self, iter: T) { - for elt in iter { - self.push_back(elt); - } + iter.into_iter().for_each(move |elt| self.push_back(elt)); } } diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index 03905f3e705..1e0f1ed578a 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -160,9 +160,7 @@ impl iter::FromIterator for TokenStream { impl iter::FromIterator for TokenStream { fn from_iter>(streams: I) -> Self { let mut builder = bridge::client::TokenStreamBuilder::new(); - for stream in streams { - builder.push(stream.0); - } + streams.into_iter().for_each(|stream| builder.push(stream.0)); TokenStream(builder.build()) } } diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 71e82f0a9b0..1bbda9b5bcb 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -1551,9 +1551,7 @@ impl> iter::FromIterator

for PathBuf { #[stable(feature = "rust1", since = "1.0.0")] impl> iter::Extend

for PathBuf { fn extend>(&mut self, iter: I) { - for p in iter { - self.push(p.as_ref()) - } + iter.into_iter().for_each(move |p| self.push(p.as_ref())); } } diff --git a/src/libstd/sys_common/wtf8.rs b/src/libstd/sys_common/wtf8.rs index 7fe1818291e..f17020de44e 100644 --- a/src/libstd/sys_common/wtf8.rs +++ b/src/libstd/sys_common/wtf8.rs @@ -388,9 +388,7 @@ impl Extend for Wtf8Buf { let (low, _high) = iterator.size_hint(); // Lower bound of one byte per code point (ASCII only) self.bytes.reserve(low); - for code_point in iterator { - self.push(code_point); - } + iterator.for_each(move |code_point| self.push(code_point)); } } -- cgit 1.4.1-3-g733a5 From 1691e06db661a19a5e25276c18cd165386f027bb Mon Sep 17 00:00:00 2001 From: Taylor Cramer Date: Mon, 11 Mar 2019 16:56:00 -0700 Subject: Future-proof the Futures API --- src/liballoc/boxed.rs | 6 +- src/libcore/future/future.rs | 18 ++-- src/libcore/task/mod.rs | 2 +- src/libcore/task/wake.rs | 101 ++++++++++++++++++++- src/libstd/future.rs | 61 ++++++++----- src/libstd/macros.rs | 2 +- src/libstd/panic.rs | 6 +- src/test/compile-fail/must_use-in-stdlib-traits.rs | 4 +- src/test/run-pass/async-await.rs | 15 ++- src/test/run-pass/auxiliary/arc_wake.rs | 14 +-- src/test/run-pass/futures-api.rs | 17 ++-- 11 files changed, 176 insertions(+), 70 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index b2315c6a739..d75a0c298c2 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -81,7 +81,7 @@ use core::ops::{ CoerceUnsized, DispatchFromDyn, Deref, DerefMut, Receiver, Generator, GeneratorState }; use core::ptr::{self, NonNull, Unique}; -use core::task::{Waker, Poll}; +use core::task::{Context, Poll}; use crate::vec::Vec; use crate::raw_vec::RawVec; @@ -914,7 +914,7 @@ impl Generator for Pin> { impl Future for Box { type Output = F::Output; - fn poll(mut self: Pin<&mut Self>, waker: &Waker) -> Poll { - F::poll(Pin::new(&mut *self), waker) + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + F::poll(Pin::new(&mut *self), cx) } } diff --git a/src/libcore/future/future.rs b/src/libcore/future/future.rs index a143b54a61f..114a6b93367 100644 --- a/src/libcore/future/future.rs +++ b/src/libcore/future/future.rs @@ -5,7 +5,7 @@ use marker::Unpin; use ops; use pin::Pin; -use task::{Poll, Waker}; +use task::{Context, Poll}; /// A future represents an asynchronous computation. /// @@ -44,8 +44,9 @@ pub trait Future { /// Once a future has finished, clients should not `poll` it again. /// /// When a future is not ready yet, `poll` returns `Poll::Pending` and - /// stores a clone of the [`Waker`] to be woken once the future can - /// make progress. For example, a future waiting for a socket to become + /// stores a clone of the [`Waker`] copied from the current [`Context`]. + /// This [`Waker`] is then woken once the future can make progress. + /// For example, a future waiting for a socket to become /// readable would call `.clone()` on the [`Waker`] and store it. /// When a signal arrives elsewhere indicating that the socket is readable, /// `[Waker::wake]` is called and the socket future's task is awoken. @@ -88,16 +89,17 @@ pub trait Future { /// /// [`Poll::Pending`]: ../task/enum.Poll.html#variant.Pending /// [`Poll::Ready(val)`]: ../task/enum.Poll.html#variant.Ready + /// [`Context`]: ../task/struct.Context.html /// [`Waker`]: ../task/struct.Waker.html /// [`Waker::wake`]: ../task/struct.Waker.html#method.wake - fn poll(self: Pin<&mut Self>, waker: &Waker) -> Poll; + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll; } impl Future for &mut F { type Output = F::Output; - fn poll(mut self: Pin<&mut Self>, waker: &Waker) -> Poll { - F::poll(Pin::new(&mut **self), waker) + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + F::poll(Pin::new(&mut **self), cx) } } @@ -108,7 +110,7 @@ where { type Output = <

::Target as Future>::Output; - fn poll(self: Pin<&mut Self>, waker: &Waker) -> Poll { - Pin::get_mut(self).as_mut().poll(waker) + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + Pin::get_mut(self).as_mut().poll(cx) } } diff --git a/src/libcore/task/mod.rs b/src/libcore/task/mod.rs index 9b8f5981162..29bae69ea83 100644 --- a/src/libcore/task/mod.rs +++ b/src/libcore/task/mod.rs @@ -8,4 +8,4 @@ mod poll; pub use self::poll::Poll; mod wake; -pub use self::wake::{Waker, RawWaker, RawWakerVTable}; +pub use self::wake::{Context, Waker, RawWaker, RawWakerVTable}; diff --git a/src/libcore/task/wake.rs b/src/libcore/task/wake.rs index 12f812d3bed..979a0792608 100644 --- a/src/libcore/task/wake.rs +++ b/src/libcore/task/wake.rs @@ -3,7 +3,7 @@ issue = "50547")] use fmt; -use marker::Unpin; +use marker::{PhantomData, Unpin}; /// A `RawWaker` allows the implementor of a task executor to create a [`Waker`] /// which provides customized wakeup behavior. @@ -36,6 +36,10 @@ impl RawWaker { /// The `vtable` customizes the behavior of a `Waker` which gets created /// from a `RawWaker`. For each operation on the `Waker`, the associated /// function in the `vtable` of the underlying `RawWaker` will be called. + #[rustc_promotable] + #[unstable(feature = "futures_api", + reason = "futures in libcore are unstable", + issue = "50547")] pub const fn new(data: *const (), vtable: &'static RawWakerVTable) -> RawWaker { RawWaker { data, @@ -63,21 +67,105 @@ pub struct RawWakerVTable { /// required for this additional instance of a [`RawWaker`] and associated /// task. Calling `wake` on the resulting [`RawWaker`] should result in a wakeup /// of the same task that would have been awoken by the original [`RawWaker`]. - pub clone: unsafe fn(*const ()) -> RawWaker, + clone: unsafe fn(*const ()) -> RawWaker, /// This function will be called when `wake` is called on the [`Waker`]. /// It must wake up the task associated with this [`RawWaker`]. /// /// The implemention of this function must not consume the provided data /// pointer. - pub wake: unsafe fn(*const ()), + wake: unsafe fn(*const ()), + + /// This function gets called when a [`RawWaker`] gets dropped. + /// + /// The implementation of this function must make sure to release any + /// resources that are associated with this instance of a [`RawWaker`] and + /// associated task. + drop: unsafe fn(*const ()), +} +impl RawWakerVTable { + /// Creates a new `RawWakerVTable` from the provided `clone`, `wake`, and + /// `drop` functions. + /// + /// # `clone` + /// + /// This function will be called when the [`RawWaker`] gets cloned, e.g. when + /// the [`Waker`] in which the [`RawWaker`] is stored gets cloned. + /// + /// The implementation of this function must retain all resources that are + /// required for this additional instance of a [`RawWaker`] and associated + /// task. Calling `wake` on the resulting [`RawWaker`] should result in a wakeup + /// of the same task that would have been awoken by the original [`RawWaker`]. + /// + /// # `wake` + /// + /// This function will be called when `wake` is called on the [`Waker`]. + /// It must wake up the task associated with this [`RawWaker`]. + /// + /// The implemention of this function must not consume the provided data + /// pointer. + /// + /// # `drop` + /// /// This function gets called when a [`RawWaker`] gets dropped. /// /// The implementation of this function must make sure to release any /// resources that are associated with this instance of a [`RawWaker`] and /// associated task. - pub drop: unsafe fn(*const ()), + #[rustc_promotable] + #[unstable(feature = "futures_api", + reason = "futures in libcore are unstable", + issue = "50547")] + pub const fn new( + clone: unsafe fn(*const ()) -> RawWaker, + wake: unsafe fn(*const ()), + drop: unsafe fn(*const ()), + ) -> Self { + Self { + clone, + wake, + drop, + } + } +} + +/// The `Context` of an asynchronous task. +/// +/// Currently, `Context` only serves to provide access to a `&Waker` +/// which can be used to wake the current task. +pub struct Context<'a> { + waker: &'a Waker, + // Ensure we future-proof against variance changes by forcing + // the lifetime to be invariant (argument-position lifetimes + // are contravariant while return-position lifetimes are + // covariant). + _marker: PhantomData &'a ()>, +} + +impl<'a> Context<'a> { + /// Create a new `Context` from a `&Waker`. + #[inline] + pub fn from_waker(waker: &'a Waker) -> Self { + Context { + waker, + _marker: PhantomData, + } + } + + /// Returns a reference to the `Waker` for the current task. + #[inline] + pub fn waker(&self) -> &'a Waker { + &self.waker + } +} + +impl fmt::Debug for Context<'_> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("Context") + .field("waker", &self.waker) + .finish() + } } /// A `Waker` is a handle for waking up a task by notifying its executor that it @@ -98,6 +186,7 @@ unsafe impl Sync for Waker {} impl Waker { /// Wake up the task associated with this `Waker`. + #[inline] pub fn wake(&self) { // The actual wakeup call is delegated through a virtual function call // to the implementation which is defined by the executor. @@ -115,6 +204,7 @@ impl Waker { /// returns `true`, it is guaranteed that the `Waker`s will awaken the same task. /// /// This function is primarily used for optimization purposes. + #[inline] pub fn will_wake(&self, other: &Waker) -> bool { self.waker == other.waker } @@ -124,6 +214,7 @@ impl Waker { /// The behavior of the returned `Waker` is undefined if the contract defined /// in [`RawWaker`]'s and [`RawWakerVTable`]'s documentation is not upheld. /// Therefore this method is unsafe. + #[inline] pub unsafe fn new_unchecked(waker: RawWaker) -> Waker { Waker { waker, @@ -132,6 +223,7 @@ impl Waker { } impl Clone for Waker { + #[inline] fn clone(&self) -> Self { Waker { // SAFETY: This is safe because `Waker::new_unchecked` is the only way @@ -143,6 +235,7 @@ impl Clone for Waker { } impl Drop for Waker { + #[inline] fn drop(&mut self) { // SAFETY: This is safe because `Waker::new_unchecked` is the only way // to initialize `drop` and `data` requiring the user to acknowledge diff --git a/src/libstd/future.rs b/src/libstd/future.rs index aa784746122..898387cb9f5 100644 --- a/src/libstd/future.rs +++ b/src/libstd/future.rs @@ -5,7 +5,7 @@ use core::marker::Unpin; use core::pin::Pin; use core::option::Option; use core::ptr::NonNull; -use core::task::{Waker, Poll}; +use core::task::{Context, Poll}; use core::ops::{Drop, Generator, GeneratorState}; #[doc(inline)] @@ -32,10 +32,10 @@ impl> !Unpin for GenFuture {} #[unstable(feature = "gen_future", issue = "50547")] impl> Future for GenFuture { type Output = T::Return; - fn poll(self: Pin<&mut Self>, waker: &Waker) -> Poll { + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { // Safe because we're !Unpin + !Drop mapping to a ?Unpin value let gen = unsafe { Pin::map_unchecked_mut(self, |s| &mut s.0) }; - set_task_waker(waker, || match gen.resume() { + set_task_context(cx, || match gen.resume() { GeneratorState::Yielded(()) => Poll::Pending, GeneratorState::Complete(x) => Poll::Ready(x), }) @@ -43,61 +43,72 @@ impl> Future for GenFuture { } thread_local! { - static TLS_WAKER: Cell>> = Cell::new(None); + static TLS_CX: Cell>>> = Cell::new(None); } -struct SetOnDrop(Option>); +struct SetOnDrop(Option>>); impl Drop for SetOnDrop { fn drop(&mut self) { - TLS_WAKER.with(|tls_waker| { - tls_waker.set(self.0.take()); + TLS_CX.with(|tls_cx| { + tls_cx.set(self.0.take()); }); } } #[unstable(feature = "gen_future", issue = "50547")] /// Sets the thread-local task context used by async/await futures. -pub fn set_task_waker(waker: &Waker, f: F) -> R +pub fn set_task_context(cx: &mut Context<'_>, f: F) -> R where F: FnOnce() -> R { - let old_waker = TLS_WAKER.with(|tls_waker| { - tls_waker.replace(Some(NonNull::from(waker))) + // transmute the context's lifetime to 'static so we can store it. + let cx = unsafe { + core::mem::transmute::<&mut Context<'_>, &mut Context<'static>>(cx) + }; + let old_cx = TLS_CX.with(|tls_cx| { + tls_cx.replace(Some(NonNull::from(cx))) }); - let _reset_waker = SetOnDrop(old_waker); + let _reset = SetOnDrop(old_cx); f() } #[unstable(feature = "gen_future", issue = "50547")] -/// Retrieves the thread-local task waker used by async/await futures. +/// Retrieves the thread-local task context used by async/await futures. /// -/// This function acquires exclusive access to the task waker. +/// This function acquires exclusive access to the task context. /// -/// Panics if no waker has been set or if the waker has already been -/// retrieved by a surrounding call to get_task_waker. -pub fn get_task_waker(f: F) -> R +/// Panics if no context has been set or if the context has already been +/// retrieved by a surrounding call to get_task_context. +pub fn get_task_context(f: F) -> R where - F: FnOnce(&Waker) -> R + F: FnOnce(&mut Context<'_>) -> R { - let waker_ptr = TLS_WAKER.with(|tls_waker| { + let cx_ptr = TLS_CX.with(|tls_cx| { // Clear the entry so that nested `get_task_waker` calls // will fail or set their own value. - tls_waker.replace(None) + tls_cx.replace(None) }); - let _reset_waker = SetOnDrop(waker_ptr); + let _reset = SetOnDrop(cx_ptr); - let waker_ptr = waker_ptr.expect( - "TLS Waker not set. This is a rustc bug. \ + let mut cx_ptr = cx_ptr.expect( + "TLS Context not set. This is a rustc bug. \ Please file an issue on https://github.com/rust-lang/rust."); - unsafe { f(waker_ptr.as_ref()) } + + // Safety: we've ensured exclusive access to the context by + // removing the pointer from TLS, only to be replaced once + // we're done with it. + // + // The pointer that was inserted came from an `&mut Context<'_>`, + // so it is safe to treat as mutable. + unsafe { f(cx_ptr.as_mut()) } } #[unstable(feature = "gen_future", issue = "50547")] /// Polls a future in the current thread-local task waker. -pub fn poll_with_tls_waker(f: Pin<&mut F>) -> Poll +pub fn poll_with_tls_context(f: Pin<&mut F>) -> Poll where F: Future { - get_task_waker(|waker| F::poll(f, waker)) + get_task_context(|cx| F::poll(f, cx)) } diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index be4db1f737d..44ca56e2611 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -346,7 +346,7 @@ macro_rules! r#await { let mut pinned = $e; loop { if let $crate::task::Poll::Ready(x) = - $crate::future::poll_with_tls_waker(unsafe { + $crate::future::poll_with_tls_context(unsafe { $crate::pin::Pin::new_unchecked(&mut pinned) }) { diff --git a/src/libstd/panic.rs b/src/libstd/panic.rs index cc147d851de..5a8101e2301 100644 --- a/src/libstd/panic.rs +++ b/src/libstd/panic.rs @@ -12,7 +12,7 @@ use crate::panicking; use crate::ptr::{Unique, NonNull}; use crate::rc::Rc; use crate::sync::{Arc, Mutex, RwLock, atomic}; -use crate::task::{Waker, Poll}; +use crate::task::{Context, Poll}; use crate::thread::Result; #[stable(feature = "panic_hooks", since = "1.10.0")] @@ -323,9 +323,9 @@ impl fmt::Debug for AssertUnwindSafe { impl Future for AssertUnwindSafe { type Output = F::Output; - fn poll(self: Pin<&mut Self>, waker: &Waker) -> Poll { + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let pinned_field = unsafe { Pin::map_unchecked_mut(self, |x| &mut x.0) }; - F::poll(pinned_field, waker) + F::poll(pinned_field, cx) } } diff --git a/src/test/compile-fail/must_use-in-stdlib-traits.rs b/src/test/compile-fail/must_use-in-stdlib-traits.rs index b4f07ab3321..503b39e181a 100644 --- a/src/test/compile-fail/must_use-in-stdlib-traits.rs +++ b/src/test/compile-fail/must_use-in-stdlib-traits.rs @@ -4,7 +4,7 @@ use std::iter::Iterator; use std::future::Future; -use std::task::{Poll, Waker}; +use std::task::{Context, Poll}; use std::pin::Pin; use std::unimplemented; @@ -13,7 +13,7 @@ struct MyFuture; impl Future for MyFuture { type Output = u32; - fn poll(self: Pin<&mut Self>, waker: &Waker) -> Poll { + fn poll(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll { Poll::Pending } } diff --git a/src/test/run-pass/async-await.rs b/src/test/run-pass/async-await.rs index 72af5162992..4f5f7724ad0 100644 --- a/src/test/run-pass/async-await.rs +++ b/src/test/run-pass/async-await.rs @@ -1,7 +1,7 @@ // edition:2018 // aux-build:arc_wake.rs -#![feature(arbitrary_self_types, async_await, await_macro, futures_api)] +#![feature(async_await, await_macro, futures_api)] extern crate arc_wake; @@ -11,9 +11,7 @@ use std::sync::{ Arc, atomic::{self, AtomicUsize}, }; -use std::task::{ - Poll, Waker, -}; +use std::task::{Context, Poll}; use arc_wake::ArcWake; struct Counter { @@ -32,11 +30,11 @@ fn wake_and_yield_once() -> WakeOnceThenComplete { WakeOnceThenComplete(false) } impl Future for WakeOnceThenComplete { type Output = (); - fn poll(mut self: Pin<&mut Self>, waker: &Waker) -> Poll<()> { + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> { if self.0 { Poll::Ready(()) } else { - waker.wake(); + cx.waker().wake(); self.0 = true; Poll::Pending } @@ -146,10 +144,11 @@ where let mut fut = Box::pin(f(9)); let counter = Arc::new(Counter { wakes: AtomicUsize::new(0) }); let waker = ArcWake::into_waker(counter.clone()); + let mut cx = Context::from_waker(&waker); assert_eq!(0, counter.wakes.load(atomic::Ordering::SeqCst)); - assert_eq!(Poll::Pending, fut.as_mut().poll(&waker)); + assert_eq!(Poll::Pending, fut.as_mut().poll(&mut cx)); assert_eq!(1, counter.wakes.load(atomic::Ordering::SeqCst)); - assert_eq!(Poll::Ready(9), fut.as_mut().poll(&waker)); + assert_eq!(Poll::Ready(9), fut.as_mut().poll(&mut cx)); } fn main() { diff --git a/src/test/run-pass/auxiliary/arc_wake.rs b/src/test/run-pass/auxiliary/arc_wake.rs index 034e378af7f..74ec56f5517 100644 --- a/src/test/run-pass/auxiliary/arc_wake.rs +++ b/src/test/run-pass/auxiliary/arc_wake.rs @@ -1,19 +1,19 @@ // edition:2018 -#![feature(arbitrary_self_types, futures_api)] +#![feature(futures_api)] use std::sync::Arc; use std::task::{ - Poll, Waker, RawWaker, RawWakerVTable, + Waker, RawWaker, RawWakerVTable, }; macro_rules! waker_vtable { ($ty:ident) => { - &RawWakerVTable { - clone: clone_arc_raw::<$ty>, - drop: drop_arc_raw::<$ty>, - wake: wake_arc_raw::<$ty>, - } + &RawWakerVTable::new( + clone_arc_raw::<$ty>, + wake_arc_raw::<$ty>, + drop_arc_raw::<$ty>, + ) }; } diff --git a/src/test/run-pass/futures-api.rs b/src/test/run-pass/futures-api.rs index fd4b585d345..5d0b0db510f 100644 --- a/src/test/run-pass/futures-api.rs +++ b/src/test/run-pass/futures-api.rs @@ -1,7 +1,6 @@ // aux-build:arc_wake.rs -#![feature(arbitrary_self_types, futures_api)] -#![allow(unused)] +#![feature(futures_api)] extern crate arc_wake; @@ -12,7 +11,7 @@ use std::sync::{ atomic::{self, AtomicUsize}, }; use std::task::{ - Poll, Waker, + Context, Poll, }; use arc_wake::ArcWake; @@ -30,8 +29,9 @@ struct MyFuture; impl Future for MyFuture { type Output = (); - fn poll(self: Pin<&mut Self>, waker: &Waker) -> Poll { + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { // Wake twice + let waker = cx.waker(); waker.wake(); waker.wake(); Poll::Ready(()) @@ -44,10 +44,11 @@ fn test_waker() { }); let waker = ArcWake::into_waker(counter.clone()); assert_eq!(2, Arc::strong_count(&counter)); - - assert_eq!(Poll::Ready(()), Pin::new(&mut MyFuture).poll(&waker)); - assert_eq!(2, counter.wakes.load(atomic::Ordering::SeqCst)); - + { + let mut context = Context::from_waker(&waker); + assert_eq!(Poll::Ready(()), Pin::new(&mut MyFuture).poll(&mut context)); + assert_eq!(2, counter.wakes.load(atomic::Ordering::SeqCst)); + } drop(waker); assert_eq!(1, Arc::strong_count(&counter)); } -- cgit 1.4.1-3-g733a5 From 08b0aca05e3709766fd7e0e01ec56a8511e4c46b Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Tue, 9 Apr 2019 13:40:21 -0700 Subject: string: implement From<&String> for String Allow Strings to be created from borrowed Strings. This is mostly to make things like passing &String to an `impl Into` parameter frictionless. --- src/liballoc/string.rs | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/liballoc') diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index a3e2098695f..ace2b3ebf55 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -2179,6 +2179,14 @@ impl From<&str> for String { } } +#[stable(feature = "from_ref_string", since = "1.35.0")] +impl From<&String> for String { + #[inline] + fn from(s: &String) -> String { + s.clone() + } +} + // note: test pulls in libstd, which causes errors here #[cfg(not(test))] #[stable(feature = "string_from_box", since = "1.18.0")] -- cgit 1.4.1-3-g733a5 From 81a1121341f4c5af6d224d25757fba0341b62b43 Mon Sep 17 00:00:00 2001 From: John Kåre Alsaker Date: Sat, 6 Apr 2019 10:37:00 +0200 Subject: Update cmake, cc and compiler_builtins for VS 2019 support --- src/bootstrap/Cargo.toml | 4 ++-- src/liballoc/Cargo.toml | 2 +- src/librustc_asan/Cargo.toml | 2 +- src/librustc_lsan/Cargo.toml | 2 +- src/librustc_msan/Cargo.toml | 2 +- src/librustc_tsan/Cargo.toml | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src/liballoc') diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index 0f7b6c22e1c..d4ffd4ad396 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -36,11 +36,11 @@ test = false [dependencies] build_helper = { path = "../build_helper" } -cmake = "0.1.23" +cmake = "0.1.38" filetime = "0.2" num_cpus = "1.0" getopts = "0.2" -cc = "1.0.1" +cc = "1.0.35" libc = "0.2" serde = "1.0.8" serde_derive = "1.0.8" diff --git a/src/liballoc/Cargo.toml b/src/liballoc/Cargo.toml index f6d6c1de8f5..ddf0044c506 100644 --- a/src/liballoc/Cargo.toml +++ b/src/liballoc/Cargo.toml @@ -12,7 +12,7 @@ path = "lib.rs" [dependencies] core = { path = "../libcore" } -compiler_builtins = { version = "0.1.0", features = ['rustc-dep-of-std'] } +compiler_builtins = { version = "0.1.10", features = ['rustc-dep-of-std'] } [dev-dependencies] rand = "0.6" diff --git a/src/librustc_asan/Cargo.toml b/src/librustc_asan/Cargo.toml index 7d9641c83ee..df117de8720 100644 --- a/src/librustc_asan/Cargo.toml +++ b/src/librustc_asan/Cargo.toml @@ -12,7 +12,7 @@ test = false [build-dependencies] build_helper = { path = "../build_helper" } -cmake = "0.1.18" +cmake = "0.1.38" [dependencies] alloc = { path = "../liballoc" } diff --git a/src/librustc_lsan/Cargo.toml b/src/librustc_lsan/Cargo.toml index 9ad53ee6d09..9a24361f44e 100644 --- a/src/librustc_lsan/Cargo.toml +++ b/src/librustc_lsan/Cargo.toml @@ -12,7 +12,7 @@ test = false [build-dependencies] build_helper = { path = "../build_helper" } -cmake = "0.1.18" +cmake = "0.1.38" [dependencies] alloc = { path = "../liballoc" } diff --git a/src/librustc_msan/Cargo.toml b/src/librustc_msan/Cargo.toml index 7d88aa59b3a..bda40785725 100644 --- a/src/librustc_msan/Cargo.toml +++ b/src/librustc_msan/Cargo.toml @@ -12,7 +12,7 @@ test = false [build-dependencies] build_helper = { path = "../build_helper" } -cmake = "0.1.18" +cmake = "0.1.38" [dependencies] alloc = { path = "../liballoc" } diff --git a/src/librustc_tsan/Cargo.toml b/src/librustc_tsan/Cargo.toml index d805833a7ef..82045dd0cdd 100644 --- a/src/librustc_tsan/Cargo.toml +++ b/src/librustc_tsan/Cargo.toml @@ -12,7 +12,7 @@ test = false [build-dependencies] build_helper = { path = "../build_helper" } -cmake = "0.1.18" +cmake = "0.1.38" [dependencies] alloc = { path = "../liballoc" } -- cgit 1.4.1-3-g733a5 From ae2a68bcf575261060eb41e5001d58067f16ae75 Mon Sep 17 00:00:00 2001 From: Oliver Middleton Date: Tue, 9 Apr 2019 15:41:46 +0100 Subject: Fix broken links on std::boxed doc page --- src/liballoc/boxed.rs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/liballoc') diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index cb33b4d4784..6a6a9146e24 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -63,6 +63,8 @@ //! //! [dereferencing]: ../../std/ops/trait.Deref.html //! [`Box`]: struct.Box.html +//! [`Global`]: ../alloc/struct.Global.html +//! [`Layout`]: ../alloc/struct.Layout.html #![stable(feature = "rust1", since = "1.0.0")] -- cgit 1.4.1-3-g733a5 From 2545867b4142fefbf980b976c9bc416d4e89bf85 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Fri, 12 Apr 2019 05:18:36 +0000 Subject: Re-export core::str::{EscapeDebug, EscapeDefault, EscapeUnicode} in std --- src/liballoc/str.rs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/liballoc') diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs index a36804bddff..f10a01d44c8 100644 --- a/src/liballoc/str.rs +++ b/src/liballoc/str.rs @@ -68,6 +68,8 @@ pub use core::str::pattern; pub use core::str::EncodeUtf16; #[stable(feature = "split_ascii_whitespace", since = "1.34.0")] pub use core::str::SplitAsciiWhitespace; +#[stable(feature = "str_escape", since = "1.34.0")] +pub use core::str::{EscapeDebug, EscapeDefault, EscapeUnicode}; #[unstable(feature = "slice_concat_ext", reason = "trait should not have to exist", -- cgit 1.4.1-3-g733a5 From fc928a18bad0b6aa275a6908351b164f6f4abcd6 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Wed, 3 Apr 2019 19:50:28 +0200 Subject: Stabilize the `alloc` crate. This implements RFC 2480: * https://github.com/rust-lang/rfcs/pull/2480 * https://github.com/rust-lang/rfcs/blob/master/text/2480-liballoc.md Closes https://github.com/rust-lang/rust/issues/27783 --- src/liballoc/lib.rs | 5 +---- src/liballoc/prelude/mod.rs | 1 - src/liballoc/raw_vec.rs | 4 ++-- src/libarena/lib.rs | 1 - src/libpanic_unwind/lib.rs | 2 -- src/libstd/lib.rs | 1 - src/test/run-make-fulldeps/sysroot-crates-are-unstable/test.py | 4 ++-- src/test/run-pass/array-slice-vec/vec-macro-no-std.rs | 2 +- src/test/run-pass/extern/extern-prelude-core.rs | 2 +- src/test/run-pass/extern/extern-prelude-core.stderr | 2 +- src/test/run-pass/for-loop-while/for-loop-no-std.rs | 2 +- src/test/run-pass/format-no-std.rs | 2 +- src/test/run-pass/structs-enums/unit-like-struct-drop-run.rs | 3 --- src/test/ui/allocator-submodule.rs | 2 -- src/test/ui/allocator-submodule.stderr | 2 +- src/test/ui/error-codes/E0254.rs | 1 - src/test/ui/error-codes/E0254.stderr | 2 +- src/test/ui/error-codes/E0259.rs | 2 +- src/test/ui/error-codes/E0260.rs | 1 - src/test/ui/error-codes/E0260.stderr | 2 +- src/test/ui/missing/missing-alloc_error_handler.rs | 2 +- src/test/ui/missing/missing-allocator.rs | 2 +- src/test/ui/resolve_self_super_hint.rs | 1 - src/test/ui/resolve_self_super_hint.stderr | 8 ++++---- src/test/ui/rust-2018/remove-extern-crate.fixed | 1 - src/test/ui/rust-2018/remove-extern-crate.rs | 1 - src/test/ui/rust-2018/remove-extern-crate.stderr | 8 ++++---- src/test/ui/unnecessary-extern-crate.rs | 2 +- 28 files changed, 25 insertions(+), 43 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 90ff56814fb..9129ce61d8c 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -51,10 +51,7 @@ //! default global allocator. It is not compatible with the libc allocator API. #![allow(unused_attributes)] -#![unstable(feature = "alloc", - reason = "this library is unlikely to be stabilized in its current \ - form or name", - issue = "27783")] +#![stable(feature = "alloc", since = "1.36.0")] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/", issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/", test(no_crate_inject, attr(allow(unused_variables), deny(warnings))))] diff --git a/src/liballoc/prelude/mod.rs b/src/liballoc/prelude/mod.rs index 33cc51d1732..0534ad3edc7 100644 --- a/src/liballoc/prelude/mod.rs +++ b/src/liballoc/prelude/mod.rs @@ -5,7 +5,6 @@ //! //! ``` //! # #![allow(unused_imports)] -//! # #![feature(alloc)] //! #![feature(alloc_prelude)] //! extern crate alloc; //! use alloc::prelude::v1::*; diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs index fe28fe5095c..d1fc5ac3b30 100644 --- a/src/liballoc/raw_vec.rs +++ b/src/liballoc/raw_vec.rs @@ -256,7 +256,7 @@ impl RawVec { /// # Examples /// /// ``` - /// # #![feature(alloc, raw_vec_internals)] + /// # #![feature(raw_vec_internals)] /// # extern crate alloc; /// # use std::ptr; /// # use alloc::raw_vec::RawVec; @@ -460,7 +460,7 @@ impl RawVec { /// # Examples /// /// ``` - /// # #![feature(alloc, raw_vec_internals)] + /// # #![feature(raw_vec_internals)] /// # extern crate alloc; /// # use std::ptr; /// # use alloc::raw_vec::RawVec; diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index 0a5b79c36aa..f2913295bdc 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -13,7 +13,6 @@ #![deny(rust_2018_idioms)] -#![feature(alloc)] #![feature(core_intrinsics)] #![feature(dropck_eyepatch)] #![feature(raw_vec_internals)] diff --git a/src/libpanic_unwind/lib.rs b/src/libpanic_unwind/lib.rs index 9d3d8f6185b..72ddafb420c 100644 --- a/src/libpanic_unwind/lib.rs +++ b/src/libpanic_unwind/lib.rs @@ -19,8 +19,6 @@ #![deny(rust_2018_idioms)] -#![feature(allocator_api)] -#![feature(alloc)] #![feature(core_intrinsics)] #![feature(lang_items)] #![feature(libc)] diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index d11dee8fc97..ee6ba3f438f 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -229,7 +229,6 @@ #![feature(align_offset)] #![feature(alloc_error_handler)] #![feature(alloc_layout_extra)] -#![feature(alloc)] #![feature(allocator_api)] #![feature(allocator_internals)] #![feature(allow_internal_unsafe)] diff --git a/src/test/run-make-fulldeps/sysroot-crates-are-unstable/test.py b/src/test/run-make-fulldeps/sysroot-crates-are-unstable/test.py index e0fa4e8f5de..855b6421cf8 100644 --- a/src/test/run-make-fulldeps/sysroot-crates-are-unstable/test.py +++ b/src/test/run-make-fulldeps/sysroot-crates-are-unstable/test.py @@ -7,8 +7,8 @@ from subprocess import PIPE, Popen # This is a whitelist of files which are stable crates or simply are not crates, # we don't check for the instability of these crates as they're all stable! -STABLE_CRATES = ['std', 'core', 'proc_macro', 'rsbegin.o', 'rsend.o', 'dllcrt2.o', 'crt2.o', - 'clang_rt'] +STABLE_CRATES = ['std', 'alloc', 'core', 'proc_macro', + 'rsbegin.o', 'rsend.o', 'dllcrt2.o', 'crt2.o', 'clang_rt'] def convert_to_string(s): diff --git a/src/test/run-pass/array-slice-vec/vec-macro-no-std.rs b/src/test/run-pass/array-slice-vec/vec-macro-no-std.rs index 7f7f1e43315..443895f7c48 100644 --- a/src/test/run-pass/array-slice-vec/vec-macro-no-std.rs +++ b/src/test/run-pass/array-slice-vec/vec-macro-no-std.rs @@ -2,7 +2,7 @@ // ignore-emscripten no no_std executables -#![feature(lang_items, start, rustc_private, alloc)] +#![feature(lang_items, start, rustc_private)] #![no_std] extern crate std as other; diff --git a/src/test/run-pass/extern/extern-prelude-core.rs b/src/test/run-pass/extern/extern-prelude-core.rs index a5d31009f9c..f0d43404b00 100644 --- a/src/test/run-pass/extern/extern-prelude-core.rs +++ b/src/test/run-pass/extern/extern-prelude-core.rs @@ -1,5 +1,5 @@ // run-pass -#![feature(extern_prelude, lang_items, start, alloc)] +#![feature(extern_prelude, lang_items, start)] #![no_std] extern crate std as other; diff --git a/src/test/run-pass/extern/extern-prelude-core.stderr b/src/test/run-pass/extern/extern-prelude-core.stderr index 417483af707..8d2a0b7425f 100644 --- a/src/test/run-pass/extern/extern-prelude-core.stderr +++ b/src/test/run-pass/extern/extern-prelude-core.stderr @@ -1,7 +1,7 @@ warning: the feature `extern_prelude` has been stable since 1.30.0 and no longer requires an attribute to enable --> $DIR/extern-prelude-core.rs:2:12 | -LL | #![feature(extern_prelude, lang_items, start, alloc)] +LL | #![feature(extern_prelude, lang_items, start)] | ^^^^^^^^^^^^^^ | = note: #[warn(stable_features)] on by default diff --git a/src/test/run-pass/for-loop-while/for-loop-no-std.rs b/src/test/run-pass/for-loop-while/for-loop-no-std.rs index 877429f5d39..65a33c5f16f 100644 --- a/src/test/run-pass/for-loop-while/for-loop-no-std.rs +++ b/src/test/run-pass/for-loop-while/for-loop-no-std.rs @@ -1,6 +1,6 @@ // run-pass #![allow(unused_imports)] -#![feature(lang_items, start, alloc)] +#![feature(lang_items, start)] #![no_std] extern crate std as other; diff --git a/src/test/run-pass/format-no-std.rs b/src/test/run-pass/format-no-std.rs index 0f3a5c277b4..32f7a4a07c4 100644 --- a/src/test/run-pass/format-no-std.rs +++ b/src/test/run-pass/format-no-std.rs @@ -1,6 +1,6 @@ // ignore-emscripten no no_std executables -#![feature(lang_items, start, alloc)] +#![feature(lang_items, start)] #![no_std] extern crate std as other; diff --git a/src/test/run-pass/structs-enums/unit-like-struct-drop-run.rs b/src/test/run-pass/structs-enums/unit-like-struct-drop-run.rs index dfe73875215..980fd97e2c6 100644 --- a/src/test/run-pass/structs-enums/unit-like-struct-drop-run.rs +++ b/src/test/run-pass/structs-enums/unit-like-struct-drop-run.rs @@ -3,9 +3,6 @@ // Make sure the destructor is run for unit-like structs. - -#![feature(alloc)] - use std::thread; struct Foo; diff --git a/src/test/ui/allocator-submodule.rs b/src/test/ui/allocator-submodule.rs index a1cca50ba98..7a8d86b8da1 100644 --- a/src/test/ui/allocator-submodule.rs +++ b/src/test/ui/allocator-submodule.rs @@ -1,8 +1,6 @@ // Tests that it is possible to create a global allocator in a submodule, rather than in the crate // root. -#![feature(alloc, allocator_api, global_allocator)] - extern crate alloc; use std::{ diff --git a/src/test/ui/allocator-submodule.stderr b/src/test/ui/allocator-submodule.stderr index 26d7aa80eee..91c7c0f6b8e 100644 --- a/src/test/ui/allocator-submodule.stderr +++ b/src/test/ui/allocator-submodule.stderr @@ -1,5 +1,5 @@ error: `global_allocator` cannot be used in submodules - --> $DIR/allocator-submodule.rs:27:5 + --> $DIR/allocator-submodule.rs:25:5 | LL | static MY_HEAP: MyAlloc = MyAlloc; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/error-codes/E0254.rs b/src/test/ui/error-codes/E0254.rs index 706cd347e13..d166aff5657 100644 --- a/src/test/ui/error-codes/E0254.rs +++ b/src/test/ui/error-codes/E0254.rs @@ -1,4 +1,3 @@ -#![feature(alloc)] #![allow(unused_extern_crates, non_camel_case_types)] extern crate alloc; diff --git a/src/test/ui/error-codes/E0254.stderr b/src/test/ui/error-codes/E0254.stderr index c2d013da417..10456fd5a5d 100644 --- a/src/test/ui/error-codes/E0254.stderr +++ b/src/test/ui/error-codes/E0254.stderr @@ -1,5 +1,5 @@ error[E0254]: the name `alloc` is defined multiple times - --> $DIR/E0254.rs:12:5 + --> $DIR/E0254.rs:11:5 | LL | extern crate alloc; | ------------------- previous import of the extern crate `alloc` here diff --git a/src/test/ui/error-codes/E0259.rs b/src/test/ui/error-codes/E0259.rs index cda3db34dfc..c83561be9c6 100644 --- a/src/test/ui/error-codes/E0259.rs +++ b/src/test/ui/error-codes/E0259.rs @@ -1,4 +1,4 @@ -#![feature(alloc, rustc_private)] +#![feature(rustc_private)] #![allow(unused_extern_crates)] extern crate alloc; diff --git a/src/test/ui/error-codes/E0260.rs b/src/test/ui/error-codes/E0260.rs index 80382c0d2fc..73b8934159f 100644 --- a/src/test/ui/error-codes/E0260.rs +++ b/src/test/ui/error-codes/E0260.rs @@ -1,4 +1,3 @@ -#![feature(alloc)] #![allow(unused_extern_crates)] extern crate alloc; diff --git a/src/test/ui/error-codes/E0260.stderr b/src/test/ui/error-codes/E0260.stderr index bfe2ed0cfc7..7d0b3022914 100644 --- a/src/test/ui/error-codes/E0260.stderr +++ b/src/test/ui/error-codes/E0260.stderr @@ -1,5 +1,5 @@ error[E0260]: the name `alloc` is defined multiple times - --> $DIR/E0260.rs:6:1 + --> $DIR/E0260.rs:5:1 | LL | extern crate alloc; | ------------------- previous import of the extern crate `alloc` here diff --git a/src/test/ui/missing/missing-alloc_error_handler.rs b/src/test/ui/missing/missing-alloc_error_handler.rs index 1a9e8688e8a..ae0c067bb5f 100644 --- a/src/test/ui/missing/missing-alloc_error_handler.rs +++ b/src/test/ui/missing/missing-alloc_error_handler.rs @@ -3,7 +3,7 @@ #![no_std] #![crate_type = "staticlib"] -#![feature(panic_handler, alloc_error_handler, alloc)] +#![feature(panic_handler, alloc_error_handler)] #[panic_handler] fn panic(_: &core::panic::PanicInfo) -> ! { diff --git a/src/test/ui/missing/missing-allocator.rs b/src/test/ui/missing/missing-allocator.rs index dbb10d1e7b9..6d867e2e8b4 100644 --- a/src/test/ui/missing/missing-allocator.rs +++ b/src/test/ui/missing/missing-allocator.rs @@ -3,7 +3,7 @@ #![no_std] #![crate_type = "staticlib"] -#![feature(panic_handler, alloc_error_handler, alloc)] +#![feature(panic_handler, alloc_error_handler)] #[panic_handler] fn panic(_: &core::panic::PanicInfo) -> ! { diff --git a/src/test/ui/resolve_self_super_hint.rs b/src/test/ui/resolve_self_super_hint.rs index 91a01cc0fa2..a9423830d90 100644 --- a/src/test/ui/resolve_self_super_hint.rs +++ b/src/test/ui/resolve_self_super_hint.rs @@ -1,4 +1,3 @@ -#![feature(alloc)] #![allow(unused_extern_crates)] mod a { diff --git a/src/test/ui/resolve_self_super_hint.stderr b/src/test/ui/resolve_self_super_hint.stderr index 03214cad8e4..14cdae97d14 100644 --- a/src/test/ui/resolve_self_super_hint.stderr +++ b/src/test/ui/resolve_self_super_hint.stderr @@ -1,17 +1,17 @@ error[E0432]: unresolved import `alloc` - --> $DIR/resolve_self_super_hint.rs:6:9 + --> $DIR/resolve_self_super_hint.rs:5:9 | LL | use alloc::HashMap; | ^^^^^ help: a similar path exists: `self::alloc` error[E0432]: unresolved import `alloc` - --> $DIR/resolve_self_super_hint.rs:11:13 + --> $DIR/resolve_self_super_hint.rs:10:13 | LL | use alloc::HashMap; | ^^^^^ help: a similar path exists: `super::alloc` error[E0432]: unresolved import `alloc` - --> $DIR/resolve_self_super_hint.rs:16:17 + --> $DIR/resolve_self_super_hint.rs:15:17 | LL | use alloc::HashMap; | ^^^^^ @@ -20,7 +20,7 @@ LL | use alloc::HashMap; | help: a similar path exists: `a::alloc` error[E0432]: unresolved import `alloc` - --> $DIR/resolve_self_super_hint.rs:21:21 + --> $DIR/resolve_self_super_hint.rs:20:21 | LL | use alloc::HashMap; | ^^^^^ diff --git a/src/test/ui/rust-2018/remove-extern-crate.fixed b/src/test/ui/rust-2018/remove-extern-crate.fixed index a977e00c013..17449caf84f 100644 --- a/src/test/ui/rust-2018/remove-extern-crate.fixed +++ b/src/test/ui/rust-2018/remove-extern-crate.fixed @@ -4,7 +4,6 @@ // aux-build:remove-extern-crate.rs // compile-flags:--extern remove_extern_crate -#![feature(alloc)] #![warn(rust_2018_idioms)] diff --git a/src/test/ui/rust-2018/remove-extern-crate.rs b/src/test/ui/rust-2018/remove-extern-crate.rs index cafe82d846e..fb2217df000 100644 --- a/src/test/ui/rust-2018/remove-extern-crate.rs +++ b/src/test/ui/rust-2018/remove-extern-crate.rs @@ -4,7 +4,6 @@ // aux-build:remove-extern-crate.rs // compile-flags:--extern remove_extern_crate -#![feature(alloc)] #![warn(rust_2018_idioms)] extern crate core; diff --git a/src/test/ui/rust-2018/remove-extern-crate.stderr b/src/test/ui/rust-2018/remove-extern-crate.stderr index 4e08b7aa6a0..549693201b7 100644 --- a/src/test/ui/rust-2018/remove-extern-crate.stderr +++ b/src/test/ui/rust-2018/remove-extern-crate.stderr @@ -1,24 +1,24 @@ warning: unused extern crate - --> $DIR/remove-extern-crate.rs:10:1 + --> $DIR/remove-extern-crate.rs:9:1 | LL | extern crate core; | ^^^^^^^^^^^^^^^^^^ help: remove it | note: lint level defined here - --> $DIR/remove-extern-crate.rs:8:9 + --> $DIR/remove-extern-crate.rs:7:9 | LL | #![warn(rust_2018_idioms)] | ^^^^^^^^^^^^^^^^ = note: #[warn(unused_extern_crates)] implied by #[warn(rust_2018_idioms)] warning: `extern crate` is not idiomatic in the new edition - --> $DIR/remove-extern-crate.rs:11:1 + --> $DIR/remove-extern-crate.rs:10:1 | LL | extern crate core as another_name; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `use` warning: `extern crate` is not idiomatic in the new edition - --> $DIR/remove-extern-crate.rs:29:5 + --> $DIR/remove-extern-crate.rs:28:5 | LL | extern crate core; | ^^^^^^^^^^^^^^^^^^ help: convert it to a `use` diff --git a/src/test/ui/unnecessary-extern-crate.rs b/src/test/ui/unnecessary-extern-crate.rs index e25b99bcb61..67eaaf4b6c2 100644 --- a/src/test/ui/unnecessary-extern-crate.rs +++ b/src/test/ui/unnecessary-extern-crate.rs @@ -1,7 +1,7 @@ // edition:2018 #![deny(unused_extern_crates)] -#![feature(alloc, test, rustc_private, crate_visibility_modifier)] +#![feature(test, rustc_private, crate_visibility_modifier)] extern crate libc; //~^ ERROR unused extern crate -- cgit 1.4.1-3-g733a5 From 6225b312cf758d078dd37b0e404286aa1b1cbd5b Mon Sep 17 00:00:00 2001 From: Martin Pool Date: Sat, 13 Apr 2019 15:39:49 +1000 Subject: Make clear that format padding doesn't work for Debug As mentioned in https://github.com/rust-lang/rust/issues/46006#issuecomment-345260633 --- src/liballoc/fmt.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/fmt.rs b/src/liballoc/fmt.rs index d2ba9b00191..68cbc366d7b 100644 --- a/src/liballoc/fmt.rs +++ b/src/liballoc/fmt.rs @@ -343,9 +343,10 @@ //! * `^` - the argument is center-aligned in `width` columns //! * `>` - the argument is right-aligned in `width` columns //! -//! Note that alignment may not be implemented by some types. A good way -//! to ensure padding is applied is to format your input, then use this -//! resulting string to pad your output. +//! Note that alignment may not be implemented by some types. In particular, it +//! is not generally implemented for the `Debug` trait. A good way to ensure +//! padding is applied is to format your input, then use this resulting string +//! to pad your output. //! //! ## Sign/`#`/`0` //! -- cgit 1.4.1-3-g733a5 From cdf1d368e2376a94fc433fedc63171ed9e050289 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 14 Apr 2019 10:00:09 +0200 Subject: bump stdsimd; make intra_doc_link_resolution_failure an error again --- src/liballoc/lib.rs | 2 +- src/libcore/lib.rs | 2 +- src/stdsimd | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 7f3acc933d4..41e22d84699 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -62,8 +62,8 @@ #![allow(explicit_outlives_requirements)] #![warn(deprecated_in_future)] -#![warn(intra_doc_link_resolution_failure)] #![warn(missing_debug_implementations)] +#![deny(intra_doc_link_resolution_failure)] // rustdoc is run without -D warnings #![cfg_attr(not(test), feature(generator_trait))] #![cfg_attr(test, feature(test))] diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 63688e70c45..615549f47bb 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -60,8 +60,8 @@ #![warn(deprecated_in_future)] #![warn(missing_docs)] -#![warn(intra_doc_link_resolution_failure)] #![warn(missing_debug_implementations)] +#![deny(intra_doc_link_resolution_failure)] // rustdoc is run without -D warnings #![feature(allow_internal_unstable)] #![feature(arbitrary_self_types)] diff --git a/src/stdsimd b/src/stdsimd index 2792b45c975..2323a858f06 160000 --- a/src/stdsimd +++ b/src/stdsimd @@ -1 +1 @@ -Subproject commit 2792b45c975880038240d477adb0d66f760ac048 +Subproject commit 2323a858f060a0d2a39786a619885608017d538f -- cgit 1.4.1-3-g733a5 From 8ef7ca130271369400719c712369c33a30d6528b Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 14 Apr 2019 10:16:23 +0200 Subject: make lint levels more consistent --- src/liballoc/lib.rs | 6 +++--- src/libstd/lib.rs | 7 ++++--- 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 41e22d84699..d8d61c673af 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -58,13 +58,13 @@ #![no_std] #![needs_allocator] -#![deny(rust_2018_idioms)] -#![allow(explicit_outlives_requirements)] - #![warn(deprecated_in_future)] #![warn(missing_debug_implementations)] #![deny(intra_doc_link_resolution_failure)] // rustdoc is run without -D warnings +#![deny(rust_2018_idioms)] +#![allow(explicit_outlives_requirements)] + #![cfg_attr(not(test), feature(generator_trait))] #![cfg_attr(test, feature(test))] diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index ee6ba3f438f..62bc1991cc9 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -205,9 +205,10 @@ // Don't link to std. We are std. #![no_std] -#![deny(missing_docs)] -#![deny(intra_doc_link_resolution_failure)] -#![deny(missing_debug_implementations)] +//#![warn(deprecated_in_future)] // FIXME: std still has quite a few uses of `mem::uninitialized` +#![warn(missing_docs)] +#![warn(missing_debug_implementations)] +#![deny(intra_doc_link_resolution_failure)] // rustdoc is run without -D warnings #![deny(rust_2018_idioms)] #![allow(explicit_outlives_requirements)] -- cgit 1.4.1-3-g733a5 From 50c615baa2c09694f0ba446c53777e98db88ed01 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 15 Apr 2019 16:34:08 +0200 Subject: warn(missing_docs) in liballoc, and add missing docs --- src/liballoc/borrow.rs | 1 + src/liballoc/boxed.rs | 1 + src/liballoc/lib.rs | 1 + src/liballoc/slice.rs | 10 ++++++++++ 4 files changed, 13 insertions(+) (limited to 'src/liballoc') diff --git a/src/liballoc/borrow.rs b/src/liballoc/borrow.rs index ee1799fad8e..d5e15b3719c 100644 --- a/src/liballoc/borrow.rs +++ b/src/liballoc/borrow.rs @@ -32,6 +32,7 @@ impl<'a, B: ?Sized> Borrow for Cow<'a, B> /// from any borrow of a given type. #[stable(feature = "rust1", since = "1.0.0")] pub trait ToOwned { + /// The resulting type after obtaining ownership. #[stable(feature = "rust1", since = "1.0.0")] type Owned: Borrow; diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 6a6a9146e24..8a3950718d7 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -760,6 +760,7 @@ impl + ?Sized> Fn for Box { #[unstable(feature = "fnbox", reason = "will be deprecated if and when `Box` becomes usable", issue = "28796")] pub trait FnBox: FnOnce { + /// Performs the call operation. fn call_box(self: Box, args: A) -> Self::Output; } diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index d8d61c673af..63b3fbbdaef 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -59,6 +59,7 @@ #![needs_allocator] #![warn(deprecated_in_future)] +#![warn(missing_docs)] #![warn(missing_debug_implementations)] #![deny(intra_doc_link_resolution_failure)] // rustdoc is run without -D warnings diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index f4b2d463778..6eac8487401 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -570,6 +570,16 @@ pub trait SliceConcatExt { #[stable(feature = "rename_connect_to_join", since = "1.3.0")] fn join(&self, sep: &T) -> Self::Output; + /// Flattens a slice of `T` into a single value `Self::Output`, placing a + /// given separator between each. + /// + /// # Examples + /// + /// ``` + /// # #![allow(deprecated)] + /// assert_eq!(["hello", "world"].connect(" "), "hello world"); + /// assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[rustc_deprecated(since = "1.3.0", reason = "renamed to join")] fn connect(&self, sep: &T) -> Self::Output; -- cgit 1.4.1-3-g733a5 From 9b21324db20593d98164616bd1866787617d35fa Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 16 Apr 2019 20:04:17 +0200 Subject: Miri now supports entropy, but is still slow --- src/liballoc/tests/binary_heap.rs | 2 +- src/liballoc/tests/slice.rs | 21 +++++++++++++++------ src/libcore/tests/slice.rs | 4 ++-- 3 files changed, 18 insertions(+), 9 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/tests/binary_heap.rs b/src/liballoc/tests/binary_heap.rs index 0930f8dacd4..0685fa943c0 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 nor entropy +#[cfg(not(miri))] // Miri does not support catching panics fn panic_safe() { static DROP_COUNTER: AtomicUsize = AtomicUsize::new(0); diff --git a/src/liballoc/tests/slice.rs b/src/liballoc/tests/slice.rs index b54c128a024..e2bef515419 100644 --- a/src/liballoc/tests/slice.rs +++ b/src/liballoc/tests/slice.rs @@ -389,7 +389,7 @@ fn test_reverse() { } #[test] -#[cfg(not(miri))] // Miri does not support entropy +#[cfg(not(miri))] // Miri is too slow fn test_sort() { let mut rng = thread_rng(); @@ -466,10 +466,19 @@ fn test_sort() { } #[test] -#[cfg(not(miri))] // Miri does not support entropy fn test_sort_stability() { - for len in (2..25).chain(500..510) { - for _ in 0..10 { + #[cfg(not(miri))] // Miri is too slow + let large_limit = 510; + #[cfg(not(miri))] // Miri is too slow + let rounds = 10; + + #[cfg(miri)] + let large_limit = 500; // effectively skips the large tests + #[cfg(miri)] + let rounds = 1; + + for len in (2..25).chain(500..large_limit) { + for _ in 0..rounds { let mut counts = [0; 10]; // create a vector like [(6, 1), (5, 1), (6, 2), ...], @@ -1397,7 +1406,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 threads nor entropy +#[cfg(not(miri))] // Miri does not support threads fn test_box_slice_clone_panics() { use std::sync::Arc; use std::sync::atomic::{AtomicUsize, Ordering}; @@ -1589,7 +1598,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 threads nor entropy +#[cfg(not(miri))] // Miri does not support threads fn panic_safe() { let prev = panic::take_hook(); panic::set_hook(Box::new(move |info| { diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs index 007283b5f69..a9474230139 100644 --- a/src/libcore/tests/slice.rs +++ b/src/libcore/tests/slice.rs @@ -1024,7 +1024,7 @@ fn test_rotate_right() { #[test] #[cfg(not(target_arch = "wasm32"))] -#[cfg(not(miri))] // Miri does not support entropy +#[cfg(not(miri))] // Miri is too slow fn sort_unstable() { use core::cmp::Ordering::{Equal, Greater, Less}; use core::slice::heapsort; @@ -1095,7 +1095,7 @@ fn sort_unstable() { #[test] #[cfg(not(target_arch = "wasm32"))] -#[cfg(not(miri))] // Miri does not support entropy +#[cfg(not(miri))] // Miri is too slow fn partition_at_index() { use core::cmp::Ordering::{Equal, Greater, Less}; use rand::rngs::SmallRng; -- cgit 1.4.1-3-g733a5 From d55e4b7a259b887202be91708f839a75b234697c Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 17 Apr 2019 09:47:36 +0200 Subject: test sort_unstable in Miri --- src/liballoc/tests/slice.rs | 6 +++--- src/libcore/tests/slice.rs | 15 ++++++++++++--- 2 files changed, 15 insertions(+), 6 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/tests/slice.rs b/src/liballoc/tests/slice.rs index e2bef515419..ad2cd7c95eb 100644 --- a/src/liballoc/tests/slice.rs +++ b/src/liballoc/tests/slice.rs @@ -468,16 +468,16 @@ fn test_sort() { #[test] fn test_sort_stability() { #[cfg(not(miri))] // Miri is too slow - let large_limit = 510; + let large_range = 500..510; #[cfg(not(miri))] // Miri is too slow let rounds = 10; #[cfg(miri)] - let large_limit = 500; // effectively skips the large tests + let large_range = 0..0; // empty range #[cfg(miri)] let rounds = 1; - for len in (2..25).chain(500..large_limit) { + for len in (2..25).chain(large_range) { for _ in 0..rounds { let mut counts = [0; 10]; diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs index a9474230139..acf6b03791f 100644 --- a/src/libcore/tests/slice.rs +++ b/src/libcore/tests/slice.rs @@ -1024,22 +1024,31 @@ fn test_rotate_right() { #[test] #[cfg(not(target_arch = "wasm32"))] -#[cfg(not(miri))] // Miri is too slow fn sort_unstable() { use core::cmp::Ordering::{Equal, Greater, Less}; use core::slice::heapsort; use rand::{FromEntropy, Rng, rngs::SmallRng, seq::SliceRandom}; + #[cfg(not(miri))] // Miri is too slow + let large_range = 500..510; + #[cfg(not(miri))] // Miri is too slow + let rounds = 100; + + #[cfg(miri)] + let large_range = 0..0; // empty range + #[cfg(miri)] + let rounds = 1; + let mut v = [0; 600]; let mut tmp = [0; 600]; let mut rng = SmallRng::from_entropy(); - for len in (2..25).chain(500..510) { + for len in (2..25).chain(large_range) { let v = &mut v[0..len]; let tmp = &mut tmp[0..len]; for &modulus in &[5, 10, 100, 1000] { - for _ in 0..100 { + for _ in 0..rounds { for i in 0..len { v[i] = rng.gen::() % modulus; } -- cgit 1.4.1-3-g733a5 From 29eed6b931c28cb30a42d80c0be11bc900fd356b Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 17 Apr 2019 19:11:56 +0200 Subject: make liballoc internal test suite mostly pass in Miri --- src/liballoc/alloc.rs | 1 + src/liballoc/collections/linked_list.rs | 2 ++ src/liballoc/collections/vec_deque.rs | 11 ++++++++++- src/liballoc/sync.rs | 2 ++ 4 files changed, 15 insertions(+), 1 deletion(-) (limited to 'src/liballoc') diff --git a/src/liballoc/alloc.rs b/src/liballoc/alloc.rs index f3877e51a66..ddc6481eec7 100644 --- a/src/liballoc/alloc.rs +++ b/src/liballoc/alloc.rs @@ -252,6 +252,7 @@ mod tests { } #[bench] + #[cfg(not(miri))] // Miri does not support benchmarks fn alloc_owned_small(b: &mut Bencher) { b.iter(|| { let _: Box<_> = box 10; diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs index d6d84a4f083..cb390aa419e 100644 --- a/src/liballoc/collections/linked_list.rs +++ b/src/liballoc/collections/linked_list.rs @@ -1354,6 +1354,7 @@ mod tests { #[test] #[cfg_attr(target_os = "emscripten", ignore)] + #[cfg(not(miri))] // Miri does not support threads fn test_send() { let n = list_from(&[1, 2, 3]); thread::spawn(move || { @@ -1371,6 +1372,7 @@ mod tests { for _ in 0..25 { fuzz_test(3); fuzz_test(16); + #[cfg(not(miri))] // Miri is too slow fuzz_test(189); } } diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index 4bea615ab86..2ecc1df17de 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -2799,6 +2799,7 @@ mod tests { use super::VecDeque; #[bench] + #[cfg(not(miri))] // Miri does not support benchmarks fn bench_push_back_100(b: &mut test::Bencher) { let mut deq = VecDeque::with_capacity(101); b.iter(|| { @@ -2811,6 +2812,7 @@ mod tests { } #[bench] + #[cfg(not(miri))] // Miri does not support benchmarks fn bench_push_front_100(b: &mut test::Bencher) { let mut deq = VecDeque::with_capacity(101); b.iter(|| { @@ -2823,6 +2825,7 @@ mod tests { } #[bench] + #[cfg(not(miri))] // Miri does not support benchmarks fn bench_pop_back_100(b: &mut test::Bencher) { let mut deq = VecDeque::::with_capacity(101); @@ -2836,6 +2839,7 @@ mod tests { } #[bench] + #[cfg(not(miri))] // Miri does not support benchmarks fn bench_pop_front_100(b: &mut test::Bencher) { let mut deq = VecDeque::::with_capacity(101); @@ -3090,6 +3094,11 @@ mod tests { fn test_vec_from_vecdeque() { use crate::vec::Vec; + #[cfg(not(miri))] // Miri is too slow + let max_pwr = 7; + #[cfg(miri)] + let max_pwr = 5; + fn create_vec_and_test_convert(cap: usize, offset: usize, len: usize) { let mut vd = VecDeque::with_capacity(cap); for _ in 0..offset { @@ -3103,7 +3112,7 @@ mod tests { assert!(vec.into_iter().eq(vd)); } - for cap_pwr in 0..7 { + for cap_pwr in 0..max_pwr { // Make capacity as a (2^x)-1, so that the ring size is 2^x let cap = (2i32.pow(cap_pwr) - 1) as usize; diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index b7d7995b540..466e806663c 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -1678,6 +1678,7 @@ mod tests { #[test] #[cfg_attr(target_os = "emscripten", ignore)] + #[cfg(not(miri))] // Miri does not support threads fn manually_share_arc() { let v = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; let arc_v = Arc::new(v); @@ -1982,6 +1983,7 @@ mod tests { #[test] #[cfg_attr(target_os = "emscripten", ignore)] + #[cfg(not(miri))] // Miri does not support threads fn test_weak_count_locked() { let mut a = Arc::new(atomic::AtomicBool::new(false)); let a2 = a.clone(); -- cgit 1.4.1-3-g733a5 From 2bc8c547cdd9cd2e4f338477eea5860861879565 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 19 Apr 2019 09:06:08 +0200 Subject: move variable down to where it is used --- src/liballoc/collections/vec_deque.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index 2ecc1df17de..d806bd0b1d7 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -3094,11 +3094,6 @@ mod tests { fn test_vec_from_vecdeque() { use crate::vec::Vec; - #[cfg(not(miri))] // Miri is too slow - let max_pwr = 7; - #[cfg(miri)] - let max_pwr = 5; - fn create_vec_and_test_convert(cap: usize, offset: usize, len: usize) { let mut vd = VecDeque::with_capacity(cap); for _ in 0..offset { @@ -3112,6 +3107,11 @@ mod tests { assert!(vec.into_iter().eq(vd)); } + #[cfg(not(miri))] // Miri is too slow + let max_pwr = 7; + #[cfg(miri)] + let max_pwr = 5; + for cap_pwr in 0..max_pwr { // Make capacity as a (2^x)-1, so that the ring size is 2^x let cap = (2i32.pow(cap_pwr) - 1) as usize; -- cgit 1.4.1-3-g733a5 From 8b09d046fedf84ed869204bbe0779a0439bbf9eb Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 18 Apr 2019 11:41:28 +0200 Subject: fix LinkedList invalidating mutable references --- src/liballoc/collections/linked_list.rs | 48 +++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 11 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs index d6d84a4f083..bc1a024e989 100644 --- a/src/liballoc/collections/linked_list.rs +++ b/src/liballoc/collections/linked_list.rs @@ -86,6 +86,9 @@ impl Clone for Iter<'_, T> { /// [`LinkedList`]: struct.LinkedList.html #[stable(feature = "rust1", since = "1.0.0")] pub struct IterMut<'a, T: 'a> { + // We do *not* exclusively own the entire list here, references to node's `element` + // have been handed out by the iterator! So be careful when using this; the methods + // called must be aware that there can be aliasing pointers to `element`. list: &'a mut LinkedList, head: Option>>, tail: Option>>, @@ -143,6 +146,8 @@ impl LinkedList { /// Adds the given node to the front of the list. #[inline] fn push_front_node(&mut self, mut node: Box>) { + // This method takes care not to create mutable references to whole nodes, + // to maintain validity of aliasing pointers into `element`. unsafe { node.next = self.head; node.prev = None; @@ -150,7 +155,8 @@ impl LinkedList { match self.head { None => self.tail = node, - Some(mut head) => head.as_mut().prev = node, + // Not creating new mutable (unique!) references overlapping `element`. + Some(head) => (*head.as_ptr()).prev = node, } self.head = node; @@ -161,13 +167,16 @@ impl LinkedList { /// Removes and returns the node at the front of the list. #[inline] fn pop_front_node(&mut self) -> Option>> { + // This method takes care not to create mutable references to whole nodes, + // to maintain validity of aliasing pointers into `element`. self.head.map(|node| unsafe { let node = Box::from_raw(node.as_ptr()); self.head = node.next; match self.head { None => self.tail = None, - Some(mut head) => head.as_mut().prev = None, + // Not creating new mutable (unique!) references overlapping `element`. + Some(head) => (*head.as_ptr()).prev = None, } self.len -= 1; @@ -178,6 +187,8 @@ impl LinkedList { /// Adds the given node to the back of the list. #[inline] fn push_back_node(&mut self, mut node: Box>) { + // This method takes care not to create mutable references to whole nodes, + // to maintain validity of aliasing pointers into `element`. unsafe { node.next = None; node.prev = self.tail; @@ -185,7 +196,8 @@ impl LinkedList { match self.tail { None => self.head = node, - Some(mut tail) => tail.as_mut().next = node, + // Not creating new mutable (unique!) references overlapping `element`. + Some(tail) => (*tail.as_ptr()).next = node, } self.tail = node; @@ -196,13 +208,16 @@ impl LinkedList { /// Removes and returns the node at the back of the list. #[inline] fn pop_back_node(&mut self) -> Option>> { + // This method takes care not to create mutable references to whole nodes, + // to maintain validity of aliasing pointers into `element`. self.tail.map(|node| unsafe { let node = Box::from_raw(node.as_ptr()); self.tail = node.prev; match self.tail { None => self.head = None, - Some(mut tail) => tail.as_mut().next = None, + // Not creating new mutable (unique!) references overlapping `element`. + Some(tail) => (*tail.as_ptr()).next = None, } self.len -= 1; @@ -213,18 +228,22 @@ impl LinkedList { /// Unlinks the specified node from the current list. /// /// Warning: this will not check that the provided node belongs to the current list. + /// + /// This method takes care not to create mutable references to `element`, to + /// maintain validity of aliasing pointers. #[inline] unsafe fn unlink_node(&mut self, mut node: NonNull>) { - let node = node.as_mut(); + let node = node.as_mut(); // this one is ours now, we can create an &mut. + // Not creating new mutable (unique!) references overlapping `element`. match node.prev { - Some(mut prev) => prev.as_mut().next = node.next.clone(), + Some(prev) => (*prev.as_ptr()).next = node.next.clone(), // this node is the head node None => self.head = node.next.clone(), }; match node.next { - Some(mut next) => next.as_mut().prev = node.prev.clone(), + Some(next) => (*next.as_ptr()).prev = node.prev.clone(), // this node is the tail node None => self.tail = node.prev.clone(), }; @@ -297,6 +316,8 @@ impl LinkedList { match self.tail { None => mem::swap(self, other), Some(mut tail) => { + // `as_mut` is okay here because we have exclusive access to the entirety + // of both lists. if let Some(mut other_head) = other.head.take() { unsafe { tail.as_mut().next = Some(other_head); @@ -916,9 +937,11 @@ impl IterMut<'_, T> { issue = "27794")] pub fn insert_next(&mut self, element: T) { match self.head { + // `push_back` is okay with aliasing `element` references None => self.list.push_back(element), - Some(mut head) => unsafe { - let mut prev = match head.as_ref().prev { + Some(head) => unsafe { + let prev = match head.as_ref().prev { + // `push_front` is okay with aliasing nodes None => return self.list.push_front(element), Some(prev) => prev, }; @@ -929,8 +952,10 @@ impl IterMut<'_, T> { element, })); - prev.as_mut().next = node; - head.as_mut().prev = node; + // Not creating references to entire nodes to not invalidate the + // reference to `element` we handed to the user. + (*prev.as_ptr()).next = node; + (*head.as_ptr()).prev = node; self.list.len += 1; }, @@ -994,6 +1019,7 @@ impl Iterator for DrainFilter<'_, T, F> self.idx += 1; if (self.pred)(&mut node.as_mut().element) { + // `unlink_node` is okay with aliasing `element` references. self.list.unlink_node(node); return Some(Box::from_raw(node.as_ptr()).element); } -- cgit 1.4.1-3-g733a5 From 3e86cf36b5114f201868bf459934fe346a76a2d4 Mon Sep 17 00:00:00 2001 From: Kyle Huey Date: Fri, 19 Apr 2019 21:13:37 -0700 Subject: Add implementations of last in terms of next_back on a bunch of DoubleEndedIterators. r?Manishearth --- src/liballoc/collections/binary_heap.rs | 15 +++++++++++++ src/liballoc/collections/btree/map.rs | 40 +++++++++++++++++++++++++++++++++ src/liballoc/collections/btree/set.rs | 15 +++++++++++++ src/liballoc/string.rs | 4 ++++ src/liballoc/vec.rs | 14 ++++++++++++ src/libcore/ascii.rs | 2 ++ src/libcore/iter/adapters/mod.rs | 5 +++++ src/libcore/slice/mod.rs | 20 +++++++++++++++++ src/libcore/str/mod.rs | 20 +++++++++++++++++ src/libstd/env.rs | 6 +++++ src/libstd/path.rs | 10 +++++++++ src/libstd/sys/unix/args.rs | 2 ++ src/libstd/sys/wasm/args.rs | 4 ++++ src/libstd/sys/windows/args.rs | 2 ++ 14 files changed, 159 insertions(+) (limited to 'src/liballoc') diff --git a/src/liballoc/collections/binary_heap.rs b/src/liballoc/collections/binary_heap.rs index 8c142a3d317..2b1e52cbf05 100644 --- a/src/liballoc/collections/binary_heap.rs +++ b/src/liballoc/collections/binary_heap.rs @@ -968,6 +968,11 @@ impl<'a, T> Iterator for Iter<'a, T> { fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } + + #[inline] + fn last(mut self) -> Option<&'a T> { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1023,6 +1028,11 @@ impl Iterator for IntoIter { fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } + + #[inline] + fn last(mut self) -> Option { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1069,6 +1079,11 @@ impl Iterator for Drain<'_, T> { fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } + + #[inline] + fn last(mut self) -> Option { + self.next_back() + } } #[stable(feature = "drain", since = "1.6.0")] diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs index 6b079fc87cc..414abb00ef1 100644 --- a/src/liballoc/collections/btree/map.rs +++ b/src/liballoc/collections/btree/map.rs @@ -1193,6 +1193,11 @@ impl<'a, K: 'a, V: 'a> Iterator for Iter<'a, K, V> { fn size_hint(&self) -> (usize, Option) { (self.length, Some(self.length)) } + + #[inline] + fn last(mut self) -> Option<(&'a K, &'a V)> { + self.next_back() + } } #[stable(feature = "fused", since = "1.26.0")] @@ -1253,6 +1258,11 @@ impl<'a, K: 'a, V: 'a> Iterator for IterMut<'a, K, V> { fn size_hint(&self) -> (usize, Option) { (self.length, Some(self.length)) } + + #[inline] + fn last(mut self) -> Option<(&'a K, &'a mut V)> { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1359,6 +1369,11 @@ impl Iterator for IntoIter { fn size_hint(&self) -> (usize, Option) { (self.length, Some(self.length)) } + + #[inline] + fn last(mut self) -> Option<(K, V)> { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1421,6 +1436,11 @@ impl<'a, K, V> Iterator for Keys<'a, K, V> { fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } + + #[inline] + fn last(mut self) -> Option<&'a K> { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1458,6 +1478,11 @@ impl<'a, K, V> Iterator for Values<'a, K, V> { fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } + + #[inline] + fn last(mut self) -> Option<&'a V> { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1495,6 +1520,11 @@ impl<'a, K, V> Iterator for Range<'a, K, V> { unsafe { Some(self.next_unchecked()) } } } + + #[inline] + fn last(mut self) -> Option<(&'a K, &'a V)> { + self.next_back() + } } #[stable(feature = "map_values_mut", since = "1.10.0")] @@ -1508,6 +1538,11 @@ impl<'a, K, V> Iterator for ValuesMut<'a, K, V> { fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } + + #[inline] + fn last(mut self) -> Option<&'a mut V> { + self.next_back() + } } #[stable(feature = "map_values_mut", since = "1.10.0")] @@ -1626,6 +1661,11 @@ impl<'a, K, V> Iterator for RangeMut<'a, K, V> { unsafe { Some(self.next_unchecked()) } } } + + #[inline] + fn last(mut self) -> Option<(&'a K, &'a mut V)> { + self.next_back() + } } impl<'a, K, V> RangeMut<'a, K, V> { diff --git a/src/liballoc/collections/btree/set.rs b/src/liballoc/collections/btree/set.rs index 16a96ca19b8..6f2467dfd6b 100644 --- a/src/liballoc/collections/btree/set.rs +++ b/src/liballoc/collections/btree/set.rs @@ -1019,6 +1019,11 @@ impl<'a, T> Iterator for Iter<'a, T> { fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } + + #[inline] + fn last(mut self) -> Option<&'a T> { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> DoubleEndedIterator for Iter<'a, T> { @@ -1044,6 +1049,11 @@ impl Iterator for IntoIter { fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } + + #[inline] + fn last(mut self) -> Option { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] impl DoubleEndedIterator for IntoIter { @@ -1073,6 +1083,11 @@ impl<'a, T> Iterator for Range<'a, T> { fn next(&mut self) -> Option<&'a T> { self.iter.next().map(|(k, _)| k) } + + #[inline] + fn last(mut self) -> Option<&'a T> { + self.next_back() + } } #[stable(feature = "btree_range", since = "1.17.0")] diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index a3e2098695f..f01610a7c3f 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -2367,6 +2367,10 @@ impl Iterator for Drain<'_> { fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } + #[inline] + fn last(mut self) -> Option { + self.next_back() + } } #[stable(feature = "drain", since = "1.6.0")] diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index cd62c3e0524..50bb37b6ed2 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -2385,6 +2385,11 @@ impl Iterator for IntoIter { fn count(self) -> usize { self.len() } + + #[inline] + fn last(mut self) -> Option { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -2504,6 +2509,11 @@ impl Iterator for Drain<'_, T> { fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } + + #[inline] + fn last(mut self) -> Option { + self.next_back() + } } #[stable(feature = "drain", since = "1.6.0")] @@ -2573,6 +2583,10 @@ impl Iterator for Splice<'_, I> { fn size_hint(&self) -> (usize, Option) { self.drain.size_hint() } + + fn last(mut self) -> Option { + self.next_back() + } } #[stable(feature = "vec_splice", since = "1.21.0")] diff --git a/src/libcore/ascii.rs b/src/libcore/ascii.rs index c0ab364380f..ddee02ea232 100644 --- a/src/libcore/ascii.rs +++ b/src/libcore/ascii.rs @@ -117,6 +117,8 @@ impl Iterator for EscapeDefault { type Item = u8; fn next(&mut self) -> Option { self.range.next().map(|i| self.data[i]) } fn size_hint(&self) -> (usize, Option) { self.range.size_hint() } + #[inline] + fn last(mut self) -> Option { self.next_back() } } #[stable(feature = "rust1", since = "1.0.0")] impl DoubleEndedIterator for EscapeDefault { diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs index 3ab404a48d3..d814e8a5958 100644 --- a/src/libcore/iter/adapters/mod.rs +++ b/src/libcore/iter/adapters/mod.rs @@ -73,6 +73,11 @@ impl Iterator for Rev where I: DoubleEndedIterator { { self.iter.position(predicate) } + + #[inline] + fn last(mut self) -> Option { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index bf3dda48dc7..cda4268607f 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -3539,6 +3539,11 @@ impl<'a, T, P> Iterator for Split<'a, T, P> where P: FnMut(&T) -> bool { (1, Some(self.v.len() + 1)) } } + + #[inline] + fn last(mut self) -> Option { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -3637,6 +3642,11 @@ impl<'a, T, P> Iterator for SplitMut<'a, T, P> where P: FnMut(&T) -> bool { (1, Some(self.v.len() + 1)) } } + + #[inline] + fn last(mut self) -> Option { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -3702,6 +3712,11 @@ impl<'a, T, P> Iterator for RSplit<'a, T, P> where P: FnMut(&T) -> bool { fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } + + #[inline] + fn last(mut self) -> Option { + self.next_back() + } } #[stable(feature = "slice_rsplit", since = "1.27.0")] @@ -3766,6 +3781,11 @@ impl<'a, T, P> Iterator for RSplitMut<'a, T, P> where P: FnMut(&T) -> bool { fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } + + #[inline] + fn last(mut self) -> Option { + self.next_back() + } } #[stable(feature = "slice_rsplit", since = "1.27.0")] diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 379c263c04c..41399d21942 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -1331,6 +1331,11 @@ impl<'a> Iterator for Lines<'a> { fn size_hint(&self) -> (usize, Option) { self.0.size_hint() } + + #[inline] + fn last(mut self) -> Option { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1377,6 +1382,11 @@ impl<'a> Iterator for LinesAny<'a> { fn size_hint(&self) -> (usize, Option) { self.0.size_hint() } + + #[inline] + fn last(mut self) -> Option { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -4215,6 +4225,11 @@ impl<'a> Iterator for SplitWhitespace<'a> { fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } + + #[inline] + fn last(mut self) -> Option { + self.next_back() + } } #[stable(feature = "split_whitespace", since = "1.1.0")] @@ -4241,6 +4256,11 @@ impl<'a> Iterator for SplitAsciiWhitespace<'a> { fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } + + #[inline] + fn last(mut self) -> Option { + self.next_back() + } } #[stable(feature = "split_ascii_whitespace", since = "1.34.0")] diff --git a/src/libstd/env.rs b/src/libstd/env.rs index 01b301cb43d..6cb160067f7 100644 --- a/src/libstd/env.rs +++ b/src/libstd/env.rs @@ -740,6 +740,10 @@ impl Iterator for Args { self.inner.next().map(|s| s.into_string().unwrap()) } fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } + #[inline] + fn last(mut self) -> Option { + self.next_back() + } } #[stable(feature = "env", since = "1.0.0")] @@ -775,6 +779,8 @@ impl Iterator for ArgsOs { type Item = OsString; fn next(&mut self) -> Option { self.inner.next() } fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } + #[inline] + fn last(mut self) -> Option { self.next_back() } } #[stable(feature = "env", since = "1.0.0")] diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 1bbda9b5bcb..79ba37b2eb5 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -886,6 +886,11 @@ impl<'a> Iterator for Iter<'a> { fn next(&mut self) -> Option<&'a OsStr> { self.inner.next().map(Component::as_os_str) } + + #[inline] + fn last(mut self) -> Option<&'a OsStr> { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -949,6 +954,11 @@ impl<'a> Iterator for Components<'a> { } None } + + #[inline] + fn last(mut self) -> Option { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libstd/sys/unix/args.rs b/src/libstd/sys/unix/args.rs index 18de1096df2..f0594bb21bd 100644 --- a/src/libstd/sys/unix/args.rs +++ b/src/libstd/sys/unix/args.rs @@ -35,6 +35,8 @@ impl Iterator for Args { type Item = OsString; fn next(&mut self) -> Option { self.iter.next() } fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } + #[inline] + fn last(mut self) -> Option { self.next_back() } } impl ExactSizeIterator for Args { diff --git a/src/libstd/sys/wasm/args.rs b/src/libstd/sys/wasm/args.rs index b3c77b86995..6766099c1ec 100644 --- a/src/libstd/sys/wasm/args.rs +++ b/src/libstd/sys/wasm/args.rs @@ -37,6 +37,10 @@ impl Iterator for Args { fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } + #[inline] + fn last(mut self) -> Option { + self.next_back() + } } impl ExactSizeIterator for Args { diff --git a/src/libstd/sys/windows/args.rs b/src/libstd/sys/windows/args.rs index b04bb484eed..744d7ec59d3 100644 --- a/src/libstd/sys/windows/args.rs +++ b/src/libstd/sys/windows/args.rs @@ -181,6 +181,8 @@ impl Iterator for Args { type Item = OsString; fn next(&mut self) -> Option { self.parsed_args_list.next() } fn size_hint(&self) -> (usize, Option) { self.parsed_args_list.size_hint() } + #[inline] + fn last(mut self) -> Option { self.next_back() } } impl DoubleEndedIterator for Args { -- cgit 1.4.1-3-g733a5 From 110a73d6c60eab76ce39426eb29cd1d016f6539c Mon Sep 17 00:00:00 2001 From: Philipp Hansch Date: Sat, 20 Apr 2019 16:05:25 +0200 Subject: Deny rust_2018_idioms in liballoc tests --- src/liballoc/tests/cow_str.rs | 24 ++++++++++++------------ src/liballoc/tests/lib.rs | 1 + src/liballoc/tests/string.rs | 4 ++-- 3 files changed, 15 insertions(+), 14 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/tests/cow_str.rs b/src/liballoc/tests/cow_str.rs index eb6adb159b0..6f357eda9b8 100644 --- a/src/liballoc/tests/cow_str.rs +++ b/src/liballoc/tests/cow_str.rs @@ -7,9 +7,9 @@ fn check_cow_add_cow() { let borrowed2 = Cow::Borrowed("World!"); let borrow_empty = Cow::Borrowed(""); - let owned1: Cow = Cow::Owned(String::from("Hi, ")); - let owned2: Cow = Cow::Owned(String::from("Rustaceans!")); - let owned_empty: Cow = Cow::Owned(String::new()); + let owned1: Cow<'_, str> = Cow::Owned(String::from("Hi, ")); + let owned2: Cow<'_, str> = Cow::Owned(String::from("Rustaceans!")); + let owned_empty: Cow<'_, str> = Cow::Owned(String::new()); assert_eq!("Hello, World!", borrowed1.clone() + borrowed2.clone()); assert_eq!("Hello, Rustaceans!", borrowed1.clone() + owned2.clone()); @@ -36,8 +36,8 @@ fn check_cow_add_str() { let borrowed = Cow::Borrowed("Hello, "); let borrow_empty = Cow::Borrowed(""); - let owned: Cow = Cow::Owned(String::from("Hi, ")); - let owned_empty: Cow = Cow::Owned(String::new()); + let owned: Cow<'_, str> = Cow::Owned(String::from("Hi, ")); + let owned_empty: Cow<'_, str> = Cow::Owned(String::new()); assert_eq!("Hello, World!", borrowed.clone() + "World!"); @@ -60,9 +60,9 @@ fn check_cow_add_assign_cow() { let borrowed2 = Cow::Borrowed("World!"); let borrow_empty = Cow::Borrowed(""); - let mut owned1: Cow = Cow::Owned(String::from("Hi, ")); - let owned2: Cow = Cow::Owned(String::from("Rustaceans!")); - let owned_empty: Cow = Cow::Owned(String::new()); + let mut owned1: Cow<'_, str> = Cow::Owned(String::from("Hi, ")); + let owned2: Cow<'_, str> = Cow::Owned(String::from("Rustaceans!")); + let owned_empty: Cow<'_, str> = Cow::Owned(String::new()); let mut s = borrowed1.clone(); s += borrow_empty.clone(); @@ -101,8 +101,8 @@ fn check_cow_add_assign_str() { let mut borrowed = Cow::Borrowed("Hello, "); let borrow_empty = Cow::Borrowed(""); - let mut owned: Cow = Cow::Owned(String::from("Hi, ")); - let owned_empty: Cow = Cow::Owned(String::new()); + let mut owned: Cow<'_, str> = Cow::Owned(String::from("Hi, ")); + let owned_empty: Cow<'_, str> = Cow::Owned(String::new()); let mut s = borrowed.clone(); s += ""; @@ -132,10 +132,10 @@ fn check_cow_add_assign_str() { #[test] fn check_cow_clone_from() { - let mut c1: Cow = Cow::Owned(String::with_capacity(25)); + let mut c1: Cow<'_, str> = Cow::Owned(String::with_capacity(25)); let s: String = "hi".to_string(); assert!(s.capacity() < 25); - let c2: Cow = Cow::Owned(s); + let c2: Cow<'_, str> = Cow::Owned(s); c1.clone_from(&c2); assert!(c1.into_owned().capacity() >= 25); } diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs index 90921b6af9f..b736750c576 100644 --- a/src/liballoc/tests/lib.rs +++ b/src/liballoc/tests/lib.rs @@ -7,6 +7,7 @@ #![feature(try_reserve)] #![feature(unboxed_closures)] #![feature(vecdeque_rotate)] +#![deny(rust_2018_idioms)] use std::hash::{Hash, Hasher}; use std::collections::hash_map::DefaultHasher; diff --git a/src/liballoc/tests/string.rs b/src/liballoc/tests/string.rs index 7e75b8c4f28..765210e5aa6 100644 --- a/src/liballoc/tests/string.rs +++ b/src/liballoc/tests/string.rs @@ -54,11 +54,11 @@ fn test_from_utf8() { #[test] fn test_from_utf8_lossy() { let xs = b"hello"; - let ys: Cow = "hello".into_cow(); + let ys: Cow<'_, str> = "hello".into_cow(); assert_eq!(String::from_utf8_lossy(xs), ys); let xs = "ศไทย中华Việt Nam".as_bytes(); - let ys: Cow = "ศไทย中华Việt Nam".into_cow(); + let ys: Cow<'_, str> = "ศไทย中华Việt Nam".into_cow(); assert_eq!(String::from_utf8_lossy(xs), ys); let xs = b"Hello\xC2 There\xFF Goodbye"; -- cgit 1.4.1-3-g733a5 From 7f0f0e31ecceacfc627440216e559b9625378ecc Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 22 Apr 2019 16:55:33 +0100 Subject: Remove double trailing newlines --- src/ci/docker/scripts/android-sdk.sh | 1 - src/ci/docker/scripts/musl-toolchain.sh | 1 - src/liballoc/str.rs | 1 - src/libcore/iter/adapters/chain.rs | 1 - src/libcore/iter/traits/exact_size.rs | 1 - src/libcore/num/flt2dec/decoder.rs | 1 - src/libcore/ops/unsize.rs | 1 - src/libcore/tests/num/bignum.rs | 1 - src/libcore/tests/num/flt2dec/estimator.rs | 1 - src/libcore/tests/num/flt2dec/mod.rs | 1 - src/libcore/tests/num/flt2dec/random.rs | 1 - src/libcore/tests/num/flt2dec/strategy/dragon.rs | 1 - src/libcore/tests/num/flt2dec/strategy/grisu.rs | 1 - src/librustc/ich/hcx.rs | 1 - src/librustc/ich/impls_hir.rs | 1 - .../infer/error_reporting/nice_region_error/outlives_closure.rs | 1 - src/librustc/infer/type_variable.rs | 1 - src/librustc/macros.rs | 1 - src/librustc/middle/free_region.rs | 1 - src/librustc/session/search_paths.rs | 1 - src/librustc/ty/inhabitedness/def_id_forest.rs | 1 - src/librustc/ty/inhabitedness/mod.rs | 1 - src/librustc_codegen_llvm/va_arg.rs | 1 - src/librustc_mir/borrow_check/nll/invalidation.rs | 1 - src/librustc_mir/borrow_check/nll/region_infer/dump_mir.rs | 1 - src/libstd/os/android/fs.rs | 1 - src/libstd/os/android/raw.rs | 1 - src/libstd/os/bitrig/fs.rs | 1 - src/libstd/os/dragonfly/fs.rs | 1 - src/libstd/os/freebsd/fs.rs | 1 - src/libstd/os/ios/fs.rs | 1 - src/libstd/os/macos/fs.rs | 1 - src/libstd/os/netbsd/fs.rs | 1 - src/libstd/os/openbsd/fs.rs | 1 - src/libstd/sys_common/backtrace.rs | 1 - src/libsyntax/test_snippet.rs | 1 - src/test/assembly/nvptx-internalizing.rs | 1 - .../item-collection/auxiliary/cgu_generic_function.rs | 1 - .../codegen-units/partitioning/auxiliary/cgu_generic_function.rs | 1 - src/test/codegen/likely.rs | 1 - src/test/codegen/nounwind.rs | 1 - src/test/codegen/packed.rs | 1 - src/test/codegen/union-abi.rs | 1 - src/test/debuginfo/should-fail.rs | 1 - src/test/debuginfo/unreachable-locals.rs | 1 - src/test/incremental/change_crate_order/auxiliary/a.rs | 1 - src/test/incremental/change_crate_order/auxiliary/b.rs | 1 - src/test/incremental/hashes/exported_vs_not.rs | 1 - src/test/incremental/issue-39569.rs | 1 - src/test/incremental/krate-inherent.rs | 1 - src/test/incremental/krate_reassign_34991/auxiliary/a.rs | 1 - src/test/incremental/span_hash_stable/main.rs | 1 - src/test/run-fail/call-fn-never-arg.rs | 1 - src/test/run-fail/cast-never.rs | 1 - src/test/run-fail/never-associated-type.rs | 1 - src/test/run-fail/never-type-arg.rs | 1 - src/test/run-make-fulldeps/issue-18943/foo.rs | 1 - src/test/run-make-fulldeps/issue-28595/b.c | 1 - src/test/run-make-fulldeps/libtest-json/f.rs | 1 - src/test/run-make-fulldeps/lto-no-link-whole-rlib/lib2.rs | 1 - src/test/run-make-fulldeps/sanitizer-staticlib-link/program.c | 1 - .../run-make-fulldeps/stable-symbol-names/stable-symbol-names2.rs | 1 - src/test/run-make-fulldeps/windows-subsystem/console.rs | 1 - src/test/run-pass/asm-concat-src.rs | 1 - src/test/run-pass/binding/empty-types-in-patterns.rs | 1 - src/test/run-pass/consts/const-fn-feature-flags.rs | 1 - src/test/run-pass/deriving/auxiliary/derive-no-std.rs | 1 - src/test/run-pass/deriving/derive-no-std.rs | 1 - src/test/run-pass/discriminant_value-wrapper.rs | 1 - src/test/run-pass/fat-lto.rs | 1 - src/test/run-pass/impl-for-never.rs | 1 - src/test/run-pass/inc-range-pat.rs | 1 - src/test/run-pass/inherit-env.rs | 1 - src/test/run-pass/issues/auxiliary/issue-17718-aux.rs | 1 - src/test/run-pass/issues/issue-16278.rs | 5 ++--- src/test/run-pass/issues/issue-21400.rs | 1 - src/test/run-pass/issues/issue-23699.rs | 1 - src/test/run-pass/issues/issue-24313.rs | 1 - .../issue-24687-embed-debuginfo/auxiliary/issue-24687-lib.rs | 1 - src/test/run-pass/issues/issue-26873-multifile/A/B.rs | 1 - src/test/run-pass/issues/issue-26873-multifile/A/C.rs | 1 - src/test/run-pass/issues/issue-26873-multifile/A/mod.rs | 1 - src/test/run-pass/issues/issue-26873-multifile/mod.rs | 1 - src/test/run-pass/issues/issue-26873-onefile.rs | 1 - src/test/run-pass/issues/issue-26905.rs | 1 - src/test/run-pass/issues/issue-28498-must-work-ex2.rs | 1 - src/test/run-pass/issues/issue-28498-ugeh-ex1.rs | 1 - src/test/run-pass/issues/issue-30371.rs | 1 - src/test/run-pass/issues/issue-34784.rs | 1 - src/test/run-pass/issues/issue-39709.rs | 1 - src/test/run-pass/issues/issue-42453.rs | 1 - src/test/run-pass/link-cfg-works.rs | 1 - src/test/run-pass/lint-cap.rs | 1 - src/test/run-pass/macros/macro-first-set.rs | 1 - src/test/run-pass/macros/macro-follow.rs | 1 - src/test/run-pass/macros/macro-nested_expr.rs | 1 - src/test/run-pass/macros/macro-pat-neg-lit.rs | 1 - src/test/run-pass/mir/mir_constval_adts.rs | 1 - src/test/run-pass/never-result.rs | 1 - src/test/run-pass/never_coercions.rs | 1 - src/test/run-pass/nll/rc-loop.rs | 1 - src/test/run-pass/optimization-fuel-0.rs | 1 - src/test/run-pass/proc-macro/auxiliary/expand-with-a-macro.rs | 1 - src/test/run-pass/proc-macro/auxiliary/external-crate-var.rs | 1 - src/test/run-pass/proc-macro/auxiliary/span-api-tests.rs | 1 - src/test/run-pass/proc-macro/expand-with-a-macro.rs | 1 - src/test/run-pass/project-cache-issue-31849.rs | 1 - src/test/run-pass/range_inclusive_gate.rs | 1 - src/test/run-pass/signal-alternate-stack-cleanup.rs | 1 - src/test/run-pass/thinlto/thin-lto-inlines2.rs | 1 - src/test/run-pass/try_from.rs | 1 - src/test/rustdoc/auxiliary/issue-23207-2.rs | 1 - src/test/rustdoc/inline_cross/auxiliary/proc_macro.rs | 1 - .../rustdoc/inline_cross/auxiliary/rustdoc-trait-object-impl.rs | 1 - src/test/rustdoc/inline_cross/issue-32881.rs | 1 - src/test/rustdoc/issue-15318-2.rs | 1 - src/test/rustdoc/issue-19190-3.rs | 1 - src/test/rustdoc/issue-20727-2.rs | 1 - src/test/rustdoc/issue-23207.rs | 1 - src/test/rustdoc/issue-38129.rs | 1 - src/test/rustdoc/issue-56701.rs | 1 - src/test/rustdoc/synthetic_auto/self-referential.rs | 1 - src/test/ui-fulldeps/dropck-tarena-unsound-drop.rs | 1 - src/test/ui/allocator/two-allocators.rs | 1 - src/test/ui/allocator/two-allocators2.rs | 1 - src/test/ui/auxiliary/default-ty-param-cross-crate-crate.rs | 1 - src/test/ui/bad/bad-lint-cap3.rs | 1 - src/test/ui/binop/binop-logic-float.rs | 1 - src/test/ui/borrowck/immutable-arg.rs | 1 - src/test/ui/borrowck/mut-borrow-in-loop.rs | 1 - src/test/ui/borrowck/two-phase-reservation-sharing-interference.rs | 1 - src/test/ui/call-fn-never-arg-wrong-type.rs | 1 - src/test/ui/consts/const-eval/const-eval-overflow-3b.rs | 7 ------- src/test/ui/consts/min_const_fn/min_const_fn.rs | 1 - src/test/ui/consts/union_constant.rs | 1 - src/test/ui/defaulted-never-note.rs | 1 - src/test/ui/derive-uninhabited-enum-38885.rs | 1 - src/test/ui/derives/deriving-copyclone.rs | 1 - src/test/ui/derives/deriving-primitive.rs | 1 - src/test/ui/did_you_mean/recursion_limit_deref.rs | 1 - src/test/ui/did_you_mean/recursion_limit_macro.rs | 1 - src/test/ui/existential_types/auxiliary/cross_crate_ice.rs | 1 - src/test/ui/existential_types/generic_duplicate_param_use7.rs | 1 - src/test/ui/existential_types/nested_existential_types.rs | 1 - src/test/ui/feature-gates/feature-gate-allocator_internals.rs | 1 - src/test/ui/feature-gates/feature-gate-compiler-builtins.rs | 1 - src/test/ui/feature-gates/feature-gate-exhaustive-patterns.rs | 1 - src/test/ui/feature-gates/feature-gate-needs-allocator.rs | 1 - src/test/ui/feature-gates/feature-gate-nll.rs | 1 - src/test/ui/feature-gates/feature-gate-rustc_const_unstable.rs | 1 - src/test/ui/generator/borrowing.rs | 1 - src/test/ui/generator/issue-53548.rs | 1 - src/test/ui/impl-trait/auto-trait-leak2.rs | 1 - src/test/ui/issues/issue-26905.rs | 1 - src/test/ui/issues/issue-30236.rs | 1 - src/test/ui/issues/issue-30240-b.rs | 1 - src/test/ui/issues/issue-33264.rs | 1 - src/test/ui/issues/issue-33287.rs | 1 - src/test/ui/issues/issue-33903.rs | 1 - src/test/ui/issues/issue-40782.rs | 1 - src/test/ui/issues/issue-42060.rs | 1 - src/test/ui/issues/issue-43196.rs | 1 - src/test/ui/issues/issue-44005.rs | 1 - src/test/ui/issues/issue-49851/compiler-builtins-error.rs | 1 - src/test/ui/issues/issue-50714-1.rs | 1 - src/test/ui/issues/issue-50714.rs | 1 - src/test/ui/issues/issue-53419.rs | 1 - src/test/ui/issues/issue-53568.rs | 1 - src/test/ui/issues/issue-58712.rs | 1 - src/test/ui/issues/issue-59488.rs | 1 - src/test/ui/issues/issue-59896.rs | 1 - src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.rs | 1 - .../lifetime-errors/ex3-both-anon-regions-return-type-is-anon.rs | 1 - .../lifetime-errors/ex3-both-anon-regions-self-is-anon.rs | 1 - src/test/ui/macro_backtrace/auxiliary/ping.rs | 1 - src/test/ui/macros/macro-follow.rs | 1 - src/test/ui/macros/must-use-in-macro-55516.rs | 1 - src/test/ui/match/match-argm-statics-2.rs | 1 - src/test/ui/match/match-byte-array-patterns-2.rs | 1 - src/test/ui/mismatched_types/main.rs | 1 - src/test/ui/mismatched_types/numeric-literal-cast.rs | 1 - src/test/ui/mismatched_types/trait-impl-fn-incompatibility.rs | 1 - src/test/ui/nll/issue-47022.rs | 1 - src/test/ui/nll/projection-return.rs | 1 - src/test/ui/nll/ty-outlives/issue-53789-1.rs | 1 - src/test/ui/nll/ty-outlives/issue-53789-2.rs | 1 - src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.rs | 1 - src/test/ui/on-unimplemented/no-debug.rs | 1 - src/test/ui/panic-runtime/libtest-unwinds.rs | 1 - src/test/ui/proc-macro/auxiliary/derive-bad.rs | 1 - src/test/ui/proc-macro/issue-50493.rs | 1 - src/test/ui/range/range_traits-2.rs | 1 - src/test/ui/range/range_traits-3.rs | 1 - src/test/ui/range/range_traits-4.rs | 1 - src/test/ui/range/range_traits-5.rs | 1 - src/test/ui/range/range_traits-6.rs | 1 - src/test/ui/range/range_traits-7.rs | 1 - src/test/ui/recursion/recursive-types-are-not-uninhabited.rs | 1 - src/test/ui/regions/region-borrow-params-issue-29793-small.rs | 1 - src/test/ui/return/return-from-diverging.rs | 1 - src/test/ui/return/return-unit-from-diverging.rs | 1 - src/test/ui/rfc-2093-infer-outlives/cross-crate.rs | 1 - src/test/ui/rfc-2093-infer-outlives/dont-infer-static.rs | 1 - src/test/ui/rfc-2093-infer-outlives/explicit-enum.rs | 1 - src/test/ui/rfc-2093-infer-outlives/explicit-struct.rs | 1 - src/test/ui/rfc-2093-infer-outlives/explicit-union.rs | 1 - src/test/ui/rfc-2093-infer-outlives/infer-static.rs | 1 - src/test/ui/rfc-2093-infer-outlives/projection.rs | 1 - src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.rs | 1 - src/test/ui/rust-2018/extern-crate-idiomatic.rs | 1 - src/test/ui/rust-2018/extern-crate-referenced-by-self-path.rs | 1 - src/test/ui/rust-2018/extern-crate-rename.rs | 1 - src/test/ui/rust-2018/extern-crate-submod.rs | 1 - src/test/ui/self/suggest-self.rs | 1 - src/test/ui/span/dropck-object-cycle.rs | 1 - src/test/ui/span/suggestion-non-ascii.rs | 1 - src/test/ui/structs/struct-fields-shorthand.rs | 1 - src/test/ui/transmute/transmute-imut-to-mut.rs | 1 - src/test/ui/trivial-bounds/trivial-bounds-leak.rs | 1 - src/test/ui/try-block/try-block-bad-lifetime.rs | 1 - src/test/ui/try-block/try-block-maybe-bad-lifetime.rs | 1 - src/test/ui/try-block/try-block-opt-init.rs | 1 - src/test/ui/type/type-mismatch-multiple.rs | 1 - src/test/ui/uninhabited/uninhabited-irrefutable.rs | 1 - src/test/ui/uninhabited/uninhabited-patterns.rs | 1 - src/test/ui/unreachable/unreachable-arm.rs | 1 - src/test/ui/unreachable/unreachable-loop-patterns.rs | 1 - src/test/ui/unreachable/unreachable-try-pattern.rs | 1 - src/test/ui/unsafe/unsafe-const-fn.rs | 1 - src/test/ui/unsized/unsized-enum2.rs | 1 - src/test/ui/wasm-import-module.rs | 1 - src/test/ui/wf/wf-outlives-ty-in-fn-or-trait.rs | 1 - 232 files changed, 2 insertions(+), 240 deletions(-) (limited to 'src/liballoc') diff --git a/src/ci/docker/scripts/android-sdk.sh b/src/ci/docker/scripts/android-sdk.sh index 0b86a2f2dff..e35be697a8d 100755 --- a/src/ci/docker/scripts/android-sdk.sh +++ b/src/ci/docker/scripts/android-sdk.sh @@ -26,4 +26,3 @@ abi="$(echo "${details}" | awk '{print($2)}')" echo no | avdmanager create avd \ -n "$abi-$api" \ -k "system-images;android-$api;default;$abi" - diff --git a/src/ci/docker/scripts/musl-toolchain.sh b/src/ci/docker/scripts/musl-toolchain.sh index 3caf2852ede..8cdbfebea4d 100644 --- a/src/ci/docker/scripts/musl-toolchain.sh +++ b/src/ci/docker/scripts/musl-toolchain.sh @@ -71,4 +71,3 @@ cmake ../libunwind-release_$LLVM \ hide_output make -j$(nproc) cp lib/libunwind.a $OUTPUT/$TARGET/lib cd - && rm -rf libunwind-build - diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs index f10a01d44c8..e5d4e1c533c 100644 --- a/src/liballoc/str.rs +++ b/src/liballoc/str.rs @@ -573,4 +573,3 @@ impl str { pub unsafe fn from_boxed_utf8_unchecked(v: Box<[u8]>) -> Box { Box::from_raw(Box::into_raw(v) as *mut str) } - diff --git a/src/libcore/iter/adapters/chain.rs b/src/libcore/iter/adapters/chain.rs index 11e13149bc2..76239ebc0ab 100644 --- a/src/libcore/iter/adapters/chain.rs +++ b/src/libcore/iter/adapters/chain.rs @@ -258,4 +258,3 @@ impl FusedIterator for Chain unsafe impl TrustedLen for Chain where A: TrustedLen, B: TrustedLen, {} - diff --git a/src/libcore/iter/traits/exact_size.rs b/src/libcore/iter/traits/exact_size.rs index 8fc4ac93daa..4a7db348b18 100644 --- a/src/libcore/iter/traits/exact_size.rs +++ b/src/libcore/iter/traits/exact_size.rs @@ -140,4 +140,3 @@ impl ExactSizeIterator for &mut I { (**self).is_empty() } } - diff --git a/src/libcore/num/flt2dec/decoder.rs b/src/libcore/num/flt2dec/decoder.rs index 6c75d00f6b2..ee0f18ba295 100644 --- a/src/libcore/num/flt2dec/decoder.rs +++ b/src/libcore/num/flt2dec/decoder.rs @@ -86,4 +86,3 @@ pub fn decode(v: T) -> (/*negative?*/ bool, FullDecoded) { }; (sign < 0, decoded) } - diff --git a/src/libcore/ops/unsize.rs b/src/libcore/ops/unsize.rs index 09231ee06ce..7f81481ab5b 100644 --- a/src/libcore/ops/unsize.rs +++ b/src/libcore/ops/unsize.rs @@ -100,4 +100,3 @@ impl, U: ?Sized> DispatchFromDyn<*const U> for *const T {} // *mut T -> *mut U #[unstable(feature = "dispatch_from_dyn", issue = "0")] impl, U: ?Sized> DispatchFromDyn<*mut U> for *mut T {} - diff --git a/src/libcore/tests/num/bignum.rs b/src/libcore/tests/num/bignum.rs index b873f1dd065..b9e15ec5c07 100644 --- a/src/libcore/tests/num/bignum.rs +++ b/src/libcore/tests/num/bignum.rs @@ -236,4 +236,3 @@ fn test_fmt() { assert_eq!(format!("{:?}", Big::from_u64(0x12345)), "0x1_23_45"); assert_eq!(format!("{:?}", Big::from_u64(0x123456)), "0x12_34_56"); } - diff --git a/src/libcore/tests/num/flt2dec/estimator.rs b/src/libcore/tests/num/flt2dec/estimator.rs index fb0888e2720..2dbb8e3a5f0 100644 --- a/src/libcore/tests/num/flt2dec/estimator.rs +++ b/src/libcore/tests/num/flt2dec/estimator.rs @@ -47,4 +47,3 @@ fn test_estimate_scaling_factor() { assert_almost_eq!(estimate_scaling_factor(1, i as i16), expected as i16); } } - diff --git a/src/libcore/tests/num/flt2dec/mod.rs b/src/libcore/tests/num/flt2dec/mod.rs index d362c7994d8..f42f500c2df 100644 --- a/src/libcore/tests/num/flt2dec/mod.rs +++ b/src/libcore/tests/num/flt2dec/mod.rs @@ -1107,4 +1107,3 @@ pub fn to_exact_fixed_str_test(mut f_: F) format!("0.0000000000000000000099999999999999994515327145420957165172950370\ 2787392447107715776066783064379706047475337982177734375{:0>79881}", "")); } - diff --git a/src/libcore/tests/num/flt2dec/random.rs b/src/libcore/tests/num/flt2dec/random.rs index 1c36af6af0e..35e3fbcbb78 100644 --- a/src/libcore/tests/num/flt2dec/random.rs +++ b/src/libcore/tests/num/flt2dec/random.rs @@ -152,4 +152,3 @@ fn exact_f64_random_equivalence_test() { |d, buf| fallback(d, buf, i16::MIN), k, 1_000); } } - diff --git a/src/libcore/tests/num/flt2dec/strategy/dragon.rs b/src/libcore/tests/num/flt2dec/strategy/dragon.rs index 1803e39b46d..5e4cc23d33c 100644 --- a/src/libcore/tests/num/flt2dec/strategy/dragon.rs +++ b/src/libcore/tests/num/flt2dec/strategy/dragon.rs @@ -62,4 +62,3 @@ fn test_to_exact_exp_str() { fn test_to_exact_fixed_str() { to_exact_fixed_str_test(format_exact); } - diff --git a/src/libcore/tests/num/flt2dec/strategy/grisu.rs b/src/libcore/tests/num/flt2dec/strategy/grisu.rs index 53e9f12ae0f..f1afd7d4bf8 100644 --- a/src/libcore/tests/num/flt2dec/strategy/grisu.rs +++ b/src/libcore/tests/num/flt2dec/strategy/grisu.rs @@ -64,4 +64,3 @@ fn test_to_exact_exp_str() { fn test_to_exact_fixed_str() { to_exact_fixed_str_test(format_exact); } - diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs index a8e5db26ead..6da2cb9ab57 100644 --- a/src/librustc/ich/hcx.rs +++ b/src/librustc/ich/hcx.rs @@ -435,4 +435,3 @@ pub fn hash_stable_trait_impls<'a, 'gcx, W>( } } } - diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index 9491a073b8f..65795d2b136 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -435,4 +435,3 @@ impl<'hir> HashStable> for attr::OptimizeAttr { mem::discriminant(self).hash_stable(hcx, hasher); } } - diff --git a/src/librustc/infer/error_reporting/nice_region_error/outlives_closure.rs b/src/librustc/infer/error_reporting/nice_region_error/outlives_closure.rs index 6432780de06..af201886a00 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/outlives_closure.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/outlives_closure.rs @@ -109,4 +109,3 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { None } } - diff --git a/src/librustc/infer/type_variable.rs b/src/librustc/infer/type_variable.rs index 8a719ff2bf3..1393e4f67eb 100644 --- a/src/librustc/infer/type_variable.rs +++ b/src/librustc/infer/type_variable.rs @@ -444,4 +444,3 @@ impl ut::UnifyKey for ty::TyVid { fn from_index(i: u32) -> ty::TyVid { ty::TyVid { index: i } } fn tag() -> &'static str { "TyVid" } } - diff --git a/src/librustc/macros.rs b/src/librustc/macros.rs index 8d9d1db5756..f8d7a5e29f6 100644 --- a/src/librustc/macros.rs +++ b/src/librustc/macros.rs @@ -509,4 +509,3 @@ macro_rules! EnumTypeFoldableImpl { ) }; } - diff --git a/src/librustc/middle/free_region.rs b/src/librustc/middle/free_region.rs index fc345df6551..dae33e34f30 100644 --- a/src/librustc/middle/free_region.rs +++ b/src/librustc/middle/free_region.rs @@ -104,4 +104,3 @@ impl<'a, 'gcx, 'tcx> RegionRelations<'a, 'gcx, 'tcx> { self.free_regions.lub_free_regions(self.tcx, r_a, r_b) } } - diff --git a/src/librustc/session/search_paths.rs b/src/librustc/session/search_paths.rs index 1b6a1739b02..3695f0a82f4 100644 --- a/src/librustc/session/search_paths.rs +++ b/src/librustc/session/search_paths.rs @@ -71,4 +71,3 @@ impl SearchPath { SearchPath { kind, dir, files } } } - diff --git a/src/librustc/ty/inhabitedness/def_id_forest.rs b/src/librustc/ty/inhabitedness/def_id_forest.rs index 3b393c3ca15..581fc41fda4 100644 --- a/src/librustc/ty/inhabitedness/def_id_forest.rs +++ b/src/librustc/ty/inhabitedness/def_id_forest.rs @@ -118,4 +118,3 @@ impl<'a, 'gcx, 'tcx> DefIdForest { ret } } - diff --git a/src/librustc/ty/inhabitedness/mod.rs b/src/librustc/ty/inhabitedness/mod.rs index 963b4b439f8..042f06e13a3 100644 --- a/src/librustc/ty/inhabitedness/mod.rs +++ b/src/librustc/ty/inhabitedness/mod.rs @@ -203,4 +203,3 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { } } } - diff --git a/src/librustc_codegen_llvm/va_arg.rs b/src/librustc_codegen_llvm/va_arg.rs index 7fc17d17f99..410e00fe0b8 100644 --- a/src/librustc_codegen_llvm/va_arg.rs +++ b/src/librustc_codegen_llvm/va_arg.rs @@ -145,4 +145,3 @@ pub(super) fn emit_va_arg( } } } - diff --git a/src/librustc_mir/borrow_check/nll/invalidation.rs b/src/librustc_mir/borrow_check/nll/invalidation.rs index a5230e67b75..8cbf68c476a 100644 --- a/src/librustc_mir/borrow_check/nll/invalidation.rs +++ b/src/librustc_mir/borrow_check/nll/invalidation.rs @@ -502,4 +502,3 @@ impl<'cg, 'cx, 'tcx, 'gcx> InvalidationGenerator<'cx, 'tcx, 'gcx> { } } } - diff --git a/src/librustc_mir/borrow_check/nll/region_infer/dump_mir.rs b/src/librustc_mir/borrow_check/nll/region_infer/dump_mir.rs index 419ee73b28a..4931005a454 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/dump_mir.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/dump_mir.rs @@ -92,4 +92,3 @@ impl<'tcx> RegionInferenceContext<'tcx> { Ok(()) } } - diff --git a/src/libstd/os/android/fs.rs b/src/libstd/os/android/fs.rs index 9b24f86204b..90fdee567ae 100644 --- a/src/libstd/os/android/fs.rs +++ b/src/libstd/os/android/fs.rs @@ -116,4 +116,3 @@ impl MetadataExt for Metadata { self.as_inner().as_inner().st_blocks as u64 } } - diff --git a/src/libstd/os/android/raw.rs b/src/libstd/os/android/raw.rs index acf5ca1e429..946a77cbfd3 100644 --- a/src/libstd/os/android/raw.rs +++ b/src/libstd/os/android/raw.rs @@ -217,4 +217,3 @@ mod arch { __unused: [c_long; 3], } } - diff --git a/src/libstd/os/bitrig/fs.rs b/src/libstd/os/bitrig/fs.rs index 849d4aa67f2..b5c6903c410 100644 --- a/src/libstd/os/bitrig/fs.rs +++ b/src/libstd/os/bitrig/fs.rs @@ -136,4 +136,3 @@ impl MetadataExt for Metadata { self.as_inner().as_inner().st_flags as u32 } } - diff --git a/src/libstd/os/dragonfly/fs.rs b/src/libstd/os/dragonfly/fs.rs index ba38660224f..ba3d8d7867d 100644 --- a/src/libstd/os/dragonfly/fs.rs +++ b/src/libstd/os/dragonfly/fs.rs @@ -131,4 +131,3 @@ impl MetadataExt for Metadata { self.as_inner().as_inner().st_lspare as u32 } } - diff --git a/src/libstd/os/freebsd/fs.rs b/src/libstd/os/freebsd/fs.rs index 4cc3a4b91fb..cfe8d575c67 100644 --- a/src/libstd/os/freebsd/fs.rs +++ b/src/libstd/os/freebsd/fs.rs @@ -141,4 +141,3 @@ impl MetadataExt for Metadata { self.as_inner().as_inner().st_lspare as u32 } } - diff --git a/src/libstd/os/ios/fs.rs b/src/libstd/os/ios/fs.rs index 7b625f5e3fe..9bdfa8e690b 100644 --- a/src/libstd/os/ios/fs.rs +++ b/src/libstd/os/ios/fs.rs @@ -141,4 +141,3 @@ impl MetadataExt for Metadata { self.as_inner().as_inner().st_lspare as u32 } } - diff --git a/src/libstd/os/macos/fs.rs b/src/libstd/os/macos/fs.rs index 1bd66ad4c76..bf951ee18c9 100644 --- a/src/libstd/os/macos/fs.rs +++ b/src/libstd/os/macos/fs.rs @@ -147,4 +147,3 @@ impl MetadataExt for Metadata { [qspare[0] as u64, qspare[1] as u64] } } - diff --git a/src/libstd/os/netbsd/fs.rs b/src/libstd/os/netbsd/fs.rs index 6dffb70b5dc..dedfc6390ce 100644 --- a/src/libstd/os/netbsd/fs.rs +++ b/src/libstd/os/netbsd/fs.rs @@ -136,4 +136,3 @@ impl MetadataExt for Metadata { self.as_inner().as_inner().st_flags as u32 } } - diff --git a/src/libstd/os/openbsd/fs.rs b/src/libstd/os/openbsd/fs.rs index 73f9757f3b7..1c019159be0 100644 --- a/src/libstd/os/openbsd/fs.rs +++ b/src/libstd/os/openbsd/fs.rs @@ -136,4 +136,3 @@ impl MetadataExt for Metadata { self.as_inner().as_inner().st_flags as u32 } } - diff --git a/src/libstd/sys_common/backtrace.rs b/src/libstd/sys_common/backtrace.rs index 1a80908779e..8d8d8169b43 100644 --- a/src/libstd/sys_common/backtrace.rs +++ b/src/libstd/sys_common/backtrace.rs @@ -241,4 +241,3 @@ fn output_fileline(w: &mut dyn Write, w.write_all(b"\n") } - diff --git a/src/libsyntax/test_snippet.rs b/src/libsyntax/test_snippet.rs index cba429068fd..3cf6699538d 100644 --- a/src/libsyntax/test_snippet.rs +++ b/src/libsyntax/test_snippet.rs @@ -1162,4 +1162,3 @@ error: foo "#); } - diff --git a/src/test/assembly/nvptx-internalizing.rs b/src/test/assembly/nvptx-internalizing.rs index db822642632..c9edc386959 100644 --- a/src/test/assembly/nvptx-internalizing.rs +++ b/src/test/assembly/nvptx-internalizing.rs @@ -24,4 +24,3 @@ pub unsafe extern "ptx-kernel" fn top_kernel(a: *const u32, b: *mut u32) { // Verify that no extra function definitions are here. // CHECK-NOT: .func // CHECK-NOT: .entry - diff --git a/src/test/codegen-units/item-collection/auxiliary/cgu_generic_function.rs b/src/test/codegen-units/item-collection/auxiliary/cgu_generic_function.rs index 976cbb2b44b..3926f295742 100644 --- a/src/test/codegen-units/item-collection/auxiliary/cgu_generic_function.rs +++ b/src/test/codegen-units/item-collection/auxiliary/cgu_generic_function.rs @@ -24,4 +24,3 @@ pub fn exported_but_not_generic(x: i32) -> i64 { fn not_exported_and_not_generic(x: u32) -> u64 { x as u64 } - diff --git a/src/test/codegen-units/partitioning/auxiliary/cgu_generic_function.rs b/src/test/codegen-units/partitioning/auxiliary/cgu_generic_function.rs index 976cbb2b44b..3926f295742 100644 --- a/src/test/codegen-units/partitioning/auxiliary/cgu_generic_function.rs +++ b/src/test/codegen-units/partitioning/auxiliary/cgu_generic_function.rs @@ -24,4 +24,3 @@ pub fn exported_but_not_generic(x: i32) -> i64 { fn not_exported_and_not_generic(x: u32) -> u64 { x as u64 } - diff --git a/src/test/codegen/likely.rs b/src/test/codegen/likely.rs index c56cf718f98..c5a0185bd48 100644 --- a/src/test/codegen/likely.rs +++ b/src/test/codegen/likely.rs @@ -28,4 +28,3 @@ pub fn check_unlikely(x: i32, y: i32) -> Option { } } } - diff --git a/src/test/codegen/nounwind.rs b/src/test/codegen/nounwind.rs index 49a74ef7ab4..f639c60b893 100644 --- a/src/test/codegen/nounwind.rs +++ b/src/test/codegen/nounwind.rs @@ -14,4 +14,3 @@ pub fn foo() { // CHECK: @bar() unnamed_addr #0 // CHECK: attributes #0 = { {{.*}}nounwind{{.*}} } } - diff --git a/src/test/codegen/packed.rs b/src/test/codegen/packed.rs index b42161db98a..3c8ff394849 100644 --- a/src/test/codegen/packed.rs +++ b/src/test/codegen/packed.rs @@ -152,4 +152,3 @@ pub fn pkd2_nested_pair(pair1: &mut Packed2NestedPair, pair2: &mut Packed2Nested // CHECK: call void @llvm.memcpy.{{.*}}(i8* align 2 %{{.*}}, i8* align 2 %{{.*}}, i{{[0-9]+}} 8, i1 false) *pair2 = *pair1; } - diff --git a/src/test/codegen/union-abi.rs b/src/test/codegen/union-abi.rs index 03b55eb52a2..b7baffe1669 100644 --- a/src/test/codegen/union-abi.rs +++ b/src/test/codegen/union-abi.rs @@ -73,4 +73,3 @@ pub union UnionBool { b:bool } #[no_mangle] pub fn test_UnionBool(b: UnionBool) -> bool { unsafe { b.b } } // CHECK: %0 = trunc i8 %b to i1 - diff --git a/src/test/debuginfo/should-fail.rs b/src/test/debuginfo/should-fail.rs index 441be56b5b4..8765c018b10 100644 --- a/src/test/debuginfo/should-fail.rs +++ b/src/test/debuginfo/should-fail.rs @@ -25,4 +25,3 @@ fn main() { } fn zzz() {()} - diff --git a/src/test/debuginfo/unreachable-locals.rs b/src/test/debuginfo/unreachable-locals.rs index b6971f353a5..5787f819cb9 100644 --- a/src/test/debuginfo/unreachable-locals.rs +++ b/src/test/debuginfo/unreachable-locals.rs @@ -156,4 +156,3 @@ fn diverge() -> ! { } fn some_predicate() -> bool { true || false } - diff --git a/src/test/incremental/change_crate_order/auxiliary/a.rs b/src/test/incremental/change_crate_order/auxiliary/a.rs index 5948f38cf1b..1bd48714ac9 100644 --- a/src/test/incremental/change_crate_order/auxiliary/a.rs +++ b/src/test/incremental/change_crate_order/auxiliary/a.rs @@ -1,4 +1,3 @@ #![crate_type="rlib"] pub static A : u32 = 32; - diff --git a/src/test/incremental/change_crate_order/auxiliary/b.rs b/src/test/incremental/change_crate_order/auxiliary/b.rs index 12e31039851..001b88912ab 100644 --- a/src/test/incremental/change_crate_order/auxiliary/b.rs +++ b/src/test/incremental/change_crate_order/auxiliary/b.rs @@ -1,4 +1,3 @@ #![crate_type="rlib"] pub static B: u32 = 32; - diff --git a/src/test/incremental/hashes/exported_vs_not.rs b/src/test/incremental/hashes/exported_vs_not.rs index dc919abc02d..5a29afa17d3 100644 --- a/src/test/incremental/hashes/exported_vs_not.rs +++ b/src/test/incremental/hashes/exported_vs_not.rs @@ -61,4 +61,3 @@ pub fn body_exported_to_metadata_because_of_generic() -> u32 { pub fn body_exported_to_metadata_because_of_generic() -> u32 { 2 } - diff --git a/src/test/incremental/issue-39569.rs b/src/test/incremental/issue-39569.rs index 06e3cf0a293..881ecfca740 100644 --- a/src/test/incremental/issue-39569.rs +++ b/src/test/incremental/issue-39569.rs @@ -25,4 +25,3 @@ fn main() { let x: Arc = Arc::new(FooX { x: 22 }); let y: Arc = x; } - diff --git a/src/test/incremental/krate-inherent.rs b/src/test/incremental/krate-inherent.rs index e01ce317a20..3e8d8fb1f94 100644 --- a/src/test/incremental/krate-inherent.rs +++ b/src/test/incremental/krate-inherent.rs @@ -21,4 +21,3 @@ pub mod x { #[cfg(cfail1)] pub fn bar() { } // remove this unrelated fn in cfail2, which should not affect `x::method` - diff --git a/src/test/incremental/krate_reassign_34991/auxiliary/a.rs b/src/test/incremental/krate_reassign_34991/auxiliary/a.rs index 33fa789fcae..69be8d3bc03 100644 --- a/src/test/incremental/krate_reassign_34991/auxiliary/a.rs +++ b/src/test/incremental/krate_reassign_34991/auxiliary/a.rs @@ -1,4 +1,3 @@ #![crate_type="rlib"] pub type X = u32; - diff --git a/src/test/incremental/span_hash_stable/main.rs b/src/test/incremental/span_hash_stable/main.rs index f19c99e1986..f1d7de14559 100644 --- a/src/test/incremental/span_hash_stable/main.rs +++ b/src/test/incremental/span_hash_stable/main.rs @@ -21,4 +21,3 @@ fn main() { b: 3, }; } - diff --git a/src/test/run-fail/call-fn-never-arg.rs b/src/test/run-fail/call-fn-never-arg.rs index d21a43ec5c5..f5b2cfaefe0 100644 --- a/src/test/run-fail/call-fn-never-arg.rs +++ b/src/test/run-fail/call-fn-never-arg.rs @@ -12,4 +12,3 @@ fn foo(x: !) -> ! { fn main() { foo(panic!("wowzers!")) } - diff --git a/src/test/run-fail/cast-never.rs b/src/test/run-fail/cast-never.rs index 3620ddee478..0b05a4b9112 100644 --- a/src/test/run-fail/cast-never.rs +++ b/src/test/run-fail/cast-never.rs @@ -8,4 +8,3 @@ fn main() { let x: ! = panic!(); let y: u32 = x as u32; } - diff --git a/src/test/run-fail/never-associated-type.rs b/src/test/run-fail/never-associated-type.rs index ba30b9ea0fe..587f0f72d5a 100644 --- a/src/test/run-fail/never-associated-type.rs +++ b/src/test/run-fail/never-associated-type.rs @@ -21,4 +21,3 @@ impl Foo for Blah { fn main() { Blah.smeg(); } - diff --git a/src/test/run-fail/never-type-arg.rs b/src/test/run-fail/never-type-arg.rs index fc7f2fc90d7..1747e96eef4 100644 --- a/src/test/run-fail/never-type-arg.rs +++ b/src/test/run-fail/never-type-arg.rs @@ -15,4 +15,3 @@ impl PartialEq for Wub { fn main() { let _ = Wub == panic!("oh no!"); } - diff --git a/src/test/run-make-fulldeps/issue-18943/foo.rs b/src/test/run-make-fulldeps/issue-18943/foo.rs index 0b29c871280..d18400dd3a5 100644 --- a/src/test/run-make-fulldeps/issue-18943/foo.rs +++ b/src/test/run-make-fulldeps/issue-18943/foo.rs @@ -3,4 +3,3 @@ trait Foo { } trait Bar { } impl<'a> Foo for Bar + 'a { } - diff --git a/src/test/run-make-fulldeps/issue-28595/b.c b/src/test/run-make-fulldeps/issue-28595/b.c index 8343f5b229e..6aecb5f9e04 100644 --- a/src/test/run-make-fulldeps/issue-28595/b.c +++ b/src/test/run-make-fulldeps/issue-28595/b.c @@ -3,4 +3,3 @@ extern void a(void); void b(void) { a(); } - diff --git a/src/test/run-make-fulldeps/libtest-json/f.rs b/src/test/run-make-fulldeps/libtest-json/f.rs index 29d52ee9654..f5e44c2c244 100644 --- a/src/test/run-make-fulldeps/libtest-json/f.rs +++ b/src/test/run-make-fulldeps/libtest-json/f.rs @@ -19,4 +19,3 @@ fn c() { fn d() { assert!(false); } - diff --git a/src/test/run-make-fulldeps/lto-no-link-whole-rlib/lib2.rs b/src/test/run-make-fulldeps/lto-no-link-whole-rlib/lib2.rs index 50b7882a05a..c9e1baa434b 100644 --- a/src/test/run-make-fulldeps/lto-no-link-whole-rlib/lib2.rs +++ b/src/test/run-make-fulldeps/lto-no-link-whole-rlib/lib2.rs @@ -10,4 +10,3 @@ extern { pub fn foo2() -> i32 { unsafe { foo() } } - diff --git a/src/test/run-make-fulldeps/sanitizer-staticlib-link/program.c b/src/test/run-make-fulldeps/sanitizer-staticlib-link/program.c index abd5d508e72..a6d3bcdc5ac 100644 --- a/src/test/run-make-fulldeps/sanitizer-staticlib-link/program.c +++ b/src/test/run-make-fulldeps/sanitizer-staticlib-link/program.c @@ -5,4 +5,3 @@ int main() { overflow(); return 0; } - diff --git a/src/test/run-make-fulldeps/stable-symbol-names/stable-symbol-names2.rs b/src/test/run-make-fulldeps/stable-symbol-names/stable-symbol-names2.rs index 6df74d2491b..33df9d6c689 100644 --- a/src/test/run-make-fulldeps/stable-symbol-names/stable-symbol-names2.rs +++ b/src/test/run-make-fulldeps/stable-symbol-names/stable-symbol-names2.rs @@ -15,4 +15,3 @@ pub fn trait_impl_test_function() { use stable_symbol_names1::*; Bar::generic_method::(); } - diff --git a/src/test/run-make-fulldeps/windows-subsystem/console.rs b/src/test/run-make-fulldeps/windows-subsystem/console.rs index 4a2e9bb3c5c..61a92eb6a9d 100644 --- a/src/test/run-make-fulldeps/windows-subsystem/console.rs +++ b/src/test/run-make-fulldeps/windows-subsystem/console.rs @@ -1,4 +1,3 @@ #![windows_subsystem = "console"] fn main() {} - diff --git a/src/test/run-pass/asm-concat-src.rs b/src/test/run-pass/asm-concat-src.rs index b24586464d6..c629519e8fe 100644 --- a/src/test/run-pass/asm-concat-src.rs +++ b/src/test/run-pass/asm-concat-src.rs @@ -6,4 +6,3 @@ pub fn main() { unsafe { asm!(concat!("", "")) }; } - diff --git a/src/test/run-pass/binding/empty-types-in-patterns.rs b/src/test/run-pass/binding/empty-types-in-patterns.rs index d9fb176c818..2b8b1b29df8 100644 --- a/src/test/run-pass/binding/empty-types-in-patterns.rs +++ b/src/test/run-pass/binding/empty-types-in-patterns.rs @@ -56,4 +56,3 @@ fn main() { bar(&[]); } - diff --git a/src/test/run-pass/consts/const-fn-feature-flags.rs b/src/test/run-pass/consts/const-fn-feature-flags.rs index 83a98f0f8e9..30e7e102b86 100644 --- a/src/test/run-pass/consts/const-fn-feature-flags.rs +++ b/src/test/run-pass/consts/const-fn-feature-flags.rs @@ -11,4 +11,3 @@ fn main() { assert_eq!(CELL.get(), v); } - diff --git a/src/test/run-pass/deriving/auxiliary/derive-no-std.rs b/src/test/run-pass/deriving/auxiliary/derive-no-std.rs index 21bfd5a2909..3893dc1be07 100644 --- a/src/test/run-pass/deriving/auxiliary/derive-no-std.rs +++ b/src/test/run-pass/deriving/auxiliary/derive-no-std.rs @@ -27,4 +27,3 @@ pub struct Empty; #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Debug, Copy)] pub struct AlsoEmpty {} - diff --git a/src/test/run-pass/deriving/derive-no-std.rs b/src/test/run-pass/deriving/derive-no-std.rs index 22edd3eed59..74c73b99cb9 100644 --- a/src/test/run-pass/deriving/derive-no-std.rs +++ b/src/test/run-pass/deriving/derive-no-std.rs @@ -10,4 +10,3 @@ fn main() { assert!(Bar::Qux < Bar::Quux(42)); } - diff --git a/src/test/run-pass/discriminant_value-wrapper.rs b/src/test/run-pass/discriminant_value-wrapper.rs index f014cce9ddd..1fb0d1edddf 100644 --- a/src/test/run-pass/discriminant_value-wrapper.rs +++ b/src/test/run-pass/discriminant_value-wrapper.rs @@ -13,4 +13,3 @@ pub fn main() { let _ = mem::discriminant(&10); let _ = mem::discriminant(&"test"); } - diff --git a/src/test/run-pass/fat-lto.rs b/src/test/run-pass/fat-lto.rs index 7e50b44430c..fb741200d3c 100644 --- a/src/test/run-pass/fat-lto.rs +++ b/src/test/run-pass/fat-lto.rs @@ -4,4 +4,3 @@ fn main() { println!("hello!"); } - diff --git a/src/test/run-pass/impl-for-never.rs b/src/test/run-pass/impl-for-never.rs index d2dbae61767..a5287123008 100644 --- a/src/test/run-pass/impl-for-never.rs +++ b/src/test/run-pass/impl-for-never.rs @@ -23,4 +23,3 @@ fn main() { println!("! is {}", ::stringify_type()); println!("None is {}", maybe_stringify(None::)); } - diff --git a/src/test/run-pass/inc-range-pat.rs b/src/test/run-pass/inc-range-pat.rs index 6b99a9d0a74..6bf857a11f8 100644 --- a/src/test/run-pass/inc-range-pat.rs +++ b/src/test/run-pass/inc-range-pat.rs @@ -7,4 +7,3 @@ fn main() { assert!(match 'x' { 'a' ... 'z' => true, _ => false }); assert!(match 'x' { 'a' ..= 'z' => true, _ => false }); } - diff --git a/src/test/run-pass/inherit-env.rs b/src/test/run-pass/inherit-env.rs index 856d3a5f72d..8e2401d0c03 100644 --- a/src/test/run-pass/inherit-env.rs +++ b/src/test/run-pass/inherit-env.rs @@ -22,4 +22,3 @@ fn main() { k, v, output); } } - diff --git a/src/test/run-pass/issues/auxiliary/issue-17718-aux.rs b/src/test/run-pass/issues/auxiliary/issue-17718-aux.rs index 1cba9709f91..91abdbff868 100644 --- a/src/test/run-pass/issues/auxiliary/issue-17718-aux.rs +++ b/src/test/run-pass/issues/auxiliary/issue-17718-aux.rs @@ -8,4 +8,3 @@ pub const C5: &'static usize = &C4; pub static S1: usize = 3; pub static S2: atomic::AtomicUsize = atomic::AtomicUsize::new(0); - diff --git a/src/test/run-pass/issues/issue-16278.rs b/src/test/run-pass/issues/issue-16278.rs index a9fa0db44d3..ad9af8473de 100644 --- a/src/test/run-pass/issues/issue-16278.rs +++ b/src/test/run-pass/issues/issue-16278.rs @@ -3,9 +3,8 @@ // this file has some special \r\n endings (use xxd to see them) -fn main() {assert_eq!(b"", b"\ +fn main() {assert_eq!(b"", b"\ "); -assert_eq!(b"\n", b" +assert_eq!(b"\n", b" "); } - diff --git a/src/test/run-pass/issues/issue-21400.rs b/src/test/run-pass/issues/issue-21400.rs index 0f297e9b8f2..4a85158d97a 100644 --- a/src/test/run-pass/issues/issue-21400.rs +++ b/src/test/run-pass/issues/issue-21400.rs @@ -54,4 +54,3 @@ impl GitConnect { Ok(out) } } - diff --git a/src/test/run-pass/issues/issue-23699.rs b/src/test/run-pass/issues/issue-23699.rs index 11b65d7a67a..952548837e4 100644 --- a/src/test/run-pass/issues/issue-23699.rs +++ b/src/test/run-pass/issues/issue-23699.rs @@ -12,4 +12,3 @@ fn main() { let t = test as fn (i32); t(0i32); } - diff --git a/src/test/run-pass/issues/issue-24313.rs b/src/test/run-pass/issues/issue-24313.rs index d6426361fae..ddcf1d04511 100644 --- a/src/test/run-pass/issues/issue-24313.rs +++ b/src/test/run-pass/issues/issue-24313.rs @@ -30,4 +30,3 @@ fn main() { }).join().unwrap(); } } - diff --git a/src/test/run-pass/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-lib.rs b/src/test/run-pass/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-lib.rs index 2275a8da696..5b1b1389ceb 100644 --- a/src/test/run-pass/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-lib.rs +++ b/src/test/run-pass/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-lib.rs @@ -8,4 +8,3 @@ mod issue_24687_mbcs_in_comments; pub use issue_24687_mbcs_in_comments::D; - diff --git a/src/test/run-pass/issues/issue-26873-multifile/A/B.rs b/src/test/run-pass/issues/issue-26873-multifile/A/B.rs index d1b802ff3cd..ab7b0d81605 100644 --- a/src/test/run-pass/issues/issue-26873-multifile/A/B.rs +++ b/src/test/run-pass/issues/issue-26873-multifile/A/B.rs @@ -2,4 +2,3 @@ use super::*; pub struct S; - diff --git a/src/test/run-pass/issues/issue-26873-multifile/A/C.rs b/src/test/run-pass/issues/issue-26873-multifile/A/C.rs index 88f3eb04afb..b287283df53 100644 --- a/src/test/run-pass/issues/issue-26873-multifile/A/C.rs +++ b/src/test/run-pass/issues/issue-26873-multifile/A/C.rs @@ -4,4 +4,3 @@ use super::*; use super::B::S; pub struct T { i: i32 } - diff --git a/src/test/run-pass/issues/issue-26873-multifile/A/mod.rs b/src/test/run-pass/issues/issue-26873-multifile/A/mod.rs index 20f40a06782..0f18772bf1b 100644 --- a/src/test/run-pass/issues/issue-26873-multifile/A/mod.rs +++ b/src/test/run-pass/issues/issue-26873-multifile/A/mod.rs @@ -3,4 +3,3 @@ pub mod B; pub mod C; pub use self::C::T; - diff --git a/src/test/run-pass/issues/issue-26873-multifile/mod.rs b/src/test/run-pass/issues/issue-26873-multifile/mod.rs index 52deea79a20..a1ba53f9191 100644 --- a/src/test/run-pass/issues/issue-26873-multifile/mod.rs +++ b/src/test/run-pass/issues/issue-26873-multifile/mod.rs @@ -2,4 +2,3 @@ mod A; use self::A::*; - diff --git a/src/test/run-pass/issues/issue-26873-onefile.rs b/src/test/run-pass/issues/issue-26873-onefile.rs index 4cfffb08e8f..f06c6499eb0 100644 --- a/src/test/run-pass/issues/issue-26873-onefile.rs +++ b/src/test/run-pass/issues/issue-26873-onefile.rs @@ -23,4 +23,3 @@ mod A { use A::*; fn main() {} - diff --git a/src/test/run-pass/issues/issue-26905.rs b/src/test/run-pass/issues/issue-26905.rs index 309e2f7e571..2f500d1c0d1 100644 --- a/src/test/run-pass/issues/issue-26905.rs +++ b/src/test/run-pass/issues/issue-26905.rs @@ -19,4 +19,3 @@ fn main() { let x = MyRc { _ptr: &iter, _boo: PhantomData }; let _y: MyRc> = x; } - diff --git a/src/test/run-pass/issues/issue-28498-must-work-ex2.rs b/src/test/run-pass/issues/issue-28498-must-work-ex2.rs index 17111308555..cadf62461fd 100644 --- a/src/test/run-pass/issues/issue-28498-must-work-ex2.rs +++ b/src/test/run-pass/issues/issue-28498-must-work-ex2.rs @@ -18,4 +18,3 @@ fn main() { foo.data[0].1.set(Some(&foo.data[1])); foo.data[1].1.set(Some(&foo.data[0])); } - diff --git a/src/test/run-pass/issues/issue-28498-ugeh-ex1.rs b/src/test/run-pass/issues/issue-28498-ugeh-ex1.rs index 65d5588871b..c4f249c45f1 100644 --- a/src/test/run-pass/issues/issue-28498-ugeh-ex1.rs +++ b/src/test/run-pass/issues/issue-28498-ugeh-ex1.rs @@ -27,4 +27,3 @@ fn main() { foo.data[0].1.set(Some(&foo.data[1])); foo.data[1].1.set(Some(&foo.data[0])); } - diff --git a/src/test/run-pass/issues/issue-30371.rs b/src/test/run-pass/issues/issue-30371.rs index 093d4b8c119..58521b95cf6 100644 --- a/src/test/run-pass/issues/issue-30371.rs +++ b/src/test/run-pass/issues/issue-30371.rs @@ -8,4 +8,3 @@ fn main() { () => Some(0), } {} } - diff --git a/src/test/run-pass/issues/issue-34784.rs b/src/test/run-pass/issues/issue-34784.rs index 4392637c39f..d3206e99430 100644 --- a/src/test/run-pass/issues/issue-34784.rs +++ b/src/test/run-pass/issues/issue-34784.rs @@ -17,4 +17,3 @@ fn main() { _ => {} } } - diff --git a/src/test/run-pass/issues/issue-39709.rs b/src/test/run-pass/issues/issue-39709.rs index 8ea49c2082b..69ef2700ef3 100644 --- a/src/test/run-pass/issues/issue-39709.rs +++ b/src/test/run-pass/issues/issue-39709.rs @@ -3,4 +3,3 @@ fn main() { println!("{}", { macro_rules! x { ($(t:tt)*) => {} } 33 }); } - diff --git a/src/test/run-pass/issues/issue-42453.rs b/src/test/run-pass/issues/issue-42453.rs index bea441c2bea..92fefceabc1 100644 --- a/src/test/run-pass/issues/issue-42453.rs +++ b/src/test/run-pass/issues/issue-42453.rs @@ -8,4 +8,3 @@ struct builder; fn main() { } - diff --git a/src/test/run-pass/link-cfg-works.rs b/src/test/run-pass/link-cfg-works.rs index a4888292c7d..d7a248fd4d5 100644 --- a/src/test/run-pass/link-cfg-works.rs +++ b/src/test/run-pass/link-cfg-works.rs @@ -10,4 +10,3 @@ extern crate link_cfg_works_transitive_dylib; extern {} fn main() {} - diff --git a/src/test/run-pass/lint-cap.rs b/src/test/run-pass/lint-cap.rs index 0e8bdbdc6aa..f03bb691892 100644 --- a/src/test/run-pass/lint-cap.rs +++ b/src/test/run-pass/lint-cap.rs @@ -5,4 +5,3 @@ use std::option; fn main() {} - diff --git a/src/test/run-pass/macros/macro-first-set.rs b/src/test/run-pass/macros/macro-first-set.rs index 8b09e72ed29..a21e4cd201a 100644 --- a/src/test/run-pass/macros/macro-first-set.rs +++ b/src/test/run-pass/macros/macro-first-set.rs @@ -275,4 +275,3 @@ fn main() { test_24189(); test_51477(); } - diff --git a/src/test/run-pass/macros/macro-follow.rs b/src/test/run-pass/macros/macro-follow.rs index 488339b025d..ca93655631f 100644 --- a/src/test/run-pass/macros/macro-follow.rs +++ b/src/test/run-pass/macros/macro-follow.rs @@ -181,4 +181,3 @@ macro_rules! follow_meta { } fn main() {} - diff --git a/src/test/run-pass/macros/macro-nested_expr.rs b/src/test/run-pass/macros/macro-nested_expr.rs index 2f93ffec4ab..f1433cbf4f9 100644 --- a/src/test/run-pass/macros/macro-nested_expr.rs +++ b/src/test/run-pass/macros/macro-nested_expr.rs @@ -20,4 +20,3 @@ fn main() { define_f!(concat!("exported_", "f")); m!(stringify!(foo)); } - diff --git a/src/test/run-pass/macros/macro-pat-neg-lit.rs b/src/test/run-pass/macros/macro-pat-neg-lit.rs index 5345df2e84e..79c68fd2541 100644 --- a/src/test/run-pass/macros/macro-pat-neg-lit.rs +++ b/src/test/run-pass/macros/macro-pat-neg-lit.rs @@ -23,4 +23,3 @@ enum_number!(Change { fn main() { if let Some(Change::Down) = foo(-1) {} else { panic!() } } - diff --git a/src/test/run-pass/mir/mir_constval_adts.rs b/src/test/run-pass/mir/mir_constval_adts.rs index 3156be3584e..ee9d73451f4 100644 --- a/src/test/run-pass/mir/mir_constval_adts.rs +++ b/src/test/run-pass/mir/mir_constval_adts.rs @@ -32,4 +32,3 @@ fn main(){ assert_eq!(mir(), (STRUCT, TUPLE1, TUPLE2, PAIR_NEWTYPE)); test_promoted_newtype_str_ref(); } - diff --git a/src/test/run-pass/never-result.rs b/src/test/run-pass/never-result.rs index 2b395aa7f66..808377ffa11 100644 --- a/src/test/run-pass/never-result.rs +++ b/src/test/run-pass/never-result.rs @@ -16,4 +16,3 @@ fn main() { }, } } - diff --git a/src/test/run-pass/never_coercions.rs b/src/test/run-pass/never_coercions.rs index 70f67fd3da1..f32e2973813 100644 --- a/src/test/run-pass/never_coercions.rs +++ b/src/test/run-pass/never_coercions.rs @@ -9,4 +9,3 @@ fn main() { _ => &v[..], }; } - diff --git a/src/test/run-pass/nll/rc-loop.rs b/src/test/run-pass/nll/rc-loop.rs index 2c54ee86939..a4ef546c25f 100644 --- a/src/test/run-pass/nll/rc-loop.rs +++ b/src/test/run-pass/nll/rc-loop.rs @@ -28,4 +28,3 @@ fn main() { let base = find_base(chain); assert_eq!(&*base, &Foo::Base(44)); } - diff --git a/src/test/run-pass/optimization-fuel-0.rs b/src/test/run-pass/optimization-fuel-0.rs index 0920bc9c4b9..77f21b3fcc0 100644 --- a/src/test/run-pass/optimization-fuel-0.rs +++ b/src/test/run-pass/optimization-fuel-0.rs @@ -12,4 +12,3 @@ fn main() { assert_eq!(size_of::(), 6); assert_eq!(size_of::(), 6); } - diff --git a/src/test/run-pass/proc-macro/auxiliary/expand-with-a-macro.rs b/src/test/run-pass/proc-macro/auxiliary/expand-with-a-macro.rs index 8580005f4fc..5155a4b8558 100644 --- a/src/test/run-pass/proc-macro/auxiliary/expand-with-a-macro.rs +++ b/src/test/run-pass/proc-macro/auxiliary/expand-with-a-macro.rs @@ -20,4 +20,3 @@ pub fn derive(input: TokenStream) -> TokenStream { } "#.parse().unwrap() } - diff --git a/src/test/run-pass/proc-macro/auxiliary/external-crate-var.rs b/src/test/run-pass/proc-macro/auxiliary/external-crate-var.rs index 09e5aea9b83..4319e921225 100644 --- a/src/test/run-pass/proc-macro/auxiliary/external-crate-var.rs +++ b/src/test/run-pass/proc-macro/auxiliary/external-crate-var.rs @@ -38,4 +38,3 @@ macro_rules! external { () => { } } } } - diff --git a/src/test/run-pass/proc-macro/auxiliary/span-api-tests.rs b/src/test/run-pass/proc-macro/auxiliary/span-api-tests.rs index 9092e7a49ea..ad1e770a4dc 100644 --- a/src/test/run-pass/proc-macro/auxiliary/span-api-tests.rs +++ b/src/test/run-pass/proc-macro/auxiliary/span-api-tests.rs @@ -43,4 +43,3 @@ pub fn macro_stringify(input: TokenStream) -> TokenStream { let src = span.source_text().expect("source_text"); TokenTree::Literal(Literal::string(&src)).into() } - diff --git a/src/test/run-pass/proc-macro/expand-with-a-macro.rs b/src/test/run-pass/proc-macro/expand-with-a-macro.rs index 46c8e0ef5e5..097520b993a 100644 --- a/src/test/run-pass/proc-macro/expand-with-a-macro.rs +++ b/src/test/run-pass/proc-macro/expand-with-a-macro.rs @@ -17,4 +17,3 @@ fn main() { A.a(); }).is_err()); } - diff --git a/src/test/run-pass/project-cache-issue-31849.rs b/src/test/run-pass/project-cache-issue-31849.rs index 086883e5cb3..4920678af1a 100644 --- a/src/test/run-pass/project-cache-issue-31849.rs +++ b/src/test/run-pass/project-cache-issue-31849.rs @@ -62,4 +62,3 @@ fn main() { let it = ((((((((((),()),()),()),()),()),()),()),()),()); it.build(); } - diff --git a/src/test/run-pass/range_inclusive_gate.rs b/src/test/run-pass/range_inclusive_gate.rs index 7f72bf5d325..d4d830ef223 100644 --- a/src/test/run-pass/range_inclusive_gate.rs +++ b/src/test/run-pass/range_inclusive_gate.rs @@ -10,4 +10,3 @@ fn main() { } assert_eq!(count, 55); } - diff --git a/src/test/run-pass/signal-alternate-stack-cleanup.rs b/src/test/run-pass/signal-alternate-stack-cleanup.rs index 3958e72040d..d11f3f5b5e6 100644 --- a/src/test/run-pass/signal-alternate-stack-cleanup.rs +++ b/src/test/run-pass/signal-alternate-stack-cleanup.rs @@ -33,4 +33,3 @@ fn main() { atexit(send_signal); } } - diff --git a/src/test/run-pass/thinlto/thin-lto-inlines2.rs b/src/test/run-pass/thinlto/thin-lto-inlines2.rs index f053dd35a21..1eb29657c70 100644 --- a/src/test/run-pass/thinlto/thin-lto-inlines2.rs +++ b/src/test/run-pass/thinlto/thin-lto-inlines2.rs @@ -26,4 +26,3 @@ fn main() { assert_eq!(*foo, *bar); } } - diff --git a/src/test/run-pass/try_from.rs b/src/test/run-pass/try_from.rs index e42f2c3e393..98344491aec 100644 --- a/src/test/run-pass/try_from.rs +++ b/src/test/run-pass/try_from.rs @@ -34,4 +34,3 @@ impl Into> for Foo { pub fn main() { let _: Result, Infallible> = Foo { t: 10 }.try_into(); } - diff --git a/src/test/rustdoc/auxiliary/issue-23207-2.rs b/src/test/rustdoc/auxiliary/issue-23207-2.rs index e1afb68dc79..b92b1665316 100644 --- a/src/test/rustdoc/auxiliary/issue-23207-2.rs +++ b/src/test/rustdoc/auxiliary/issue-23207-2.rs @@ -3,4 +3,3 @@ extern crate issue_23207_1; pub mod fmt { pub use issue_23207_1::fmt::Error; } - diff --git a/src/test/rustdoc/inline_cross/auxiliary/proc_macro.rs b/src/test/rustdoc/inline_cross/auxiliary/proc_macro.rs index 9836b6ba2ed..c99ef744333 100644 --- a/src/test/rustdoc/inline_cross/auxiliary/proc_macro.rs +++ b/src/test/rustdoc/inline_cross/auxiliary/proc_macro.rs @@ -25,4 +25,3 @@ pub fn some_proc_attr(_attr: TokenStream, item: TokenStream) -> TokenStream { pub fn some_derive(_item: TokenStream) -> TokenStream { TokenStream::new() } - diff --git a/src/test/rustdoc/inline_cross/auxiliary/rustdoc-trait-object-impl.rs b/src/test/rustdoc/inline_cross/auxiliary/rustdoc-trait-object-impl.rs index 76913f02cfd..11d8733c40d 100644 --- a/src/test/rustdoc/inline_cross/auxiliary/rustdoc-trait-object-impl.rs +++ b/src/test/rustdoc/inline_cross/auxiliary/rustdoc-trait-object-impl.rs @@ -11,4 +11,3 @@ impl<'a> fmt::Debug for Bar + 'a { Ok(()) } } - diff --git a/src/test/rustdoc/inline_cross/issue-32881.rs b/src/test/rustdoc/inline_cross/issue-32881.rs index f783837d060..5f31e6cd3ad 100644 --- a/src/test/rustdoc/inline_cross/issue-32881.rs +++ b/src/test/rustdoc/inline_cross/issue-32881.rs @@ -9,4 +9,3 @@ extern crate rustdoc_trait_object_impl; // @has - '//code' "impl<'a> Debug for dyn Bar" pub use rustdoc_trait_object_impl::Bar; - diff --git a/src/test/rustdoc/issue-15318-2.rs b/src/test/rustdoc/issue-15318-2.rs index 1dbfba988ef..2af811ad5bb 100644 --- a/src/test/rustdoc/issue-15318-2.rs +++ b/src/test/rustdoc/issue-15318-2.rs @@ -9,4 +9,3 @@ pub use issue_15318::ptr; // '//*[@href="primitive.pointer.html"]' \ // '*mut T' pub fn bar(ptr: *mut T) {} - diff --git a/src/test/rustdoc/issue-19190-3.rs b/src/test/rustdoc/issue-19190-3.rs index f7366302a1e..4d34ce6509f 100644 --- a/src/test/rustdoc/issue-19190-3.rs +++ b/src/test/rustdoc/issue-19190-3.rs @@ -25,4 +25,3 @@ impl Deref for MyBar { type Target = Baz; fn deref(&self) -> &Baz { loop {} } } - diff --git a/src/test/rustdoc/issue-20727-2.rs b/src/test/rustdoc/issue-20727-2.rs index 7c8b82fbe21..022ff290e1a 100644 --- a/src/test/rustdoc/issue-20727-2.rs +++ b/src/test/rustdoc/issue-20727-2.rs @@ -20,4 +20,3 @@ pub mod reexport { // @has - '//*[@class="rust trait"]' 'fn add(self, rhs: RHS) -> Self::Output;' pub use issue_20727::Add; } - diff --git a/src/test/rustdoc/issue-23207.rs b/src/test/rustdoc/issue-23207.rs index 747c59bba6a..1a4b849ee82 100644 --- a/src/test/rustdoc/issue-23207.rs +++ b/src/test/rustdoc/issue-23207.rs @@ -7,4 +7,3 @@ extern crate issue_23207_2; // @has issue_23207/fmt/index.html // @count - '//*[@class="struct"]' 1 pub use issue_23207_2::fmt; - diff --git a/src/test/rustdoc/issue-38129.rs b/src/test/rustdoc/issue-38129.rs index bf9d5e43304..156d50fa52a 100644 --- a/src/test/rustdoc/issue-38129.rs +++ b/src/test/rustdoc/issue-38129.rs @@ -97,4 +97,3 @@ pub fn both_attrs() {} /// assert_eq!(1 + 1, 2); /// ``` pub fn both_attrs_reverse() {} - diff --git a/src/test/rustdoc/issue-56701.rs b/src/test/rustdoc/issue-56701.rs index 6fb30a4ff4c..ba00743fcd1 100644 --- a/src/test/rustdoc/issue-56701.rs +++ b/src/test/rustdoc/issue-56701.rs @@ -31,4 +31,3 @@ impl>> Deref for Unrelated Pattern for Wrapper { // WriteAndThen where ::Value: Send" pub struct WriteAndThen(pub P1::Value,pub > as Pattern>::Value) where P1: Pattern; - diff --git a/src/test/ui-fulldeps/dropck-tarena-unsound-drop.rs b/src/test/ui-fulldeps/dropck-tarena-unsound-drop.rs index 3103aef36cb..e454f44d1af 100644 --- a/src/test/ui-fulldeps/dropck-tarena-unsound-drop.rs +++ b/src/test/ui-fulldeps/dropck-tarena-unsound-drop.rs @@ -40,4 +40,3 @@ fn main() { let arena: TypedArena = TypedArena::default(); f(&arena); } //~^ ERROR `arena` does not live long enough - diff --git a/src/test/ui/allocator/two-allocators.rs b/src/test/ui/allocator/two-allocators.rs index c967a45c7b4..10fb03c3930 100644 --- a/src/test/ui/allocator/two-allocators.rs +++ b/src/test/ui/allocator/two-allocators.rs @@ -7,4 +7,3 @@ static B: System = System; //~^ ERROR: cannot define more than one #[global_allocator] fn main() {} - diff --git a/src/test/ui/allocator/two-allocators2.rs b/src/test/ui/allocator/two-allocators2.rs index b7a07cc274e..96da780e4a2 100644 --- a/src/test/ui/allocator/two-allocators2.rs +++ b/src/test/ui/allocator/two-allocators2.rs @@ -10,4 +10,3 @@ use std::alloc::System; static A: System = System; fn main() {} - diff --git a/src/test/ui/auxiliary/default-ty-param-cross-crate-crate.rs b/src/test/ui/auxiliary/default-ty-param-cross-crate-crate.rs index 612f99dbcf8..d722b78768a 100644 --- a/src/test/ui/auxiliary/default-ty-param-cross-crate-crate.rs +++ b/src/test/ui/auxiliary/default-ty-param-cross-crate-crate.rs @@ -7,4 +7,3 @@ use std::marker::PhantomData; pub struct Foo(PhantomData<(A, B)>); pub fn bleh() -> Foo { Foo(PhantomData) } - diff --git a/src/test/ui/bad/bad-lint-cap3.rs b/src/test/ui/bad/bad-lint-cap3.rs index 8aab38ee5ec..4cfa0b266c8 100644 --- a/src/test/ui/bad/bad-lint-cap3.rs +++ b/src/test/ui/bad/bad-lint-cap3.rs @@ -8,4 +8,3 @@ use std::option; //~ WARN fn main() {} - diff --git a/src/test/ui/binop/binop-logic-float.rs b/src/test/ui/binop/binop-logic-float.rs index c95c1d30d1c..1750d97ba81 100644 --- a/src/test/ui/binop/binop-logic-float.rs +++ b/src/test/ui/binop/binop-logic-float.rs @@ -1,4 +1,3 @@ fn main() { let x = 1.0_f32 || 2.0_f32; } //~^ ERROR mismatched types //~| ERROR mismatched types - diff --git a/src/test/ui/borrowck/immutable-arg.rs b/src/test/ui/borrowck/immutable-arg.rs index 5a5e619ef31..8d1cd3c8045 100644 --- a/src/test/ui/borrowck/immutable-arg.rs +++ b/src/test/ui/borrowck/immutable-arg.rs @@ -7,4 +7,3 @@ fn foo(_x: u32) { } fn main() {} - diff --git a/src/test/ui/borrowck/mut-borrow-in-loop.rs b/src/test/ui/borrowck/mut-borrow-in-loop.rs index 6b65b903757..09f3e4f9b76 100644 --- a/src/test/ui/borrowck/mut-borrow-in-loop.rs +++ b/src/test/ui/borrowck/mut-borrow-in-loop.rs @@ -27,4 +27,3 @@ impl<'a, T : 'a> FuncWrapper<'a, T> { fn main() { } - diff --git a/src/test/ui/borrowck/two-phase-reservation-sharing-interference.rs b/src/test/ui/borrowck/two-phase-reservation-sharing-interference.rs index d8e60c5859e..de6f66c1c3f 100644 --- a/src/test/ui/borrowck/two-phase-reservation-sharing-interference.rs +++ b/src/test/ui/borrowck/two-phase-reservation-sharing-interference.rs @@ -47,4 +47,3 @@ fn main() { // flummoxes our attmpt to delay the activation point here.) delay.push(2); } - diff --git a/src/test/ui/call-fn-never-arg-wrong-type.rs b/src/test/ui/call-fn-never-arg-wrong-type.rs index 7ed1162171f..d06637e74a2 100644 --- a/src/test/ui/call-fn-never-arg-wrong-type.rs +++ b/src/test/ui/call-fn-never-arg-wrong-type.rs @@ -9,4 +9,3 @@ fn foo(x: !) -> ! { fn main() { foo("wow"); //~ ERROR mismatched types } - diff --git a/src/test/ui/consts/const-eval/const-eval-overflow-3b.rs b/src/test/ui/consts/const-eval/const-eval-overflow-3b.rs index d9b06370dff..db6f17a671a 100644 --- a/src/test/ui/consts/const-eval/const-eval-overflow-3b.rs +++ b/src/test/ui/consts/const-eval/const-eval-overflow-3b.rs @@ -7,12 +7,6 @@ // types for the left- and right-hand sides of the addition do not // match (as well as overflow). - - - - - - #![allow(unused_imports)] use std::fmt; @@ -32,4 +26,3 @@ fn main() { fn foo(x: T) { println!("{:?}", x); } - diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.rs b/src/test/ui/consts/min_const_fn/min_const_fn.rs index 881cbb14b53..783c79005ae 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn.rs +++ b/src/test/ui/consts/min_const_fn/min_const_fn.rs @@ -148,4 +148,3 @@ const fn no_fn_ptrs(_x: fn()) {} //~^ ERROR function pointers in const fn are unstable const fn no_fn_ptrs2() -> fn() { fn foo() {} foo } //~^ ERROR function pointers in const fn are unstable - diff --git a/src/test/ui/consts/union_constant.rs b/src/test/ui/consts/union_constant.rs index 074014908ba..6b6042194ba 100644 --- a/src/test/ui/consts/union_constant.rs +++ b/src/test/ui/consts/union_constant.rs @@ -8,4 +8,3 @@ union Uninit { const UNINIT: Uninit = Uninit { uninit: () }; fn main() {} - diff --git a/src/test/ui/defaulted-never-note.rs b/src/test/ui/defaulted-never-note.rs index acda4b42f15..cf1922ecc78 100644 --- a/src/test/ui/defaulted-never-note.rs +++ b/src/test/ui/defaulted-never-note.rs @@ -32,4 +32,3 @@ fn smeg() { fn main() { smeg(); } - diff --git a/src/test/ui/derive-uninhabited-enum-38885.rs b/src/test/ui/derive-uninhabited-enum-38885.rs index c0279d60e24..b314eacc92e 100644 --- a/src/test/ui/derive-uninhabited-enum-38885.rs +++ b/src/test/ui/derive-uninhabited-enum-38885.rs @@ -14,4 +14,3 @@ enum Foo { //~ WARN never used } fn main() {} - diff --git a/src/test/ui/derives/deriving-copyclone.rs b/src/test/ui/derives/deriving-copyclone.rs index afe61969071..4565412bff7 100644 --- a/src/test/ui/derives/deriving-copyclone.rs +++ b/src/test/ui/derives/deriving-copyclone.rs @@ -35,4 +35,3 @@ fn main() { is_copy(B { a: 1, b: D }); //~ERROR Copy is_clone(B { a: 1, b: D }); } - diff --git a/src/test/ui/derives/deriving-primitive.rs b/src/test/ui/derives/deriving-primitive.rs index 53acf6164d9..c7098d4b563 100644 --- a/src/test/ui/derives/deriving-primitive.rs +++ b/src/test/ui/derives/deriving-primitive.rs @@ -2,4 +2,3 @@ enum Foo {} fn main() {} - diff --git a/src/test/ui/did_you_mean/recursion_limit_deref.rs b/src/test/ui/did_you_mean/recursion_limit_deref.rs index 76e555e5aa6..613843801d4 100644 --- a/src/test/ui/did_you_mean/recursion_limit_deref.rs +++ b/src/test/ui/did_you_mean/recursion_limit_deref.rs @@ -50,4 +50,3 @@ fn main() { let x: &Bottom = &t; //~ ERROR mismatched types //~^ error recursion limit } - diff --git a/src/test/ui/did_you_mean/recursion_limit_macro.rs b/src/test/ui/did_you_mean/recursion_limit_macro.rs index c9415361cf8..a68a5ece7cf 100644 --- a/src/test/ui/did_you_mean/recursion_limit_macro.rs +++ b/src/test/ui/did_you_mean/recursion_limit_macro.rs @@ -13,4 +13,3 @@ macro_rules! recurse { fn main() { recurse!(0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9); } - diff --git a/src/test/ui/existential_types/auxiliary/cross_crate_ice.rs b/src/test/ui/existential_types/auxiliary/cross_crate_ice.rs index af2d209826e..96ab476061d 100644 --- a/src/test/ui/existential_types/auxiliary/cross_crate_ice.rs +++ b/src/test/ui/existential_types/auxiliary/cross_crate_ice.rs @@ -9,4 +9,3 @@ pub existential type Foo: std::fmt::Debug; pub fn foo() -> Foo { 5 } - diff --git a/src/test/ui/existential_types/generic_duplicate_param_use7.rs b/src/test/ui/existential_types/generic_duplicate_param_use7.rs index 2bcac315f5a..5d8d05c3087 100644 --- a/src/test/ui/existential_types/generic_duplicate_param_use7.rs +++ b/src/test/ui/existential_types/generic_duplicate_param_use7.rs @@ -22,4 +22,3 @@ fn four(t: T, t2: T, u: U, v: V) -> Two { fn five(x: X, y: Y, y2: Y) -> Two { (y, y2) } - diff --git a/src/test/ui/existential_types/nested_existential_types.rs b/src/test/ui/existential_types/nested_existential_types.rs index 62a47799914..6d2a12da7e4 100644 --- a/src/test/ui/existential_types/nested_existential_types.rs +++ b/src/test/ui/existential_types/nested_existential_types.rs @@ -18,4 +18,3 @@ mod my_mod { fn main() { let _: my_mod::Foot = my_mod::get_foot(); } - diff --git a/src/test/ui/feature-gates/feature-gate-allocator_internals.rs b/src/test/ui/feature-gates/feature-gate-allocator_internals.rs index 2045857e4cb..a17d17da607 100644 --- a/src/test/ui/feature-gates/feature-gate-allocator_internals.rs +++ b/src/test/ui/feature-gates/feature-gate-allocator_internals.rs @@ -1,4 +1,3 @@ #![default_lib_allocator] //~ ERROR: attribute is an experimental feature fn main() {} - diff --git a/src/test/ui/feature-gates/feature-gate-compiler-builtins.rs b/src/test/ui/feature-gates/feature-gate-compiler-builtins.rs index 10a9749ee5c..0d64f1fdcf5 100644 --- a/src/test/ui/feature-gates/feature-gate-compiler-builtins.rs +++ b/src/test/ui/feature-gates/feature-gate-compiler-builtins.rs @@ -1,4 +1,3 @@ #![compiler_builtins] //~ ERROR the `#[compiler_builtins]` attribute is fn main() {} - diff --git a/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.rs b/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.rs index dce8cf46ff9..27ff5ace25d 100644 --- a/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.rs +++ b/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.rs @@ -6,4 +6,3 @@ fn foo() -> Result { fn main() { let Ok(_x) = foo(); //~ ERROR refutable pattern in local binding } - diff --git a/src/test/ui/feature-gates/feature-gate-needs-allocator.rs b/src/test/ui/feature-gates/feature-gate-needs-allocator.rs index a3f91d02b3e..08954944bcd 100644 --- a/src/test/ui/feature-gates/feature-gate-needs-allocator.rs +++ b/src/test/ui/feature-gates/feature-gate-needs-allocator.rs @@ -1,4 +1,3 @@ #![needs_allocator] //~ ERROR the `#[needs_allocator]` attribute is fn main() {} - diff --git a/src/test/ui/feature-gates/feature-gate-nll.rs b/src/test/ui/feature-gates/feature-gate-nll.rs index 2cf6e4d5209..ec5eacd1625 100644 --- a/src/test/ui/feature-gates/feature-gate-nll.rs +++ b/src/test/ui/feature-gates/feature-gate-nll.rs @@ -17,4 +17,3 @@ fn main() { //~ ERROR compilation successful //~| WARNING this warning will become a hard error in the future m; } - diff --git a/src/test/ui/feature-gates/feature-gate-rustc_const_unstable.rs b/src/test/ui/feature-gates/feature-gate-rustc_const_unstable.rs index a85f2f4ad30..6961e68744f 100644 --- a/src/test/ui/feature-gates/feature-gate-rustc_const_unstable.rs +++ b/src/test/ui/feature-gates/feature-gate-rustc_const_unstable.rs @@ -10,4 +10,3 @@ pub const fn bazinga() {} fn main() { } - diff --git a/src/test/ui/generator/borrowing.rs b/src/test/ui/generator/borrowing.rs index 9f8fc7483f6..6234b738048 100644 --- a/src/test/ui/generator/borrowing.rs +++ b/src/test/ui/generator/borrowing.rs @@ -18,4 +18,3 @@ fn main() { } }; } - diff --git a/src/test/ui/generator/issue-53548.rs b/src/test/ui/generator/issue-53548.rs index 00fdb91faab..73a2bcdd555 100644 --- a/src/test/ui/generator/issue-53548.rs +++ b/src/test/ui/generator/issue-53548.rs @@ -36,4 +36,3 @@ fn main() { yield (); }); } - diff --git a/src/test/ui/impl-trait/auto-trait-leak2.rs b/src/test/ui/impl-trait/auto-trait-leak2.rs index a373edcfcf9..e529b4757ed 100644 --- a/src/test/ui/impl-trait/auto-trait-leak2.rs +++ b/src/test/ui/impl-trait/auto-trait-leak2.rs @@ -25,4 +25,3 @@ fn after() -> impl Fn(i32) { let p = Rc::new(Cell::new(0)); move |x| p.set(x) } - diff --git a/src/test/ui/issues/issue-26905.rs b/src/test/ui/issues/issue-26905.rs index 0cd166f4ac6..efd06219c3d 100644 --- a/src/test/ui/issues/issue-26905.rs +++ b/src/test/ui/issues/issue-26905.rs @@ -21,4 +21,3 @@ fn main() { let x = MyRc { _ptr: &iter, _boo: NotPhantomData(PhantomData) }; let _y: MyRc> = x; } - diff --git a/src/test/ui/issues/issue-30236.rs b/src/test/ui/issues/issue-30236.rs index 02f899be09c..9c2d855076d 100644 --- a/src/test/ui/issues/issue-30236.rs +++ b/src/test/ui/issues/issue-30236.rs @@ -5,4 +5,3 @@ type Foo< fn main() { } - diff --git a/src/test/ui/issues/issue-30240-b.rs b/src/test/ui/issues/issue-30240-b.rs index 2df06842e18..01a6e7d8cb9 100644 --- a/src/test/ui/issues/issue-30240-b.rs +++ b/src/test/ui/issues/issue-30240-b.rs @@ -13,4 +13,3 @@ fn main() { _ => {}, } } - diff --git a/src/test/ui/issues/issue-33264.rs b/src/test/ui/issues/issue-33264.rs index 7cba4df7d82..51608b48be2 100644 --- a/src/test/ui/issues/issue-33264.rs +++ b/src/test/ui/issues/issue-33264.rs @@ -27,4 +27,3 @@ impl D32x4 { } fn main() { } - diff --git a/src/test/ui/issues/issue-33287.rs b/src/test/ui/issues/issue-33287.rs index c6e1f4d1eb2..cc47e58fcdc 100644 --- a/src/test/ui/issues/issue-33287.rs +++ b/src/test/ui/issues/issue-33287.rs @@ -8,4 +8,3 @@ fn test() { } fn main() { } - diff --git a/src/test/ui/issues/issue-33903.rs b/src/test/ui/issues/issue-33903.rs index 98544aca5f9..4fdc8dda8b4 100644 --- a/src/test/ui/issues/issue-33903.rs +++ b/src/test/ui/issues/issue-33903.rs @@ -8,4 +8,3 @@ const FOO: i32 = [12, 34][0 + 1]; fn main() {} - diff --git a/src/test/ui/issues/issue-40782.rs b/src/test/ui/issues/issue-40782.rs index 55fec04e0e0..60db19ef915 100644 --- a/src/test/ui/issues/issue-40782.rs +++ b/src/test/ui/issues/issue-40782.rs @@ -2,4 +2,3 @@ fn main() { for i 0..2 { //~ ERROR missing `in` } } - diff --git a/src/test/ui/issues/issue-42060.rs b/src/test/ui/issues/issue-42060.rs index da7c03032eb..1740b238343 100644 --- a/src/test/ui/issues/issue-42060.rs +++ b/src/test/ui/issues/issue-42060.rs @@ -9,4 +9,3 @@ fn f(){ ::N //~ ERROR attempt to use a non-constant value in a constant //~^ ERROR `typeof` is a reserved keyword but unimplemented [E0516] } - diff --git a/src/test/ui/issues/issue-43196.rs b/src/test/ui/issues/issue-43196.rs index 81e5205ce33..0eefa01ce6d 100644 --- a/src/test/ui/issues/issue-43196.rs +++ b/src/test/ui/issues/issue-43196.rs @@ -4,4 +4,3 @@ fn main() { //~^ ERROR expected `|`, found `}` | //~^ ERROR expected item, found `|` - diff --git a/src/test/ui/issues/issue-44005.rs b/src/test/ui/issues/issue-44005.rs index e2625fd9379..f6d1b7073a2 100644 --- a/src/test/ui/issues/issue-44005.rs +++ b/src/test/ui/issues/issue-44005.rs @@ -27,4 +27,3 @@ pub fn broken(x: &i32, f: F) { } fn main() { } - diff --git a/src/test/ui/issues/issue-49851/compiler-builtins-error.rs b/src/test/ui/issues/issue-49851/compiler-builtins-error.rs index 0163da0771e..3484ff3b874 100644 --- a/src/test/ui/issues/issue-49851/compiler-builtins-error.rs +++ b/src/test/ui/issues/issue-49851/compiler-builtins-error.rs @@ -8,4 +8,3 @@ #![no_std] extern crate cortex_m; - diff --git a/src/test/ui/issues/issue-50714-1.rs b/src/test/ui/issues/issue-50714-1.rs index 31de3f3c0a1..a25940ce1cb 100644 --- a/src/test/ui/issues/issue-50714-1.rs +++ b/src/test/ui/issues/issue-50714-1.rs @@ -9,4 +9,3 @@ extern crate std; fn start(_: isize, _: *const *const u8) -> isize where fn(&()): Eq { //~ ERROR [E0647] 0 } - diff --git a/src/test/ui/issues/issue-50714.rs b/src/test/ui/issues/issue-50714.rs index 3683d4bdacc..c571a470cee 100644 --- a/src/test/ui/issues/issue-50714.rs +++ b/src/test/ui/issues/issue-50714.rs @@ -1,4 +1,3 @@ // Regression test for issue 50714, make sure that this isn't a linker error. fn main() where fn(&()): Eq {} //~ ERROR [E0646] - diff --git a/src/test/ui/issues/issue-53419.rs b/src/test/ui/issues/issue-53419.rs index fc2a926f90f..52149cf486d 100644 --- a/src/test/ui/issues/issue-53419.rs +++ b/src/test/ui/issues/issue-53419.rs @@ -6,4 +6,3 @@ struct Foo { fn main() { } - diff --git a/src/test/ui/issues/issue-53568.rs b/src/test/ui/issues/issue-53568.rs index 60a6e16492c..f04d861250b 100644 --- a/src/test/ui/issues/issue-53568.rs +++ b/src/test/ui/issues/issue-53568.rs @@ -48,4 +48,3 @@ where H: Fn() + Copy } fn main() { } - diff --git a/src/test/ui/issues/issue-58712.rs b/src/test/ui/issues/issue-58712.rs index 577709cf291..930bec6889b 100644 --- a/src/test/ui/issues/issue-58712.rs +++ b/src/test/ui/issues/issue-58712.rs @@ -12,4 +12,3 @@ impl AddrVec { } fn main() {} - diff --git a/src/test/ui/issues/issue-59488.rs b/src/test/ui/issues/issue-59488.rs index 7d8d5f5e7ea..e0a37f6adcc 100644 --- a/src/test/ui/issues/issue-59488.rs +++ b/src/test/ui/issues/issue-59488.rs @@ -34,4 +34,3 @@ fn main() { //~| ERROR `fn(usize) -> Foo {Foo::Bar}` doesn't implement `std::fmt::Debug` [E0277] //~| ERROR `fn(usize) -> Foo {Foo::Bar}` doesn't implement `std::fmt::Debug` [E0277] } - diff --git a/src/test/ui/issues/issue-59896.rs b/src/test/ui/issues/issue-59896.rs index cecf2c5c22b..ff9f19acf84 100644 --- a/src/test/ui/issues/issue-59896.rs +++ b/src/test/ui/issues/issue-59896.rs @@ -7,4 +7,3 @@ fn main() { let _s = S; } - diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.rs b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.rs index c04b5d3a3eb..c483f59f9d9 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.rs +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.rs @@ -4,4 +4,3 @@ fn foo(z: &mut Vec<(&u8,&u8)>, (x, y): (&u8, &u8)) { } fn main() { } - diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.rs b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.rs index 09852403d93..286cb6dc90e 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.rs +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.rs @@ -9,4 +9,3 @@ impl Foo { } fn main() { } - diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.rs b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.rs index 33aa199938f..79d7d63c8bb 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.rs +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.rs @@ -9,4 +9,3 @@ impl Foo { } fn main() {} - diff --git a/src/test/ui/macro_backtrace/auxiliary/ping.rs b/src/test/ui/macro_backtrace/auxiliary/ping.rs index efddb209cda..25b9efbc93a 100644 --- a/src/test/ui/macro_backtrace/auxiliary/ping.rs +++ b/src/test/ui/macro_backtrace/auxiliary/ping.rs @@ -28,4 +28,3 @@ macro_rules! bar { ping!(); } } - diff --git a/src/test/ui/macros/macro-follow.rs b/src/test/ui/macros/macro-follow.rs index 10b44e00175..8054418d9b8 100644 --- a/src/test/ui/macros/macro-follow.rs +++ b/src/test/ui/macros/macro-follow.rs @@ -112,4 +112,3 @@ macro_rules! follow_path { // FOLLOW(ident) = any token fn main() {} - diff --git a/src/test/ui/macros/must-use-in-macro-55516.rs b/src/test/ui/macros/must-use-in-macro-55516.rs index 10e5646dc3d..a5de32e5d2a 100644 --- a/src/test/ui/macros/must-use-in-macro-55516.rs +++ b/src/test/ui/macros/must-use-in-macro-55516.rs @@ -8,4 +8,3 @@ fn main() { let mut example = String::new(); write!(&mut example, "{}", 42); //~WARN must be used } - diff --git a/src/test/ui/match/match-argm-statics-2.rs b/src/test/ui/match/match-argm-statics-2.rs index ad220d2f431..4c5f2d35649 100644 --- a/src/test/ui/match/match-argm-statics-2.rs +++ b/src/test/ui/match/match-argm-statics-2.rs @@ -60,4 +60,3 @@ fn main() { nonexhaustive_2(); nonexhaustive_3(); } - diff --git a/src/test/ui/match/match-byte-array-patterns-2.rs b/src/test/ui/match/match-byte-array-patterns-2.rs index a3a47d23bef..33468d03fae 100644 --- a/src/test/ui/match/match-byte-array-patterns-2.rs +++ b/src/test/ui/match/match-byte-array-patterns-2.rs @@ -11,4 +11,3 @@ fn main() { b"AAAA" => {} } } - diff --git a/src/test/ui/mismatched_types/main.rs b/src/test/ui/mismatched_types/main.rs index 16c18ddda29..e2d09dc2199 100644 --- a/src/test/ui/mismatched_types/main.rs +++ b/src/test/ui/mismatched_types/main.rs @@ -2,4 +2,3 @@ fn main() { let x: u32 = ( //~ ERROR mismatched types ); } - diff --git a/src/test/ui/mismatched_types/numeric-literal-cast.rs b/src/test/ui/mismatched_types/numeric-literal-cast.rs index 74a22117099..69cfe262fdf 100644 --- a/src/test/ui/mismatched_types/numeric-literal-cast.rs +++ b/src/test/ui/mismatched_types/numeric-literal-cast.rs @@ -10,4 +10,3 @@ fn main() { foo2(3i16); //~^ ERROR mismatched types } - diff --git a/src/test/ui/mismatched_types/trait-impl-fn-incompatibility.rs b/src/test/ui/mismatched_types/trait-impl-fn-incompatibility.rs index 3547272e51b..949f5683c8a 100644 --- a/src/test/ui/mismatched_types/trait-impl-fn-incompatibility.rs +++ b/src/test/ui/mismatched_types/trait-impl-fn-incompatibility.rs @@ -14,4 +14,3 @@ impl Foo for Bar { fn main() { } - diff --git a/src/test/ui/nll/issue-47022.rs b/src/test/ui/nll/issue-47022.rs index c0f8efa2498..1add2c334da 100644 --- a/src/test/ui/nll/issue-47022.rs +++ b/src/test/ui/nll/issue-47022.rs @@ -34,4 +34,3 @@ fn convert(objects: Vec) -> (Vec, Vec) { } fn main() {} - diff --git a/src/test/ui/nll/projection-return.rs b/src/test/ui/nll/projection-return.rs index b2c9a087e0e..fdf3f594841 100644 --- a/src/test/ui/nll/projection-return.rs +++ b/src/test/ui/nll/projection-return.rs @@ -16,4 +16,3 @@ fn foo() -> <() as Foo>::Bar { } fn main() { } - diff --git a/src/test/ui/nll/ty-outlives/issue-53789-1.rs b/src/test/ui/nll/ty-outlives/issue-53789-1.rs index 593cdfdbf71..586f076c8ca 100644 --- a/src/test/ui/nll/ty-outlives/issue-53789-1.rs +++ b/src/test/ui/nll/ty-outlives/issue-53789-1.rs @@ -88,4 +88,3 @@ fn any_with<'a, A: Arbitrary<'a>>(args: A::Parameters) -> StrategyType<'a, A> { } fn main() { } - diff --git a/src/test/ui/nll/ty-outlives/issue-53789-2.rs b/src/test/ui/nll/ty-outlives/issue-53789-2.rs index 62e2833aa1b..de8b05aeed7 100644 --- a/src/test/ui/nll/ty-outlives/issue-53789-2.rs +++ b/src/test/ui/nll/ty-outlives/issue-53789-2.rs @@ -248,4 +248,3 @@ mod statics { } fn main() { } - diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.rs b/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.rs index 058ebaee9e5..9f0c60967ef 100644 --- a/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.rs +++ b/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.rs @@ -12,4 +12,3 @@ fn foo<'a>(_: &'a u32) -> &'static u32 { fn main() { } - diff --git a/src/test/ui/on-unimplemented/no-debug.rs b/src/test/ui/on-unimplemented/no-debug.rs index 858df17ffda..45c9ea46fa2 100644 --- a/src/test/ui/on-unimplemented/no-debug.rs +++ b/src/test/ui/on-unimplemented/no-debug.rs @@ -14,4 +14,3 @@ fn main() { //~| ERROR `no_debug::Bar` doesn't implement `std::fmt::Debug` //~^^^^ ERROR `Foo` doesn't implement `std::fmt::Display` //~| ERROR `no_debug::Bar` doesn't implement `std::fmt::Display` - diff --git a/src/test/ui/panic-runtime/libtest-unwinds.rs b/src/test/ui/panic-runtime/libtest-unwinds.rs index 47dd8c3efe5..bc13072612a 100644 --- a/src/test/ui/panic-runtime/libtest-unwinds.rs +++ b/src/test/ui/panic-runtime/libtest-unwinds.rs @@ -8,4 +8,3 @@ extern crate test; fn main() { } - diff --git a/src/test/ui/proc-macro/auxiliary/derive-bad.rs b/src/test/ui/proc-macro/auxiliary/derive-bad.rs index 468410972fb..90bb9b1baf2 100644 --- a/src/test/ui/proc-macro/auxiliary/derive-bad.rs +++ b/src/test/ui/proc-macro/auxiliary/derive-bad.rs @@ -11,4 +11,3 @@ use proc_macro::TokenStream; pub fn derive_a(_input: TokenStream) -> TokenStream { "struct A { inner }".parse().unwrap() } - diff --git a/src/test/ui/proc-macro/issue-50493.rs b/src/test/ui/proc-macro/issue-50493.rs index eeb08f5eebd..5d1a9f25baf 100644 --- a/src/test/ui/proc-macro/issue-50493.rs +++ b/src/test/ui/proc-macro/issue-50493.rs @@ -11,4 +11,3 @@ struct Restricted { mod restricted {} fn main() {} - diff --git a/src/test/ui/range/range_traits-2.rs b/src/test/ui/range/range_traits-2.rs index c34ef781d8c..234d7a64dc8 100644 --- a/src/test/ui/range/range_traits-2.rs +++ b/src/test/ui/range/range_traits-2.rs @@ -4,4 +4,3 @@ use std::ops::*; struct R(Range); fn main() {} - diff --git a/src/test/ui/range/range_traits-3.rs b/src/test/ui/range/range_traits-3.rs index b0448afce04..2d597cce5ad 100644 --- a/src/test/ui/range/range_traits-3.rs +++ b/src/test/ui/range/range_traits-3.rs @@ -4,4 +4,3 @@ use std::ops::*; struct R(RangeFrom); fn main() {} - diff --git a/src/test/ui/range/range_traits-4.rs b/src/test/ui/range/range_traits-4.rs index ff845770483..52c706080f3 100644 --- a/src/test/ui/range/range_traits-4.rs +++ b/src/test/ui/range/range_traits-4.rs @@ -7,4 +7,3 @@ struct R(RangeTo); fn main() {} - diff --git a/src/test/ui/range/range_traits-5.rs b/src/test/ui/range/range_traits-5.rs index 95505c94d1f..a8c3e9b0d62 100644 --- a/src/test/ui/range/range_traits-5.rs +++ b/src/test/ui/range/range_traits-5.rs @@ -7,4 +7,3 @@ struct R(RangeFull); fn main() {} - diff --git a/src/test/ui/range/range_traits-6.rs b/src/test/ui/range/range_traits-6.rs index 041f04a3498..bce106bbfe7 100644 --- a/src/test/ui/range/range_traits-6.rs +++ b/src/test/ui/range/range_traits-6.rs @@ -4,4 +4,3 @@ use std::ops::*; struct R(RangeInclusive); fn main() {} - diff --git a/src/test/ui/range/range_traits-7.rs b/src/test/ui/range/range_traits-7.rs index c328ecb223a..548676063ca 100644 --- a/src/test/ui/range/range_traits-7.rs +++ b/src/test/ui/range/range_traits-7.rs @@ -7,4 +7,3 @@ struct R(RangeToInclusive); fn main() {} - diff --git a/src/test/ui/recursion/recursive-types-are-not-uninhabited.rs b/src/test/ui/recursion/recursive-types-are-not-uninhabited.rs index b3e4efb9940..44893036383 100644 --- a/src/test/ui/recursion/recursive-types-are-not-uninhabited.rs +++ b/src/test/ui/recursion/recursive-types-are-not-uninhabited.rs @@ -11,4 +11,3 @@ fn foo(res: Result) -> u32 { fn main() { foo(Ok(23)); } - diff --git a/src/test/ui/regions/region-borrow-params-issue-29793-small.rs b/src/test/ui/regions/region-borrow-params-issue-29793-small.rs index 0d8c9fb2699..a1ccf667671 100644 --- a/src/test/ui/regions/region-borrow-params-issue-29793-small.rs +++ b/src/test/ui/regions/region-borrow-params-issue-29793-small.rs @@ -210,4 +210,3 @@ fn move_of_trait_default_params() { } fn main() { } - diff --git a/src/test/ui/return/return-from-diverging.rs b/src/test/ui/return/return-from-diverging.rs index faeccaace69..2ee48e7bc47 100644 --- a/src/test/ui/return/return-from-diverging.rs +++ b/src/test/ui/return/return-from-diverging.rs @@ -6,4 +6,3 @@ fn fail() -> ! { fn main() { } - diff --git a/src/test/ui/return/return-unit-from-diverging.rs b/src/test/ui/return/return-unit-from-diverging.rs index 31a13784b47..48417599b1d 100644 --- a/src/test/ui/return/return-unit-from-diverging.rs +++ b/src/test/ui/return/return-unit-from-diverging.rs @@ -7,4 +7,3 @@ fn fail() -> ! { fn main() { } - diff --git a/src/test/ui/rfc-2093-infer-outlives/cross-crate.rs b/src/test/ui/rfc-2093-infer-outlives/cross-crate.rs index ce50452dd52..a9bfeabf16e 100644 --- a/src/test/ui/rfc-2093-infer-outlives/cross-crate.rs +++ b/src/test/ui/rfc-2093-infer-outlives/cross-crate.rs @@ -6,4 +6,3 @@ struct Foo<'a, T> { //~ ERROR rustc_outlives } fn main() {} - diff --git a/src/test/ui/rfc-2093-infer-outlives/dont-infer-static.rs b/src/test/ui/rfc-2093-infer-outlives/dont-infer-static.rs index 812e8c8bb3e..9e81ee46169 100644 --- a/src/test/ui/rfc-2093-infer-outlives/dont-infer-static.rs +++ b/src/test/ui/rfc-2093-infer-outlives/dont-infer-static.rs @@ -14,4 +14,3 @@ struct Bar { } fn main() {} - diff --git a/src/test/ui/rfc-2093-infer-outlives/explicit-enum.rs b/src/test/ui/rfc-2093-infer-outlives/explicit-enum.rs index b7a66a326b8..c330c27fea0 100644 --- a/src/test/ui/rfc-2093-infer-outlives/explicit-enum.rs +++ b/src/test/ui/rfc-2093-infer-outlives/explicit-enum.rs @@ -11,4 +11,3 @@ struct Bar<'x, T> where T: 'x { } fn main() {} - diff --git a/src/test/ui/rfc-2093-infer-outlives/explicit-struct.rs b/src/test/ui/rfc-2093-infer-outlives/explicit-struct.rs index 3c69f9f612e..3d5e610b934 100644 --- a/src/test/ui/rfc-2093-infer-outlives/explicit-struct.rs +++ b/src/test/ui/rfc-2093-infer-outlives/explicit-struct.rs @@ -11,4 +11,3 @@ struct Bar<'a, T> where T: 'a { } fn main() {} - diff --git a/src/test/ui/rfc-2093-infer-outlives/explicit-union.rs b/src/test/ui/rfc-2093-infer-outlives/explicit-union.rs index 87a789b06a0..a16fb7670a6 100644 --- a/src/test/ui/rfc-2093-infer-outlives/explicit-union.rs +++ b/src/test/ui/rfc-2093-infer-outlives/explicit-union.rs @@ -13,4 +13,3 @@ union Bar<'a, T> where T: 'a { } fn main() {} - diff --git a/src/test/ui/rfc-2093-infer-outlives/infer-static.rs b/src/test/ui/rfc-2093-infer-outlives/infer-static.rs index 916d4849edb..bd778e3b136 100644 --- a/src/test/ui/rfc-2093-infer-outlives/infer-static.rs +++ b/src/test/ui/rfc-2093-infer-outlives/infer-static.rs @@ -10,4 +10,3 @@ struct Bar { } fn main() {} - diff --git a/src/test/ui/rfc-2093-infer-outlives/projection.rs b/src/test/ui/rfc-2093-infer-outlives/projection.rs index 0b9637e9528..411c86da1de 100644 --- a/src/test/ui/rfc-2093-infer-outlives/projection.rs +++ b/src/test/ui/rfc-2093-infer-outlives/projection.rs @@ -6,4 +6,3 @@ struct Foo<'a, T: Iterator> { //~ ERROR rustc_outlives } fn main() {} - diff --git a/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.rs b/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.rs index 02e3e83df12..47674bc19fc 100644 --- a/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.rs +++ b/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.rs @@ -23,4 +23,3 @@ fn main() { // But this should be a use of the (renamed) crate: crate::bar::foo(); } - diff --git a/src/test/ui/rust-2018/extern-crate-idiomatic.rs b/src/test/ui/rust-2018/extern-crate-idiomatic.rs index 38dddf38d30..3111b1dabcb 100644 --- a/src/test/ui/rust-2018/extern-crate-idiomatic.rs +++ b/src/test/ui/rust-2018/extern-crate-idiomatic.rs @@ -16,4 +16,3 @@ use edition_lint_paths::foo; fn main() { foo(); } - diff --git a/src/test/ui/rust-2018/extern-crate-referenced-by-self-path.rs b/src/test/ui/rust-2018/extern-crate-referenced-by-self-path.rs index e249c8a026d..11b9a67ed70 100644 --- a/src/test/ui/rust-2018/extern-crate-referenced-by-self-path.rs +++ b/src/test/ui/rust-2018/extern-crate-referenced-by-self-path.rs @@ -15,4 +15,3 @@ use self::edition_lint_paths::foo; fn main() { foo(); } - diff --git a/src/test/ui/rust-2018/extern-crate-rename.rs b/src/test/ui/rust-2018/extern-crate-rename.rs index 98c7d341bff..8f14f2f1fec 100644 --- a/src/test/ui/rust-2018/extern-crate-rename.rs +++ b/src/test/ui/rust-2018/extern-crate-rename.rs @@ -16,4 +16,3 @@ use my_crate::foo; fn main() { foo(); } - diff --git a/src/test/ui/rust-2018/extern-crate-submod.rs b/src/test/ui/rust-2018/extern-crate-submod.rs index 206f3903b47..f3a357917cc 100644 --- a/src/test/ui/rust-2018/extern-crate-submod.rs +++ b/src/test/ui/rust-2018/extern-crate-submod.rs @@ -23,4 +23,3 @@ use m::edition_lint_paths::foo; fn main() { foo(); } - diff --git a/src/test/ui/self/suggest-self.rs b/src/test/ui/self/suggest-self.rs index 9d81b6fd7ca..1cc17116ea7 100644 --- a/src/test/ui/self/suggest-self.rs +++ b/src/test/ui/self/suggest-self.rs @@ -39,4 +39,3 @@ fn main() { let len = this.len(); let len = my.len(); } - diff --git a/src/test/ui/span/dropck-object-cycle.rs b/src/test/ui/span/dropck-object-cycle.rs index 7b7f37d53f1..8dc70ea252b 100644 --- a/src/test/ui/span/dropck-object-cycle.rs +++ b/src/test/ui/span/dropck-object-cycle.rs @@ -45,4 +45,3 @@ pub fn main() { // the type of `m` *strictly outlives* `'m`. Hence we get an // error. } - diff --git a/src/test/ui/span/suggestion-non-ascii.rs b/src/test/ui/span/suggestion-non-ascii.rs index 74032cf0266..914efd85a0c 100644 --- a/src/test/ui/span/suggestion-non-ascii.rs +++ b/src/test/ui/span/suggestion-non-ascii.rs @@ -2,4 +2,3 @@ fn main() { let tup = (1,); println!("☃{}", tup[0]); //~ ERROR cannot index into a value of type } - diff --git a/src/test/ui/structs/struct-fields-shorthand.rs b/src/test/ui/structs/struct-fields-shorthand.rs index 45e3014f22e..1bdcc8315c1 100644 --- a/src/test/ui/structs/struct-fields-shorthand.rs +++ b/src/test/ui/structs/struct-fields-shorthand.rs @@ -9,4 +9,3 @@ fn main() { x, y, z //~ ERROR struct `Foo` has no field named `z` }; } - diff --git a/src/test/ui/transmute/transmute-imut-to-mut.rs b/src/test/ui/transmute/transmute-imut-to-mut.rs index 94361a29087..8e34e0ae8c7 100644 --- a/src/test/ui/transmute/transmute-imut-to-mut.rs +++ b/src/test/ui/transmute/transmute-imut-to-mut.rs @@ -6,4 +6,3 @@ fn main() { let _a: &mut u8 = unsafe { transmute(&1u8) }; //~^ ERROR mutating transmuted &mut T from &T may cause undefined behavior } - diff --git a/src/test/ui/trivial-bounds/trivial-bounds-leak.rs b/src/test/ui/trivial-bounds/trivial-bounds-leak.rs index dc4f1c7f9fc..249051d8067 100644 --- a/src/test/ui/trivial-bounds/trivial-bounds-leak.rs +++ b/src/test/ui/trivial-bounds/trivial-bounds-leak.rs @@ -29,4 +29,3 @@ fn foo() { fn generic_function(t: T) {} fn main() {} - diff --git a/src/test/ui/try-block/try-block-bad-lifetime.rs b/src/test/ui/try-block/try-block-bad-lifetime.rs index 872604f4eee..6063e2e463e 100644 --- a/src/test/ui/try-block/try-block-bad-lifetime.rs +++ b/src/test/ui/try-block/try-block-bad-lifetime.rs @@ -35,4 +35,3 @@ pub fn main() { *i_ptr = 50; } } - diff --git a/src/test/ui/try-block/try-block-maybe-bad-lifetime.rs b/src/test/ui/try-block/try-block-maybe-bad-lifetime.rs index 113d089c757..1d1c3d980e2 100644 --- a/src/test/ui/try-block/try-block-maybe-bad-lifetime.rs +++ b/src/test/ui/try-block/try-block-maybe-bad-lifetime.rs @@ -42,4 +42,3 @@ pub fn main() { do_something_with(j); } } - diff --git a/src/test/ui/try-block/try-block-opt-init.rs b/src/test/ui/try-block/try-block-opt-init.rs index ef559226e67..2387db8de4d 100644 --- a/src/test/ui/try-block/try-block-opt-init.rs +++ b/src/test/ui/try-block/try-block-opt-init.rs @@ -14,4 +14,3 @@ pub fn main() { }; assert_eq!(cfg_res, 5); //~ ERROR borrow of possibly uninitialized variable: `cfg_res` } - diff --git a/src/test/ui/type/type-mismatch-multiple.rs b/src/test/ui/type/type-mismatch-multiple.rs index 1904ccf5d59..b8f04ca8d4a 100644 --- a/src/test/ui/type/type-mismatch-multiple.rs +++ b/src/test/ui/type/type-mismatch-multiple.rs @@ -7,4 +7,3 @@ fn main() { let a: bool = 1; let b: i32 = true; } //~| expected bool, found integer //~| ERROR mismatched types //~| expected i32, found bool - diff --git a/src/test/ui/uninhabited/uninhabited-irrefutable.rs b/src/test/ui/uninhabited/uninhabited-irrefutable.rs index c32d3a4a0a2..48cd92719b4 100644 --- a/src/test/ui/uninhabited/uninhabited-irrefutable.rs +++ b/src/test/ui/uninhabited/uninhabited-irrefutable.rs @@ -26,4 +26,3 @@ fn main() { let x: Foo = Foo::D(123); let Foo::D(_y) = x; //~ ERROR refutable pattern in local binding: `A(_)` not covered } - diff --git a/src/test/ui/uninhabited/uninhabited-patterns.rs b/src/test/ui/uninhabited/uninhabited-patterns.rs index 609ed3d75ba..1bf01184a08 100644 --- a/src/test/ui/uninhabited/uninhabited-patterns.rs +++ b/src/test/ui/uninhabited/uninhabited-patterns.rs @@ -45,4 +45,3 @@ fn main() { //~^ ERROR unreachable pattern } } - diff --git a/src/test/ui/unreachable/unreachable-arm.rs b/src/test/ui/unreachable/unreachable-arm.rs index 9f1a5a39587..64c38968516 100644 --- a/src/test/ui/unreachable/unreachable-arm.rs +++ b/src/test/ui/unreachable/unreachable-arm.rs @@ -12,4 +12,3 @@ fn main() { _ => { } } } - diff --git a/src/test/ui/unreachable/unreachable-loop-patterns.rs b/src/test/ui/unreachable/unreachable-loop-patterns.rs index 97948063753..3c878410f77 100644 --- a/src/test/ui/unreachable/unreachable-loop-patterns.rs +++ b/src/test/ui/unreachable/unreachable-loop-patterns.rs @@ -20,4 +20,3 @@ fn main() { for _ in unimplemented!() as Void {} //~^ ERROR unreachable pattern } - diff --git a/src/test/ui/unreachable/unreachable-try-pattern.rs b/src/test/ui/unreachable/unreachable-try-pattern.rs index 1c1e01ff0e9..6665c58e457 100644 --- a/src/test/ui/unreachable/unreachable-try-pattern.rs +++ b/src/test/ui/unreachable/unreachable-try-pattern.rs @@ -39,4 +39,3 @@ fn main() { let _ = qux(Ok(123)); let _ = vom(Ok(123)); } - diff --git a/src/test/ui/unsafe/unsafe-const-fn.rs b/src/test/ui/unsafe/unsafe-const-fn.rs index cadfdd064e3..3b4becf17a7 100644 --- a/src/test/ui/unsafe/unsafe-const-fn.rs +++ b/src/test/ui/unsafe/unsafe-const-fn.rs @@ -10,4 +10,3 @@ const VAL: u32 = dummy(0xFFFF); fn main() { assert_eq!(VAL, 0xFFFF0000); } - diff --git a/src/test/ui/unsized/unsized-enum2.rs b/src/test/ui/unsized/unsized-enum2.rs index 0fe4a3acfbe..60bfb5cb640 100644 --- a/src/test/ui/unsized/unsized-enum2.rs +++ b/src/test/ui/unsized/unsized-enum2.rs @@ -72,4 +72,3 @@ enum E { fn main() { } - diff --git a/src/test/ui/wasm-import-module.rs b/src/test/ui/wasm-import-module.rs index 618bf1952aa..16d628a6187 100644 --- a/src/test/ui/wasm-import-module.rs +++ b/src/test/ui/wasm-import-module.rs @@ -8,4 +8,3 @@ extern {} extern {} fn main() {} - diff --git a/src/test/ui/wf/wf-outlives-ty-in-fn-or-trait.rs b/src/test/ui/wf/wf-outlives-ty-in-fn-or-trait.rs index 1c4cda261d1..ac95cbab1f7 100644 --- a/src/test/ui/wf/wf-outlives-ty-in-fn-or-trait.rs +++ b/src/test/ui/wf/wf-outlives-ty-in-fn-or-trait.rs @@ -20,4 +20,3 @@ impl<'a, T> Trait<'a, T> for u32 { } fn main() { } - -- cgit 1.4.1-3-g733a5 From 3f966dcd53faabd8313d29a4e1ba2464995e624a Mon Sep 17 00:00:00 2001 From: Taylor Cramer Date: Fri, 5 Apr 2019 14:14:19 -0700 Subject: Stabilize futures_api --- src/liballoc/boxed.rs | 2 +- src/liballoc/lib.rs | 1 - src/libcore/future/future.rs | 9 ++++-- src/libcore/future/mod.rs | 5 ++- src/libcore/task/mod.rs | 6 ++-- src/libcore/task/poll.rs | 20 +++++++++--- src/libcore/task/wake.rs | 36 ++++++++++++++++------ src/libstd/future.rs | 1 + src/libstd/lib.rs | 10 ++---- src/libstd/panic.rs | 2 +- src/test/compile-fail/must_use-in-stdlib-traits.rs | 2 +- src/test/run-pass/async-await.rs | 2 +- src/test/run-pass/auxiliary/arc_wake.rs | 2 -- src/test/run-pass/futures-api.rs | 2 -- src/test/run-pass/issue-54716.rs | 2 +- src/test/run-pass/issue-55809.rs | 2 +- src/test/rustdoc/async-fn.rs | 2 +- src/test/ui/async-fn-multiple-lifetimes.rs | 2 +- .../consts/min_const_fn/allow_const_fn_ptr.stderr | 3 +- .../ui/editions/edition-deny-async-fns-2015.rs | 2 +- .../feature-gate-async-await-2015-edition.rs | 2 -- .../feature-gate-async-await-2015-edition.stderr | 8 ++--- .../ui/feature-gates/feature-gate-async-await.rs | 2 -- .../feature-gates/feature-gate-async-await.stderr | 12 ++++---- .../impl-trait/recursive-async-impl-trait-type.rs | 2 +- .../ui/impl-trait/recursive-impl-trait-type.rs | 2 +- src/test/ui/issues/issue-54974.rs | 2 +- src/test/ui/issues/issue-55324.rs | 2 +- src/test/ui/issues/issue-58885.rs | 2 +- src/test/ui/issues/issue-59001.rs | 2 +- src/test/ui/no-args-non-move-async-closure.rs | 2 +- src/test/ui/try-poll.rs | 1 - 32 files changed, 86 insertions(+), 66 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 8a3950718d7..207359ed696 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -911,7 +911,7 @@ impl Generator for Pin> { } } -#[unstable(feature = "futures_api", issue = "50547")] +#[stable(feature = "futures_api", since = "1.36.0")] impl Future for Box { type Output = F::Output; diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 63b3fbbdaef..eb673488170 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -85,7 +85,6 @@ #![feature(fmt_internals)] #![feature(fn_traits)] #![feature(fundamental)] -#![feature(futures_api)] #![feature(lang_items)] #![feature(libc)] #![feature(needs_allocator)] diff --git a/src/libcore/future/future.rs b/src/libcore/future/future.rs index e1ab67873a0..504330a023b 100644 --- a/src/libcore/future/future.rs +++ b/src/libcore/future/future.rs @@ -1,6 +1,4 @@ -#![unstable(feature = "futures_api", - reason = "futures in libcore are unstable", - issue = "50547")] +#![stable(feature = "futures_api", since = "1.36.0")] use crate::marker::Unpin; use crate::ops; @@ -26,8 +24,10 @@ use crate::task::{Context, Poll}; /// `await!` the value. #[doc(spotlight)] #[must_use = "futures do nothing unless polled"] +#[stable(feature = "futures_api", since = "1.36.0")] pub trait Future { /// The type of value produced on completion. + #[stable(feature = "futures_api", since = "1.36.0")] type Output; /// Attempt to resolve the future to a final value, registering @@ -92,9 +92,11 @@ pub trait Future { /// [`Context`]: ../task/struct.Context.html /// [`Waker`]: ../task/struct.Waker.html /// [`Waker::wake`]: ../task/struct.Waker.html#method.wake + #[stable(feature = "futures_api", since = "1.36.0")] fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll; } +#[stable(feature = "futures_api", since = "1.36.0")] impl Future for &mut F { type Output = F::Output; @@ -103,6 +105,7 @@ impl Future for &mut F { } } +#[stable(feature = "futures_api", since = "1.36.0")] impl

Future for Pin

where P: Unpin + ops::DerefMut, diff --git a/src/libcore/future/mod.rs b/src/libcore/future/mod.rs index 6693ecbac41..89ea4713cfd 100644 --- a/src/libcore/future/mod.rs +++ b/src/libcore/future/mod.rs @@ -1,8 +1,7 @@ -#![unstable(feature = "futures_api", - reason = "futures in libcore are unstable", - issue = "50547")] +#![stable(feature = "futures_api", since = "1.36.0")] //! Asynchronous values. mod future; +#[stable(feature = "futures_api", since = "1.36.0")] pub use self::future::Future; diff --git a/src/libcore/task/mod.rs b/src/libcore/task/mod.rs index 29bae69ea83..ef090928392 100644 --- a/src/libcore/task/mod.rs +++ b/src/libcore/task/mod.rs @@ -1,11 +1,11 @@ -#![unstable(feature = "futures_api", - reason = "futures in libcore are unstable", - issue = "50547")] +#![stable(feature = "futures_api", since = "1.36.0")] //! Types and Traits for working with asynchronous tasks. mod poll; +#[stable(feature = "futures_api", since = "1.36.0")] pub use self::poll::Poll; mod wake; +#[stable(feature = "futures_api", since = "1.36.0")] pub use self::wake::{Context, Waker, RawWaker, RawWakerVTable}; diff --git a/src/libcore/task/poll.rs b/src/libcore/task/poll.rs index ecf03afb88e..3db70d5e764 100644 --- a/src/libcore/task/poll.rs +++ b/src/libcore/task/poll.rs @@ -1,6 +1,4 @@ -#![unstable(feature = "futures_api", - reason = "futures in libcore are unstable", - issue = "50547")] +#![stable(feature = "futures_api", since = "1.36.0")] use crate::ops::Try; use crate::result::Result; @@ -9,20 +7,27 @@ use crate::result::Result; /// scheduled to receive a wakeup instead. #[must_use = "this `Poll` may be a `Pending` variant, which should be handled"] #[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)] +#[stable(feature = "futures_api", since = "1.36.0")] pub enum Poll { /// Represents that a value is immediately ready. - Ready(T), + #[stable(feature = "futures_api", since = "1.36.0")] + Ready( + #[stable(feature = "futures_api", since = "1.36.0")] + T + ), /// Represents that a value is not ready yet. /// /// When a function returns `Pending`, the function *must* also /// ensure that the current task is scheduled to be awoken when /// progress can be made. + #[stable(feature = "futures_api", since = "1.36.0")] Pending, } impl Poll { /// Changes the ready value of this `Poll` with the closure provided. + #[stable(feature = "futures_api", since = "1.36.0")] pub fn map(self, f: F) -> Poll where F: FnOnce(T) -> U { @@ -34,6 +39,7 @@ impl Poll { /// Returns `true` if this is `Poll::Ready` #[inline] + #[stable(feature = "futures_api", since = "1.36.0")] pub fn is_ready(&self) -> bool { match *self { Poll::Ready(_) => true, @@ -43,6 +49,7 @@ impl Poll { /// Returns `true` if this is `Poll::Pending` #[inline] + #[stable(feature = "futures_api", since = "1.36.0")] pub fn is_pending(&self) -> bool { !self.is_ready() } @@ -50,6 +57,7 @@ impl Poll { impl Poll> { /// Changes the success value of this `Poll` with the closure provided. + #[stable(feature = "futures_api", since = "1.36.0")] pub fn map_ok(self, f: F) -> Poll> where F: FnOnce(T) -> U { @@ -61,6 +69,7 @@ impl Poll> { } /// Changes the error value of this `Poll` with the closure provided. + #[stable(feature = "futures_api", since = "1.36.0")] pub fn map_err(self, f: F) -> Poll> where F: FnOnce(E) -> U { @@ -72,12 +81,14 @@ impl Poll> { } } +#[stable(feature = "futures_api", since = "1.36.0")] impl From for Poll { fn from(t: T) -> Poll { Poll::Ready(t) } } +#[stable(feature = "futures_api", since = "1.36.0")] impl Try for Poll> { type Ok = Poll; type Error = E; @@ -102,6 +113,7 @@ impl Try for Poll> { } } +#[stable(feature = "futures_api", since = "1.36.0")] impl Try for Poll>> { type Ok = Poll>; type Error = E; diff --git a/src/libcore/task/wake.rs b/src/libcore/task/wake.rs index 94e31054a58..b4e91249832 100644 --- a/src/libcore/task/wake.rs +++ b/src/libcore/task/wake.rs @@ -1,6 +1,4 @@ -#![unstable(feature = "futures_api", - reason = "futures in libcore are unstable", - issue = "50547")] +#![stable(feature = "futures_api", since = "1.36.0")] use crate::fmt; use crate::marker::{PhantomData, Unpin}; @@ -13,6 +11,7 @@ use crate::marker::{PhantomData, Unpin}; /// It consists of a data pointer and a [virtual function pointer table (vtable)][vtable] that /// customizes the behavior of the `RawWaker`. #[derive(PartialEq, Debug)] +#[stable(feature = "futures_api", since = "1.36.0")] pub struct RawWaker { /// A data pointer, which can be used to store arbitrary data as required /// by the executor. This could be e.g. a type-erased pointer to an `Arc` @@ -37,9 +36,7 @@ impl RawWaker { /// from a `RawWaker`. For each operation on the `Waker`, the associated /// function in the `vtable` of the underlying `RawWaker` will be called. #[rustc_promotable] - #[unstable(feature = "futures_api", - reason = "futures in libcore are unstable", - issue = "50547")] + #[stable(feature = "futures_api", since = "1.36.0")] pub const fn new(data: *const (), vtable: &'static RawWakerVTable) -> RawWaker { RawWaker { data, @@ -58,6 +55,7 @@ impl RawWaker { /// pointer of a properly constructed [`RawWaker`] object from inside the /// [`RawWaker`] implementation. Calling one of the contained functions using /// any other `data` pointer will cause undefined behavior. +#[stable(feature = "futures_api", since = "1.36.0")] #[derive(PartialEq, Copy, Clone, Debug)] pub struct RawWakerVTable { /// This function will be called when the [`RawWaker`] gets cloned, e.g. when @@ -131,9 +129,14 @@ impl RawWakerVTable { /// resources that are associated with this instance of a [`RawWaker`] and /// associated task. #[rustc_promotable] - #[unstable(feature = "futures_api", - reason = "futures in libcore are unstable", - issue = "50547")] + #[cfg_attr(stage0, unstable(feature = "futures_api_const_fn_ptr", issue = "50547"))] + #[cfg_attr(not(stage0), stable(feature = "futures_api", since = "1.36.0"))] + // `rustc_allow_const_fn_ptr` is a hack that should not be used anywhere else + // without first consulting with T-Lang. + // + // FIXME: remove whenever we have a stable way to accept fn pointers from const fn + // (see https://github.com/rust-rfcs/const-eval/issues/19#issuecomment-472799062) + #[cfg_attr(not(stage0), rustc_allow_const_fn_ptr)] pub const fn new( clone: unsafe fn(*const ()) -> RawWaker, wake: unsafe fn(*const ()), @@ -153,6 +156,7 @@ impl RawWakerVTable { /// /// Currently, `Context` only serves to provide access to a `&Waker` /// which can be used to wake the current task. +#[stable(feature = "futures_api", since = "1.36.0")] pub struct Context<'a> { waker: &'a Waker, // Ensure we future-proof against variance changes by forcing @@ -164,6 +168,7 @@ pub struct Context<'a> { impl<'a> Context<'a> { /// Create a new `Context` from a `&Waker`. + #[stable(feature = "futures_api", since = "1.36.0")] #[inline] pub fn from_waker(waker: &'a Waker) -> Self { Context { @@ -173,12 +178,14 @@ impl<'a> Context<'a> { } /// Returns a reference to the `Waker` for the current task. + #[stable(feature = "futures_api", since = "1.36.0")] #[inline] pub fn waker(&self) -> &'a Waker { &self.waker } } +#[stable(feature = "futures_api", since = "1.36.0")] impl fmt::Debug for Context<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Context") @@ -195,17 +202,22 @@ impl fmt::Debug for Context<'_> { /// /// Implements [`Clone`], [`Send`], and [`Sync`]. #[repr(transparent)] +#[stable(feature = "futures_api", since = "1.36.0")] pub struct Waker { waker: RawWaker, } +#[stable(feature = "futures_api", since = "1.36.0")] impl Unpin for Waker {} +#[stable(feature = "futures_api", since = "1.36.0")] unsafe impl Send for Waker {} +#[stable(feature = "futures_api", since = "1.36.0")] unsafe impl Sync for Waker {} impl Waker { /// Wake up the task associated with this `Waker`. #[inline] + #[stable(feature = "futures_api", since = "1.36.0")] pub fn wake(self) { // The actual wakeup call is delegated through a virtual function call // to the implementation which is defined by the executor. @@ -227,6 +239,7 @@ impl Waker { /// where an owned `Waker` is available. This method should be preferred to /// calling `waker.clone().wake()`. #[inline] + #[stable(feature = "futures_api", since = "1.36.0")] pub fn wake_by_ref(&self) { // The actual wakeup call is delegated through a virtual function call // to the implementation which is defined by the executor. @@ -243,6 +256,7 @@ impl Waker { /// /// This function is primarily used for optimization purposes. #[inline] + #[stable(feature = "futures_api", since = "1.36.0")] pub fn will_wake(&self, other: &Waker) -> bool { self.waker == other.waker } @@ -253,6 +267,7 @@ impl Waker { /// in [`RawWaker`]'s and [`RawWakerVTable`]'s documentation is not upheld. /// Therefore this method is unsafe. #[inline] + #[stable(feature = "futures_api", since = "1.36.0")] pub unsafe fn from_raw(waker: RawWaker) -> Waker { Waker { waker, @@ -260,6 +275,7 @@ impl Waker { } } +#[stable(feature = "futures_api", since = "1.36.0")] impl Clone for Waker { #[inline] fn clone(&self) -> Self { @@ -272,6 +288,7 @@ impl Clone for Waker { } } +#[stable(feature = "futures_api", since = "1.36.0")] impl Drop for Waker { #[inline] fn drop(&mut self) { @@ -282,6 +299,7 @@ impl Drop for Waker { } } +#[stable(feature = "futures_api", since = "1.36.0")] impl fmt::Debug for Waker { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let vtable_ptr = self.waker.vtable as *const RawWakerVTable; diff --git a/src/libstd/future.rs b/src/libstd/future.rs index 898387cb9f5..c18a314116b 100644 --- a/src/libstd/future.rs +++ b/src/libstd/future.rs @@ -9,6 +9,7 @@ use core::task::{Context, Poll}; use core::ops::{Drop, Generator, GeneratorState}; #[doc(inline)] +#[stable(feature = "futures_api", since = "1.36.0")] pub use core::future::*; /// Wrap a generator in a future. diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 62bc1991cc9..bdec0c347f5 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -263,7 +263,6 @@ #![feature(fixed_size_array)] #![feature(fn_traits)] #![feature(fnbox)] -#![feature(futures_api)] #![feature(generator_trait)] #![feature(hash_raw_entry)] #![feature(hashmap_internals)] @@ -458,18 +457,15 @@ pub mod process; pub mod sync; pub mod time; -#[unstable(feature = "futures_api", - reason = "futures in libcore are unstable", - issue = "50547")] +#[stable(feature = "futures_api", since = "1.36.0")] pub mod task { //! Types and Traits for working with asynchronous tasks. #[doc(inline)] + #[stable(feature = "futures_api", since = "1.36.0")] pub use core::task::*; } -#[unstable(feature = "futures_api", - reason = "futures in libcore are unstable", - issue = "50547")] +#[stable(feature = "futures_api", since = "1.36.0")] pub mod future; // Platform-abstraction modules diff --git a/src/libstd/panic.rs b/src/libstd/panic.rs index 5a8101e2301..7a3b5d30500 100644 --- a/src/libstd/panic.rs +++ b/src/libstd/panic.rs @@ -319,7 +319,7 @@ impl fmt::Debug for AssertUnwindSafe { } } -#[unstable(feature = "futures_api", issue = "50547")] +#[stable(feature = "futures_api", since = "1.36.0")] impl Future for AssertUnwindSafe { type Output = F::Output; diff --git a/src/test/compile-fail/must_use-in-stdlib-traits.rs b/src/test/compile-fail/must_use-in-stdlib-traits.rs index 503b39e181a..39472ae11fb 100644 --- a/src/test/compile-fail/must_use-in-stdlib-traits.rs +++ b/src/test/compile-fail/must_use-in-stdlib-traits.rs @@ -1,5 +1,5 @@ #![deny(unused_must_use)] -#![feature(arbitrary_self_types, futures_api)] +#![feature(arbitrary_self_types)] use std::iter::Iterator; use std::future::Future; diff --git a/src/test/run-pass/async-await.rs b/src/test/run-pass/async-await.rs index 518452aefc1..e1b4328debd 100644 --- a/src/test/run-pass/async-await.rs +++ b/src/test/run-pass/async-await.rs @@ -1,7 +1,7 @@ // edition:2018 // aux-build:arc_wake.rs -#![feature(async_await, await_macro, futures_api)] +#![feature(async_await, await_macro)] extern crate arc_wake; diff --git a/src/test/run-pass/auxiliary/arc_wake.rs b/src/test/run-pass/auxiliary/arc_wake.rs index 93e074e7ee5..c21886f26f4 100644 --- a/src/test/run-pass/auxiliary/arc_wake.rs +++ b/src/test/run-pass/auxiliary/arc_wake.rs @@ -1,7 +1,5 @@ // edition:2018 -#![feature(futures_api)] - use std::sync::Arc; use std::task::{ Waker, RawWaker, RawWakerVTable, diff --git a/src/test/run-pass/futures-api.rs b/src/test/run-pass/futures-api.rs index 6094f15569b..ee77053fd5b 100644 --- a/src/test/run-pass/futures-api.rs +++ b/src/test/run-pass/futures-api.rs @@ -1,7 +1,5 @@ // aux-build:arc_wake.rs -#![feature(futures_api)] - extern crate arc_wake; use std::future::Future; diff --git a/src/test/run-pass/issue-54716.rs b/src/test/run-pass/issue-54716.rs index ea4f5e076b0..961c412f5ec 100644 --- a/src/test/run-pass/issue-54716.rs +++ b/src/test/run-pass/issue-54716.rs @@ -3,7 +3,7 @@ // run-pass #![allow(unused_variables)] -#![feature(async_await, await_macro, futures_api)] +#![feature(async_await, await_macro)] extern crate arc_wake; diff --git a/src/test/run-pass/issue-55809.rs b/src/test/run-pass/issue-55809.rs index 86b0977bebe..12be6582a21 100644 --- a/src/test/run-pass/issue-55809.rs +++ b/src/test/run-pass/issue-55809.rs @@ -1,7 +1,7 @@ // edition:2018 // run-pass -#![feature(async_await, await_macro, futures_api)] +#![feature(async_await, await_macro)] trait Foo { } diff --git a/src/test/rustdoc/async-fn.rs b/src/test/rustdoc/async-fn.rs index ba4997a7f9b..7384f7027d1 100644 --- a/src/test/rustdoc/async-fn.rs +++ b/src/test/rustdoc/async-fn.rs @@ -1,6 +1,6 @@ // edition:2018 -#![feature(async_await, futures_api)] +#![feature(async_await)] // @has async_fn/fn.foo.html '//pre[@class="rust fn"]' 'pub async fn foo() -> Option' pub async fn foo() -> Option { diff --git a/src/test/ui/async-fn-multiple-lifetimes.rs b/src/test/ui/async-fn-multiple-lifetimes.rs index fccc4fdb917..e3ac817b15c 100644 --- a/src/test/ui/async-fn-multiple-lifetimes.rs +++ b/src/test/ui/async-fn-multiple-lifetimes.rs @@ -1,6 +1,6 @@ // edition:2018 -#![feature(arbitrary_self_types, async_await, await_macro, futures_api, pin)] +#![feature(arbitrary_self_types, async_await, await_macro, pin)] use std::ops::Add; diff --git a/src/test/ui/consts/min_const_fn/allow_const_fn_ptr.stderr b/src/test/ui/consts/min_const_fn/allow_const_fn_ptr.stderr index ed9cba9fa2f..e6e1ced6592 100644 --- a/src/test/ui/consts/min_const_fn/allow_const_fn_ptr.stderr +++ b/src/test/ui/consts/min_const_fn/allow_const_fn_ptr.stderr @@ -1,9 +1,10 @@ -error[E0723]: function pointers in const fn are unstable (see issue #57563) +error[E0723]: function pointers in const fn are unstable --> $DIR/allow_const_fn_ptr.rs:4:16 | LL | const fn error(_: fn()) {} | ^ | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 = help: add #![feature(const_fn)] to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/editions/edition-deny-async-fns-2015.rs b/src/test/ui/editions/edition-deny-async-fns-2015.rs index 2105aa5835d..e1111f9e0e4 100644 --- a/src/test/ui/editions/edition-deny-async-fns-2015.rs +++ b/src/test/ui/editions/edition-deny-async-fns-2015.rs @@ -1,6 +1,6 @@ // edition:2015 -#![feature(futures_api, async_await)] +#![feature(async_await)] async fn foo() {} //~ ERROR `async fn` is not permitted in the 2015 edition diff --git a/src/test/ui/feature-gates/feature-gate-async-await-2015-edition.rs b/src/test/ui/feature-gates/feature-gate-async-await-2015-edition.rs index b6ab8ae0a9b..801aeb82aa2 100644 --- a/src/test/ui/feature-gates/feature-gate-async-await-2015-edition.rs +++ b/src/test/ui/feature-gates/feature-gate-async-await-2015-edition.rs @@ -1,7 +1,5 @@ // edition:2015 -#![feature(futures_api)] - async fn foo() {} //~ ERROR `async fn` is not permitted in the 2015 edition //~^ ERROR async fn is unstable diff --git a/src/test/ui/feature-gates/feature-gate-async-await-2015-edition.stderr b/src/test/ui/feature-gates/feature-gate-async-await-2015-edition.stderr index cec211fef13..b419f1232df 100644 --- a/src/test/ui/feature-gates/feature-gate-async-await-2015-edition.stderr +++ b/src/test/ui/feature-gates/feature-gate-async-await-2015-edition.stderr @@ -1,23 +1,23 @@ error[E0670]: `async fn` is not permitted in the 2015 edition - --> $DIR/feature-gate-async-await-2015-edition.rs:5:1 + --> $DIR/feature-gate-async-await-2015-edition.rs:3:1 | LL | async fn foo() {} | ^^^^^ error[E0422]: cannot find struct, variant or union type `async` in this scope - --> $DIR/feature-gate-async-await-2015-edition.rs:9:13 + --> $DIR/feature-gate-async-await-2015-edition.rs:7:13 | LL | let _ = async {}; | ^^^^^ not found in this scope error[E0425]: cannot find value `async` in this scope - --> $DIR/feature-gate-async-await-2015-edition.rs:10:13 + --> $DIR/feature-gate-async-await-2015-edition.rs:8:13 | LL | let _ = async || { true }; | ^^^^^ not found in this scope error[E0658]: async fn is unstable - --> $DIR/feature-gate-async-await-2015-edition.rs:5:1 + --> $DIR/feature-gate-async-await-2015-edition.rs:3:1 | LL | async fn foo() {} | ^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/feature-gates/feature-gate-async-await.rs b/src/test/ui/feature-gates/feature-gate-async-await.rs index 1fdaec75e9d..9cfefef4129 100644 --- a/src/test/ui/feature-gates/feature-gate-async-await.rs +++ b/src/test/ui/feature-gates/feature-gate-async-await.rs @@ -1,7 +1,5 @@ // edition:2018 -#![feature(futures_api)] - struct S; impl S { diff --git a/src/test/ui/feature-gates/feature-gate-async-await.stderr b/src/test/ui/feature-gates/feature-gate-async-await.stderr index 1fa21f52045..43e41b45458 100644 --- a/src/test/ui/feature-gates/feature-gate-async-await.stderr +++ b/src/test/ui/feature-gates/feature-gate-async-await.stderr @@ -1,11 +1,11 @@ error[E0706]: trait fns cannot be declared `async` - --> $DIR/feature-gate-async-await.rs:12:5 + --> $DIR/feature-gate-async-await.rs:10:5 | LL | async fn foo(); | ^^^^^^^^^^^^^^^ error[E0658]: async fn is unstable - --> $DIR/feature-gate-async-await.rs:8:5 + --> $DIR/feature-gate-async-await.rs:6:5 | LL | async fn foo() {} | ^^^^^^^^^^^^^^^^^ @@ -14,7 +14,7 @@ LL | async fn foo() {} = help: add #![feature(async_await)] to the crate attributes to enable error[E0658]: async fn is unstable - --> $DIR/feature-gate-async-await.rs:12:5 + --> $DIR/feature-gate-async-await.rs:10:5 | LL | async fn foo(); | ^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | async fn foo(); = help: add #![feature(async_await)] to the crate attributes to enable error[E0658]: async fn is unstable - --> $DIR/feature-gate-async-await.rs:16:1 + --> $DIR/feature-gate-async-await.rs:14:1 | LL | async fn foo() {} | ^^^^^^^^^^^^^^^^^ @@ -32,7 +32,7 @@ LL | async fn foo() {} = help: add #![feature(async_await)] to the crate attributes to enable error[E0658]: async blocks are unstable - --> $DIR/feature-gate-async-await.rs:19:13 + --> $DIR/feature-gate-async-await.rs:17:13 | LL | let _ = async {}; | ^^^^^^^^ @@ -41,7 +41,7 @@ LL | let _ = async {}; = help: add #![feature(async_await)] to the crate attributes to enable error[E0658]: async closures are unstable - --> $DIR/feature-gate-async-await.rs:20:13 + --> $DIR/feature-gate-async-await.rs:18:13 | LL | let _ = async || {}; | ^^^^^^^^^^^ diff --git a/src/test/ui/impl-trait/recursive-async-impl-trait-type.rs b/src/test/ui/impl-trait/recursive-async-impl-trait-type.rs index 40642523be2..a4e08011934 100644 --- a/src/test/ui/impl-trait/recursive-async-impl-trait-type.rs +++ b/src/test/ui/impl-trait/recursive-async-impl-trait-type.rs @@ -2,7 +2,7 @@ // Test that impl trait does not allow creating recursive types that are // otherwise forbidden when using `async` and `await`. -#![feature(await_macro, async_await, futures_api, generators)] +#![feature(await_macro, async_await, generators)] async fn recursive_async_function() -> () { //~ ERROR await!(recursive_async_function()); diff --git a/src/test/ui/impl-trait/recursive-impl-trait-type.rs b/src/test/ui/impl-trait/recursive-impl-trait-type.rs index 869876dc6a8..2428b560b70 100644 --- a/src/test/ui/impl-trait/recursive-impl-trait-type.rs +++ b/src/test/ui/impl-trait/recursive-impl-trait-type.rs @@ -1,7 +1,7 @@ // Test that impl trait does not allow creating recursive types that are // otherwise forbidden. -#![feature(futures_api, generators)] +#![feature(generators)] fn option(i: i32) -> impl Sized { //~ ERROR if i < 0 { diff --git a/src/test/ui/issues/issue-54974.rs b/src/test/ui/issues/issue-54974.rs index b2624ec92a1..d6f18875c9e 100644 --- a/src/test/ui/issues/issue-54974.rs +++ b/src/test/ui/issues/issue-54974.rs @@ -1,7 +1,7 @@ // compile-pass // edition:2018 -#![feature(async_await, await_macro, futures_api)] +#![feature(async_await, await_macro)] use std::sync::Arc; diff --git a/src/test/ui/issues/issue-55324.rs b/src/test/ui/issues/issue-55324.rs index 6160fbabd96..4572e543f22 100644 --- a/src/test/ui/issues/issue-55324.rs +++ b/src/test/ui/issues/issue-55324.rs @@ -1,7 +1,7 @@ // compile-pass // edition:2018 -#![feature(async_await, await_macro, futures_api)] +#![feature(async_await, await_macro)] use std::future::Future; diff --git a/src/test/ui/issues/issue-58885.rs b/src/test/ui/issues/issue-58885.rs index 559899194fb..99d87b2273c 100644 --- a/src/test/ui/issues/issue-58885.rs +++ b/src/test/ui/issues/issue-58885.rs @@ -1,7 +1,7 @@ // compile-pass // edition:2018 -#![feature(async_await, await_macro, futures_api)] +#![feature(async_await, await_macro)] struct Xyz { a: u64, diff --git a/src/test/ui/issues/issue-59001.rs b/src/test/ui/issues/issue-59001.rs index a310653fbce..c758244002f 100644 --- a/src/test/ui/issues/issue-59001.rs +++ b/src/test/ui/issues/issue-59001.rs @@ -1,7 +1,7 @@ // compile-pass // edition:2018 -#![feature(async_await, await_macro, futures_api)] +#![feature(async_await, await_macro)] use std::future::Future; diff --git a/src/test/ui/no-args-non-move-async-closure.rs b/src/test/ui/no-args-non-move-async-closure.rs index 4f5b2ea3783..345f19b0623 100644 --- a/src/test/ui/no-args-non-move-async-closure.rs +++ b/src/test/ui/no-args-non-move-async-closure.rs @@ -1,6 +1,6 @@ // edition:2018 -#![feature(arbitrary_self_types, async_await, await_macro, futures_api, pin)] +#![feature(async_await, await_macro)] fn main() { let _ = async |x: u8| {}; diff --git a/src/test/ui/try-poll.rs b/src/test/ui/try-poll.rs index 3d7115c5223..f63950ad5e9 100644 --- a/src/test/ui/try-poll.rs +++ b/src/test/ui/try-poll.rs @@ -1,7 +1,6 @@ // compile-pass #![allow(dead_code, unused)] -#![feature(futures_api)] use std::task::Poll; -- cgit 1.4.1-3-g733a5 From aa388f1d11da024898d823ce24654766a4cc3459 Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 22 Apr 2019 15:29:04 +0100 Subject: ignore-tidy-filelength on all files with greater than 3000 lines --- src/liballoc/collections/vec_deque.rs | 2 ++ src/libcore/num/mod.rs | 2 ++ src/libcore/ptr.rs | 2 ++ src/libcore/slice/mod.rs | 2 ++ src/libcore/str/mod.rs | 2 ++ src/librustc/hir/lowering.rs | 2 ++ src/librustc/mir/mod.rs | 2 ++ src/librustc/session/config.rs | 2 ++ src/librustc/traits/select.rs | 2 ++ src/librustc/ty/context.rs | 2 ++ src/librustc/ty/mod.rs | 2 ++ src/librustc_apfloat/tests/ieee.rs | 2 ++ src/librustc_resolve/lib.rs | 2 ++ src/librustc_typeck/check/mod.rs | 2 ++ src/librustc_typeck/error_codes.rs | 2 ++ src/librustdoc/clean/mod.rs | 2 ++ src/librustdoc/html/render.rs | 2 ++ src/libstd/collections/hash/map.rs | 2 ++ src/libstd/fs.rs | 2 ++ src/libstd/path.rs | 2 ++ src/libstd/sync/mpsc/mod.rs | 2 ++ src/libsyntax/parse/parser.rs | 2 ++ src/libsyntax/print/pprust.rs | 2 ++ src/test/run-pass/issues/issue-29466.rs | 4 ++++ src/tools/compiletest/src/runtest.rs | 2 ++ 25 files changed, 52 insertions(+) (limited to 'src/liballoc') diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index d806bd0b1d7..05225e5a25b 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -1,3 +1,5 @@ +// ignore-tidy-filelength + //! A double-ended queue implemented with a growable ring buffer. //! //! This queue has `O(1)` amortized inserts and removals from both ends of the diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index f1325f383ee..5c48c732b78 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -1,3 +1,5 @@ +// ignore-tidy-filelength + //! Numeric traits and functions for the built-in numeric types. #![stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index f05700a1db2..5d77b4dfbf7 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -1,3 +1,5 @@ +// ignore-tidy-filelength + //! Manually manage memory through raw pointers. //! //! *[See also the pointer primitive types](../../std/primitive.pointer.html).* diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index bf3dda48dc7..8731f486753 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -1,3 +1,5 @@ +// ignore-tidy-filelength + //! Slice management and manipulation. //! //! For more details see [`std::slice`]. diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 379c263c04c..7a5511ee1dc 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -1,3 +1,5 @@ +// ignore-tidy-filelength + //! String manipulation. //! //! For more details, see the `std::str` module. diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 380dee5fcdc..d4dd983e217 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1,3 +1,5 @@ +// ignore-tidy-filelength + //! Lowers the AST to the HIR. //! //! Since the AST and HIR are fairly similar, this is mostly a simple procedure, diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index bf2a1eaafd6..9da961b4e9e 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -1,3 +1,5 @@ +// ignore-tidy-filelength + //! MIR datatypes and passes. See the [rustc guide] for more info. //! //! [rustc guide]: https://rust-lang.github.io/rustc-guide/mir/index.html diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index cb307800fcd..60d5340613c 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1,3 +1,5 @@ +// ignore-tidy-filelength + //! Contains infrastructure for configuring the compiler, including parsing //! command line options. diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index e7cc9618080..c079a526842 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -1,3 +1,5 @@ +// ignore-tidy-filelength + //! Candidate selection. See the [rustc guide] for more information on how this works. //! //! [rustc guide]: https://rust-lang.github.io/rustc-guide/traits/resolution.html#selection diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index ed500d1ac33..2d857f402ed 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1,3 +1,5 @@ +// ignore-tidy-filelength + //! Type context book-keeping. use crate::arena::Arena; diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 67be228d232..f2c77b1bfab 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1,3 +1,5 @@ +// ignore-tidy-filelength + #![allow(usage_of_ty_tykind)] pub use self::Variance::*; diff --git a/src/librustc_apfloat/tests/ieee.rs b/src/librustc_apfloat/tests/ieee.rs index 108b2114439..7158efae8f1 100644 --- a/src/librustc_apfloat/tests/ieee.rs +++ b/src/librustc_apfloat/tests/ieee.rs @@ -1,3 +1,5 @@ +// ignore-tidy-filelength + use rustc_apfloat::{Category, ExpInt, IEK_INF, IEK_NAN, IEK_ZERO}; use rustc_apfloat::{Float, FloatConvert, ParseError, Round, Status}; use rustc_apfloat::ieee::{Half, Single, Double, Quad, X87DoubleExtended}; diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 7754bb26f90..f6b62146c60 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1,3 +1,5 @@ +// ignore-tidy-filelength + #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![feature(crate_visibility_modifier)] diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index bd715df6e9d..9f0c377e19c 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1,3 +1,5 @@ +// ignore-tidy-filelength + /*! # typeck: check phase diff --git a/src/librustc_typeck/error_codes.rs b/src/librustc_typeck/error_codes.rs index 22f24df450f..dc23a92adbb 100644 --- a/src/librustc_typeck/error_codes.rs +++ b/src/librustc_typeck/error_codes.rs @@ -1,4 +1,6 @@ // ignore-tidy-linelength +// ignore-tidy-filelength + #![allow(non_snake_case)] register_long_diagnostics! { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 4ff16e4a267..81e4905890d 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1,3 +1,5 @@ +// ignore-tidy-filelength + //! This module contains the "cleaned" pieces of the AST, and the functions //! that clean them. diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 487c57172d9..2c4e1cde880 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -1,3 +1,5 @@ +// ignore-tidy-filelength + //! Rustdoc's HTML rendering module. //! //! This modules contains the bulk of the logic necessary for rendering a diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index d1ba9c267b7..f9fb392f9f5 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -1,3 +1,5 @@ +// ignore-tidy-filelength + use self::Entry::*; use hashbrown::hash_map as base; diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index 1772879d013..04672da2b66 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -1,3 +1,5 @@ +// ignore-tidy-filelength + //! Filesystem manipulation operations. //! //! This module contains basic methods to manipulate the contents of the local diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 1bbda9b5bcb..126bc3754da 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -1,3 +1,5 @@ +// ignore-tidy-filelength + //! Cross-platform path manipulation. //! //! This module provides two types, [`PathBuf`] and [`Path`][`Path`] (akin to [`String`] diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs index 685c7909ff2..04353fde1b4 100644 --- a/src/libstd/sync/mpsc/mod.rs +++ b/src/libstd/sync/mpsc/mod.rs @@ -1,3 +1,5 @@ +// ignore-tidy-filelength + //! Multi-producer, single-consumer FIFO queue communication primitives. //! //! This module provides message-based communication over channels, concretely diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 75d687be280..8efe84cdf01 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1,3 +1,5 @@ +// ignore-tidy-filelength + use crate::ast::{AngleBracketedArgs, AsyncArgument, ParenthesizedArgs, AttrStyle, BareFnTy}; use crate::ast::{GenericBound, TraitBoundModifier}; use crate::ast::Unsafety; diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 7ce3951f13e..6c0fdfaa776 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1,3 +1,5 @@ +// ignore-tidy-filelength + use crate::ast::{self, BlockCheckMode, PatKind, RangeEnd, RangeSyntax}; use crate::ast::{SelfKind, GenericBound, TraitBoundModifier}; use crate::ast::{Attribute, MacDelimiter, GenericArg}; diff --git a/src/test/run-pass/issues/issue-29466.rs b/src/test/run-pass/issues/issue-29466.rs index e28185bc3a2..f8785a63217 100644 --- a/src/test/run-pass/issues/issue-29466.rs +++ b/src/test/run-pass/issues/issue-29466.rs @@ -1,5 +1,9 @@ +// ignore-tidy-filelength +// // run-pass + #![allow(unused_variables)] + macro_rules! m( ($e1:expr => $e2:expr) => ({ $e1 }) ); diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index d7a5395757f..9db16b69e5f 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1,3 +1,5 @@ +// ignore-tidy-filelength + use crate::common::CompareMode; use crate::common::{expected_output_path, UI_EXTENSIONS, UI_FIXED, UI_STDERR, UI_STDOUT}; use crate::common::{output_base_dir, output_base_name, output_testname_unique}; -- cgit 1.4.1-3-g733a5 From be12ab070d733303355d433d68efb870e3da753b Mon Sep 17 00:00:00 2001 From: Matthias Geier Date: Fri, 26 Apr 2019 18:43:24 +0200 Subject: Use "capacity" as parameter name in with_capacity() methods Closes #60271. --- src/liballoc/collections/vec_deque.rs | 8 ++++---- src/librustc_data_structures/bit_set.rs | 4 ++-- src/libstd/io/buffered.rs | 14 +++++++------- src/libstd/sys_common/wtf8.rs | 6 +++--- 4 files changed, 16 insertions(+), 16 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index 05225e5a25b..d65c24f7350 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -369,7 +369,7 @@ impl VecDeque { VecDeque::with_capacity(INITIAL_CAPACITY) } - /// Creates an empty `VecDeque` with space for at least `n` elements. + /// Creates an empty `VecDeque` with space for at least `capacity` elements. /// /// # Examples /// @@ -379,10 +379,10 @@ impl VecDeque { /// let vector: VecDeque = VecDeque::with_capacity(10); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn with_capacity(n: usize) -> VecDeque { + pub fn with_capacity(capacity: usize) -> VecDeque { // +1 since the ringbuffer always leaves one space empty - let cap = cmp::max(n + 1, MINIMUM_CAPACITY + 1).next_power_of_two(); - assert!(cap > n, "capacity overflow"); + let cap = cmp::max(capacity + 1, MINIMUM_CAPACITY + 1).next_power_of_two(); + assert!(cap > capacity, "capacity overflow"); VecDeque { tail: 0, diff --git a/src/librustc_data_structures/bit_set.rs b/src/librustc_data_structures/bit_set.rs index ff7964646d6..ec7ff3bd813 100644 --- a/src/librustc_data_structures/bit_set.rs +++ b/src/librustc_data_structures/bit_set.rs @@ -607,8 +607,8 @@ impl GrowableBitSet { GrowableBitSet { bit_set: BitSet::new_empty(0) } } - pub fn with_capacity(bits: usize) -> GrowableBitSet { - GrowableBitSet { bit_set: BitSet::new_empty(bits) } + pub fn with_capacity(capacity: usize) -> GrowableBitSet { + GrowableBitSet { bit_set: BitSet::new_empty(capacity) } } /// Returns `true` if the set has changed. diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index bf406bb9b0b..e6c8e26fa92 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -92,10 +92,10 @@ impl BufReader { /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn with_capacity(cap: usize, inner: R) -> BufReader { + pub fn with_capacity(capacity: usize, inner: R) -> BufReader { unsafe { - let mut buffer = Vec::with_capacity(cap); - buffer.set_len(cap); + let mut buffer = Vec::with_capacity(capacity); + buffer.set_len(capacity); inner.initializer().initialize(&mut buffer); BufReader { inner, @@ -477,10 +477,10 @@ impl BufWriter { /// let mut buffer = BufWriter::with_capacity(100, stream); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn with_capacity(cap: usize, inner: W) -> BufWriter { + pub fn with_capacity(capacity: usize, inner: W) -> BufWriter { BufWriter { inner: Some(inner), - buf: Vec::with_capacity(cap), + buf: Vec::with_capacity(capacity), panicked: false, } } @@ -851,9 +851,9 @@ impl LineWriter { /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn with_capacity(cap: usize, inner: W) -> LineWriter { + pub fn with_capacity(capacity: usize, inner: W) -> LineWriter { LineWriter { - inner: BufWriter::with_capacity(cap, inner), + inner: BufWriter::with_capacity(capacity, inner), need_flush: false, } } diff --git a/src/libstd/sys_common/wtf8.rs b/src/libstd/sys_common/wtf8.rs index f17020de44e..81e606fc165 100644 --- a/src/libstd/sys_common/wtf8.rs +++ b/src/libstd/sys_common/wtf8.rs @@ -146,10 +146,10 @@ impl Wtf8Buf { Wtf8Buf { bytes: Vec::new() } } - /// Creates a new, empty WTF-8 string with pre-allocated capacity for `n` bytes. + /// Creates a new, empty WTF-8 string with pre-allocated capacity for `capacity` bytes. #[inline] - pub fn with_capacity(n: usize) -> Wtf8Buf { - Wtf8Buf { bytes: Vec::with_capacity(n) } + pub fn with_capacity(capacity: usize) -> Wtf8Buf { + Wtf8Buf { bytes: Vec::with_capacity(capacity) } } /// Creates a WTF-8 string from a UTF-8 `String`. -- cgit 1.4.1-3-g733a5 From 0967d28be787b281c0364aca8fb9c25124029b30 Mon Sep 17 00:00:00 2001 From: Matthias Geier Date: Sat, 27 Apr 2019 21:28:40 +0200 Subject: Rename .cap() methods to .capacity() ... but leave the old names in there for backwards compatibility. --- src/liballoc/collections/vec_deque.rs | 34 ++++----- src/liballoc/raw_vec.rs | 125 ++++++++++++++++++---------------- src/liballoc/vec.rs | 8 +-- src/libarena/lib.rs | 6 +- src/libcore/slice/rotate.rs | 4 +- src/libstd/sync/mpsc/sync.rs | 14 ++-- 6 files changed, 99 insertions(+), 92 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index d65c24f7350..793da97a083 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -98,7 +98,7 @@ impl VecDeque { // For zero sized types, we are always at maximum capacity MAXIMUM_ZST_CAPACITY } else { - self.buf.cap() + self.buf.capacity() } } @@ -314,10 +314,10 @@ impl VecDeque { } /// Frobs the head and tail sections around to handle the fact that we - /// just reallocated. Unsafe because it trusts old_cap. + /// just reallocated. Unsafe because it trusts old_capacity. #[inline] - unsafe fn handle_cap_increase(&mut self, old_cap: usize) { - let new_cap = self.cap(); + unsafe fn handle_capacity_increase(&mut self, old_capacity: usize) { + let new_capacity = self.cap(); // Move the shortest contiguous section of the ring buffer // T H @@ -336,15 +336,15 @@ impl VecDeque { if self.tail <= self.head { // A // Nop - } else if self.head < old_cap - self.tail { + } else if self.head < old_capacity - self.tail { // B - self.copy_nonoverlapping(old_cap, 0, self.head); - self.head += old_cap; + self.copy_nonoverlapping(old_capacity, 0, self.head); + self.head += old_capacity; debug_assert!(self.head > self.tail); } else { // C - let new_tail = new_cap - (old_cap - self.tail); - self.copy_nonoverlapping(new_tail, self.tail, old_cap - self.tail); + let new_tail = new_capacity - (old_capacity - self.tail); + self.copy_nonoverlapping(new_tail, self.tail, old_capacity - self.tail); self.tail = new_tail; debug_assert!(self.head < self.tail); } @@ -551,7 +551,7 @@ impl VecDeque { if new_cap > old_cap { self.buf.reserve_exact(used_cap, new_cap - used_cap); unsafe { - self.handle_cap_increase(old_cap); + self.handle_capacity_increase(old_cap); } } } @@ -641,7 +641,7 @@ impl VecDeque { if new_cap > old_cap { self.buf.try_reserve_exact(used_cap, new_cap - used_cap)?; unsafe { - self.handle_cap_increase(old_cap); + self.handle_capacity_increase(old_cap); } } Ok(()) @@ -1873,7 +1873,7 @@ impl VecDeque { let old_cap = self.cap(); self.buf.double(); unsafe { - self.handle_cap_increase(old_cap); + self.handle_capacity_increase(old_cap); } debug_assert!(!self.is_full()); } @@ -2708,9 +2708,9 @@ impl From> for VecDeque { // We need to extend the buf if it's not a power of two, too small // or doesn't have at least one free space - if !buf.cap().is_power_of_two() || (buf.cap() < (MINIMUM_CAPACITY + 1)) || - (buf.cap() == len) { - let cap = cmp::max(buf.cap() + 1, MINIMUM_CAPACITY + 1).next_power_of_two(); + if !buf.capacity().is_power_of_two() || (buf.capacity() < (MINIMUM_CAPACITY + 1)) || + (buf.capacity() == len) { + let cap = cmp::max(buf.capacity() + 1, MINIMUM_CAPACITY + 1).next_power_of_two(); buf.reserve_exact(len, cap - len); } @@ -3096,8 +3096,8 @@ mod tests { fn test_vec_from_vecdeque() { use crate::vec::Vec; - fn create_vec_and_test_convert(cap: usize, offset: usize, len: usize) { - let mut vd = VecDeque::with_capacity(cap); + fn create_vec_and_test_convert(capacity: usize, offset: usize, len: usize) { + let mut vd = VecDeque::with_capacity(capacity); for _ in 0..offset { vd.push_back(0); vd.pop_front(); diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs index d1fc5ac3b30..e5a8a522fbc 100644 --- a/src/liballoc/raw_vec.rs +++ b/src/liballoc/raw_vec.rs @@ -34,7 +34,7 @@ use crate::boxed::Box; /// that might occur with zero-sized types. /// /// However this means that you need to be careful when round-tripping this type -/// with a `Box<[T]>`: `cap()` won't yield the len. However `with_capacity`, +/// with a `Box<[T]>`: `capacity()` won't yield the len. However `with_capacity`, /// `shrink_to_fit`, and `from_box` will actually set RawVec's private capacity /// field. This allows zero-sized types to not be special-cased by consumers of /// this type. @@ -65,25 +65,25 @@ impl RawVec { /// Like `with_capacity` but parameterized over the choice of /// allocator for the returned RawVec. #[inline] - pub fn with_capacity_in(cap: usize, a: A) -> Self { - RawVec::allocate_in(cap, false, a) + pub fn with_capacity_in(capacity: usize, a: A) -> Self { + RawVec::allocate_in(capacity, false, a) } /// Like `with_capacity_zeroed` but parameterized over the choice /// of allocator for the returned RawVec. #[inline] - pub fn with_capacity_zeroed_in(cap: usize, a: A) -> Self { - RawVec::allocate_in(cap, true, a) + pub fn with_capacity_zeroed_in(capacity: usize, a: A) -> Self { + RawVec::allocate_in(capacity, true, a) } - fn allocate_in(cap: usize, zeroed: bool, mut a: A) -> Self { + fn allocate_in(capacity: usize, zeroed: bool, mut a: A) -> Self { unsafe { let elem_size = mem::size_of::(); - let alloc_size = cap.checked_mul(elem_size).unwrap_or_else(|| capacity_overflow()); + let alloc_size = capacity.checked_mul(elem_size).unwrap_or_else(|| capacity_overflow()); alloc_guard(alloc_size).unwrap_or_else(|_| capacity_overflow()); - // handles ZSTs and `cap = 0` alike + // handles ZSTs and `capacity = 0` alike let ptr = if alloc_size == 0 { NonNull::::dangling() } else { @@ -102,7 +102,7 @@ impl RawVec { RawVec { ptr: ptr.into(), - cap, + cap: capacity, a, } } @@ -120,8 +120,8 @@ impl RawVec { } /// Creates a RawVec (on the system heap) with exactly the - /// capacity and alignment requirements for a `[T; cap]`. This is - /// equivalent to calling RawVec::new when `cap` is 0 or T is + /// capacity and alignment requirements for a `[T; capacity]`. This is + /// equivalent to calling RawVec::new when `capacity` is 0 or T is /// zero-sized. Note that if `T` is zero-sized this means you will /// *not* get a RawVec with the requested capacity! /// @@ -135,14 +135,14 @@ impl RawVec { /// /// Aborts on OOM #[inline] - pub fn with_capacity(cap: usize) -> Self { - RawVec::allocate_in(cap, false, Global) + pub fn with_capacity(capacity: usize) -> Self { + RawVec::allocate_in(capacity, false, Global) } /// Like `with_capacity` but guarantees the buffer is zeroed. #[inline] - pub fn with_capacity_zeroed(cap: usize) -> Self { - RawVec::allocate_in(cap, true, Global) + pub fn with_capacity_zeroed(capacity: usize) -> Self { + RawVec::allocate_in(capacity, true, Global) } } @@ -154,10 +154,10 @@ impl RawVec { /// The ptr must be allocated (via the given allocator `a`), and with the given capacity. The /// capacity cannot exceed `isize::MAX` (only a concern on 32-bit systems). /// If the ptr and capacity come from a RawVec created via `a`, then this is guaranteed. - pub unsafe fn from_raw_parts_in(ptr: *mut T, cap: usize, a: A) -> Self { + pub unsafe fn from_raw_parts_in(ptr: *mut T, capacity: usize, a: A) -> Self { RawVec { ptr: Unique::new_unchecked(ptr), - cap, + cap: capacity, a, } } @@ -171,10 +171,10 @@ impl RawVec { /// The ptr must be allocated (on the system heap), and with the given capacity. The /// capacity cannot exceed `isize::MAX` (only a concern on 32-bit systems). /// If the ptr and capacity come from a RawVec, then this is guaranteed. - pub unsafe fn from_raw_parts(ptr: *mut T, cap: usize) -> Self { + pub unsafe fn from_raw_parts(ptr: *mut T, capacity: usize) -> Self { RawVec { ptr: Unique::new_unchecked(ptr), - cap, + cap: capacity, a: Global, } } @@ -191,7 +191,7 @@ impl RawVec { impl RawVec { /// Gets a raw pointer to the start of the allocation. Note that this is - /// Unique::empty() if `cap = 0` or T is zero-sized. In the former case, you must + /// Unique::empty() if `capacity = 0` or T is zero-sized. In the former case, you must /// be careful. pub fn ptr(&self) -> *mut T { self.ptr.as_ptr() @@ -201,7 +201,7 @@ impl RawVec { /// /// This will always be `usize::MAX` if `T` is zero-sized. #[inline(always)] - pub fn cap(&self) -> usize { + pub fn capacity(&self) -> usize { if mem::size_of::() == 0 { !0 } else { @@ -209,6 +209,12 @@ impl RawVec { } } + // For backwards compatibility + #[inline(always)] + pub fn cap(&self) -> usize { + self.capacity() + } + /// Returns a shared reference to the allocator backing this RawVec. pub fn alloc(&self) -> &A { &self.a @@ -240,7 +246,7 @@ impl RawVec { /// This function is ideal for when pushing elements one-at-a-time because /// you don't need to incur the costs of the more general computations /// reserve needs to do to guard against overflow. You do however need to - /// manually check if your `len == cap`. + /// manually check if your `len == capacity`. /// /// # Panics /// @@ -267,7 +273,7 @@ impl RawVec { /// /// impl MyVec { /// pub fn push(&mut self, elem: T) { - /// if self.len == self.buf.cap() { self.buf.double(); } + /// if self.len == self.buf.capacity() { self.buf.double(); } /// // double would have aborted or panicked if the len exceeded /// // `isize::MAX` so this is safe to do unchecked now. /// unsafe { @@ -381,20 +387,20 @@ impl RawVec { } /// The same as `reserve_exact`, but returns on errors instead of panicking or aborting. - pub fn try_reserve_exact(&mut self, used_cap: usize, needed_extra_cap: usize) + pub fn try_reserve_exact(&mut self, used_capacity: usize, needed_extra_capacity: usize) -> Result<(), CollectionAllocErr> { - self.reserve_internal(used_cap, needed_extra_cap, Fallible, Exact) + self.reserve_internal(used_capacity, needed_extra_capacity, Fallible, Exact) } /// Ensures that the buffer contains at least enough space to hold - /// `used_cap + needed_extra_cap` elements. If it doesn't already, + /// `used_capacity + needed_extra_capacity` elements. If it doesn't already, /// will reallocate the minimum possible amount of memory necessary. /// Generally this will be exactly the amount of memory necessary, /// but in principle the allocator is free to give back more than /// we asked for. /// - /// If `used_cap` exceeds `self.cap()`, this may fail to actually allocate + /// If `used_capacity` exceeds `self.capacity()`, this may fail to actually allocate /// the requested space. This is not really unsafe, but the unsafe /// code *you* write that relies on the behavior of this function may break. /// @@ -407,22 +413,23 @@ impl RawVec { /// # Aborts /// /// Aborts on OOM - pub fn reserve_exact(&mut self, used_cap: usize, needed_extra_cap: usize) { - match self.reserve_internal(used_cap, needed_extra_cap, Infallible, Exact) { + pub fn reserve_exact(&mut self, used_capacity: usize, needed_extra_capacity: usize) { + match self.reserve_internal(used_capacity, needed_extra_capacity, Infallible, Exact) { Err(CapacityOverflow) => capacity_overflow(), Err(AllocErr) => unreachable!(), Ok(()) => { /* yay */ } } } - /// Calculates the buffer's new size given that it'll hold `used_cap + - /// needed_extra_cap` elements. This logic is used in amortized reserve methods. + /// Calculates the buffer's new size given that it'll hold `used_capacity + + /// needed_extra_capacity` elements. This logic is used in amortized reserve methods. /// Returns `(new_capacity, new_alloc_size)`. - fn amortized_new_size(&self, used_cap: usize, needed_extra_cap: usize) + fn amortized_new_size(&self, used_capacity: usize, needed_extra_capacity: usize) -> Result { // Nothing we can really do about these checks :( - let required_cap = used_cap.checked_add(needed_extra_cap).ok_or(CapacityOverflow)?; + let required_cap = used_capacity.checked_add(needed_extra_capacity) + .ok_or(CapacityOverflow)?; // Cannot overflow, because `cap <= isize::MAX`, and type of `cap` is `usize`. let double_cap = self.cap * 2; // `double_cap` guarantees exponential growth. @@ -430,18 +437,18 @@ impl RawVec { } /// The same as `reserve`, but returns on errors instead of panicking or aborting. - pub fn try_reserve(&mut self, used_cap: usize, needed_extra_cap: usize) + pub fn try_reserve(&mut self, used_capacity: usize, needed_extra_capacity: usize) -> Result<(), CollectionAllocErr> { - self.reserve_internal(used_cap, needed_extra_cap, Fallible, Amortized) + self.reserve_internal(used_capacity, needed_extra_capacity, Fallible, Amortized) } /// Ensures that the buffer contains at least enough space to hold - /// `used_cap + needed_extra_cap` elements. If it doesn't already have + /// `used_capacity + needed_extra_capacity` elements. If it doesn't already have /// enough capacity, will reallocate enough space plus comfortable slack /// space to get amortized `O(1)` behavior. Will limit this behavior /// if it would needlessly cause itself to panic. /// - /// If `used_cap` exceeds `self.cap()`, this may fail to actually allocate + /// If `used_capacity` exceeds `self.capacity()`, this may fail to actually allocate /// the requested space. This is not really unsafe, but the unsafe /// code *you* write that relies on the behavior of this function may break. /// @@ -487,20 +494,20 @@ impl RawVec { /// # vector.push_all(&[1, 3, 5, 7, 9]); /// # } /// ``` - pub fn reserve(&mut self, used_cap: usize, needed_extra_cap: usize) { - match self.reserve_internal(used_cap, needed_extra_cap, Infallible, Amortized) { + pub fn reserve(&mut self, used_capacity: usize, needed_extra_capacity: usize) { + match self.reserve_internal(used_capacity, needed_extra_capacity, Infallible, Amortized) { Err(CapacityOverflow) => capacity_overflow(), Err(AllocErr) => unreachable!(), Ok(()) => { /* yay */ } } } /// Attempts to ensure that the buffer contains at least enough space to hold - /// `used_cap + needed_extra_cap` elements. If it doesn't already have + /// `used_capacity + needed_extra_capacity` elements. If it doesn't already have /// enough capacity, will reallocate in place enough space plus comfortable slack /// space to get amortized `O(1)` behavior. Will limit this behaviour /// if it would needlessly cause itself to panic. /// - /// If `used_cap` exceeds `self.cap()`, this may fail to actually allocate + /// If `used_capacity` exceeds `self.capacity()`, this may fail to actually allocate /// the requested space. This is not really unsafe, but the unsafe /// code *you* write that relies on the behavior of this function may break. /// @@ -511,7 +518,7 @@ impl RawVec { /// * Panics if the requested capacity exceeds `usize::MAX` bytes. /// * Panics on 32-bit platforms if the requested capacity exceeds /// `isize::MAX` bytes. - pub fn reserve_in_place(&mut self, used_cap: usize, needed_extra_cap: usize) -> bool { + pub fn reserve_in_place(&mut self, used_capacity: usize, needed_extra_capacity: usize) -> bool { unsafe { // NOTE: we don't early branch on ZSTs here because we want this // to actually catch "asking for more than usize::MAX" in that case. @@ -520,20 +527,20 @@ impl RawVec { // Don't actually need any more capacity. If the current `cap` is 0, we can't // reallocate in place. - // Wrapping in case they give a bad `used_cap` + // Wrapping in case they give a bad `used_capacity` let old_layout = match self.current_layout() { Some(layout) => layout, None => return false, }; - if self.cap().wrapping_sub(used_cap) >= needed_extra_cap { + if self.capacity().wrapping_sub(used_capacity) >= needed_extra_capacity { return false; } - let new_cap = self.amortized_new_size(used_cap, needed_extra_cap) + let new_cap = self.amortized_new_size(used_capacity, needed_extra_capacity) .unwrap_or_else(|_| capacity_overflow()); - // Here, `cap < used_cap + needed_extra_cap <= new_cap` - // (regardless of whether `self.cap - used_cap` wrapped). + // Here, `cap < used_capacity + needed_extra_capacity <= new_cap` + // (regardless of whether `self.cap - used_capacity` wrapped). // Therefore we can safely call grow_in_place. let new_layout = Layout::new::().repeat(new_cap).unwrap().0; @@ -632,8 +639,8 @@ use ReserveStrategy::*; impl RawVec { fn reserve_internal( &mut self, - used_cap: usize, - needed_extra_cap: usize, + used_capacity: usize, + needed_extra_capacity: usize, fallibility: Fallibility, strategy: ReserveStrategy, ) -> Result<(), CollectionAllocErr> { @@ -646,15 +653,15 @@ impl RawVec { // panic. // Don't actually need any more capacity. - // Wrapping in case they gave a bad `used_cap`. - if self.cap().wrapping_sub(used_cap) >= needed_extra_cap { + // Wrapping in case they gave a bad `used_capacity`. + if self.capacity().wrapping_sub(used_capacity) >= needed_extra_capacity { return Ok(()); } // Nothing we can really do about these checks :( let new_cap = match strategy { - Exact => used_cap.checked_add(needed_extra_cap).ok_or(CapacityOverflow)?, - Amortized => self.amortized_new_size(used_cap, needed_extra_cap)?, + Exact => used_capacity.checked_add(needed_extra_capacity).ok_or(CapacityOverflow)?, + Amortized => self.amortized_new_size(used_capacity, needed_extra_capacity)?, }; let new_layout = Layout::array::(new_cap).map_err(|_| CapacityOverflow)?; @@ -692,7 +699,7 @@ impl RawVec { /// Note that this will correctly reconstitute any `cap` changes /// that may have been performed. (see description of type for details) pub unsafe fn into_box(self) -> Box<[T]> { - // NOTE: not calling `cap()` here, actually using the real `cap` field! + // NOTE: not calling `capacity()` here, actually using the real `cap` field! let slice = slice::from_raw_parts_mut(self.ptr(), self.cap); let output: Box<[T]> = Box::from_raw(slice); mem::forget(self); @@ -796,29 +803,29 @@ mod tests { let mut v: RawVec = RawVec::new(); // First `reserve` allocates like `reserve_exact` v.reserve(0, 9); - assert_eq!(9, v.cap()); + assert_eq!(9, v.capacity()); } { let mut v: RawVec = RawVec::new(); v.reserve(0, 7); - assert_eq!(7, v.cap()); + assert_eq!(7, v.capacity()); // 97 if more than double of 7, so `reserve` should work // like `reserve_exact`. v.reserve(7, 90); - assert_eq!(97, v.cap()); + assert_eq!(97, v.capacity()); } { let mut v: RawVec = RawVec::new(); v.reserve(0, 12); - assert_eq!(12, v.cap()); + assert_eq!(12, v.capacity()); v.reserve(12, 3); // 3 is less than half of 12, so `reserve` must grow // exponentially. At the time of writing this test grow // factor is 2, so new capacity is 24, however, grow factor // of 1.5 is OK too. Hence `>= 18` in assert. - assert!(v.cap() >= 12 + 12 / 2); + assert!(v.capacity() >= 12 + 12 / 2); } } diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index cd62c3e0524..72b702de875 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -432,7 +432,7 @@ impl Vec { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn capacity(&self) -> usize { - self.buf.cap() + self.buf.capacity() } /// Reserves capacity for at least `additional` more elements to be inserted @@ -878,7 +878,7 @@ impl Vec { assert!(index <= len); // space for the new element - if len == self.buf.cap() { + if len == self.buf.capacity() { self.reserve(1); } @@ -1019,7 +1019,7 @@ impl Vec { pub fn push(&mut self, value: T) { // This will panic or abort if we would allocate > isize::MAX bytes // or if the length increment would overflow for zero-sized types. - if self.len == self.buf.cap() { + if self.len == self.buf.capacity() { self.reserve(1); } unsafe { @@ -1750,7 +1750,7 @@ impl IntoIterator for Vec { } else { begin.add(self.len()) as *const T }; - let cap = self.buf.cap(); + let cap = self.buf.capacity(); mem::forget(self); IntoIter { buf: NonNull::new_unchecked(begin), diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index ce5e5f23a94..619b25c7905 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -99,7 +99,7 @@ impl TypedArenaChunk { // A pointer as large as possible for zero-sized elements. !0 as *mut T } else { - self.start().add(self.storage.cap()) + self.start().add(self.storage.capacity()) } } } @@ -270,7 +270,7 @@ impl TypedArena { self.end.set(last_chunk.end()); return; } else { - new_capacity = last_chunk.storage.cap(); + new_capacity = last_chunk.storage.capacity(); loop { new_capacity = new_capacity.checked_mul(2).unwrap(); if new_capacity >= currently_used_cap + n { @@ -405,7 +405,7 @@ impl DroplessArena { self.end.set(last_chunk.end()); return; } else { - new_capacity = last_chunk.storage.cap(); + new_capacity = last_chunk.storage.capacity(); loop { new_capacity = new_capacity.checked_mul(2).unwrap(); if new_capacity >= used_bytes + needed_bytes { diff --git a/src/libcore/slice/rotate.rs b/src/libcore/slice/rotate.rs index f69b219715a..0437937d769 100644 --- a/src/libcore/slice/rotate.rs +++ b/src/libcore/slice/rotate.rs @@ -16,7 +16,7 @@ union RawArray { } impl RawArray { - fn cap() -> usize { + fn capacity() -> usize { if mem::size_of::() == 0 { usize::max_value() } else { @@ -55,7 +55,7 @@ impl RawArray { pub unsafe fn ptr_rotate(mut left: usize, mid: *mut T, mut right: usize) { loop { let delta = cmp::min(left, right); - if delta <= RawArray::::cap() { + if delta <= RawArray::::capacity() { // We will always hit this immediately for ZST. break; } diff --git a/src/libstd/sync/mpsc/sync.rs b/src/libstd/sync/mpsc/sync.rs index b2d9f4c6491..36eafa50c9b 100644 --- a/src/libstd/sync/mpsc/sync.rs +++ b/src/libstd/sync/mpsc/sync.rs @@ -161,20 +161,20 @@ fn wakeup(token: SignalToken, guard: MutexGuard<'_, State>) { } impl Packet { - pub fn new(cap: usize) -> Packet { + pub fn new(capacity: usize) -> Packet { Packet { channels: AtomicUsize::new(1), lock: Mutex::new(State { disconnected: false, blocker: NoneBlocked, - cap, + cap: capacity, canceled: None, queue: Queue { head: ptr::null_mut(), tail: ptr::null_mut(), }, buf: Buffer { - buf: (0..cap + if cap == 0 {1} else {0}).map(|_| None).collect(), + buf: (0..capacity + if capacity == 0 {1} else {0}).map(|_| None).collect(), start: 0, size: 0, }, @@ -189,7 +189,7 @@ impl Packet { loop { let mut guard = self.lock.lock().unwrap(); // are we ready to go? - if guard.disconnected || guard.buf.size() < guard.buf.cap() { + if guard.disconnected || guard.buf.size() < guard.buf.capacity() { return guard; } // no room; actually block @@ -231,7 +231,7 @@ impl Packet { let mut guard = self.lock.lock().unwrap(); if guard.disconnected { Err(super::TrySendError::Disconnected(t)) - } else if guard.buf.size() == guard.buf.cap() { + } else if guard.buf.size() == guard.buf.capacity() { Err(super::TrySendError::Full(t)) } else if guard.cap == 0 { // With capacity 0, even though we have buffer space we can't @@ -249,7 +249,7 @@ impl Packet { // If the buffer has some space and the capacity isn't 0, then we // just enqueue the data for later retrieval, ensuring to wake up // any blocked receiver if there is one. - assert!(guard.buf.size() < guard.buf.cap()); + assert!(guard.buf.size() < guard.buf.capacity()); guard.buf.enqueue(t); match mem::replace(&mut guard.blocker, NoneBlocked) { BlockedReceiver(token) => wakeup(token, guard), @@ -475,7 +475,7 @@ impl Buffer { } fn size(&self) -> usize { self.size } - fn cap(&self) -> usize { self.buf.len() } + fn capacity(&self) -> usize { self.buf.len() } } //////////////////////////////////////////////////////////////////////////////// -- cgit 1.4.1-3-g733a5 From 9b3583375dbd45b19b8ce8822b89ff79529354d6 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 29 Apr 2019 18:32:05 -0700 Subject: Document the order of {Vec,VecDeque,String}::retain It's natural for `retain` to work in order from beginning to end, but this wasn't actually documented to be the case. If we actually promise this, then the caller can do useful things like track the index of each element being tested, as [discussed in the forum][1]. This is now documented for `Vec`, `VecDeque`, and `String`. [1]: https://users.rust-lang.org/t/vec-retain-by-index/27697 `HashMap` and `HashSet` also have `retain`, and the `hashbrown` implementation does happen to use a plain `iter()` order too, but it's not certain that this should always be the case for these types. --- src/liballoc/collections/vec_deque.rs | 4 ++-- src/liballoc/string.rs | 4 ++-- src/liballoc/vec.rs | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index d65c24f7350..82a60f92444 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -1835,8 +1835,8 @@ impl VecDeque { /// Retains only the elements specified by the predicate. /// /// In other words, remove all elements `e` such that `f(&e)` returns false. - /// This method operates in place and preserves the order of the retained - /// elements. + /// This method operates in place, visiting each element exactly once in the + /// original order, and preserves the order of the retained elements. /// /// # Examples /// diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index a3e2098695f..aaa38142693 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -1200,8 +1200,8 @@ impl String { /// Retains only the characters specified by the predicate. /// /// In other words, remove all characters `c` such that `f(c)` returns `false`. - /// This method operates in place and preserves the order of the retained - /// characters. + /// This method operates in place, visiting each character exactly once in the + /// original order, and preserves the order of the retained characters. /// /// # Examples /// diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index cd62c3e0524..a9bc835010f 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -937,8 +937,8 @@ impl Vec { /// Retains only the elements specified by the predicate. /// /// In other words, remove all elements `e` such that `f(&e)` returns `false`. - /// This method operates in place and preserves the order of the retained - /// elements. + /// This method operates in place, visiting each element exactly once in the + /// original order, and preserves the order of the retained elements. /// /// # Examples /// -- cgit 1.4.1-3-g733a5 From a0e112ba52bbf90f958cf51b6fb39970c8a5c8b2 Mon Sep 17 00:00:00 2001 From: YOSHIOKA Takuma Date: Tue, 30 Apr 2019 15:52:07 +0900 Subject: Implement `BorrowMut` for `String` Closes rust-lang/rfcs#1282. --- src/liballoc/str.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src/liballoc') diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs index e5d4e1c533c..f66ff894ae8 100644 --- a/src/liballoc/str.rs +++ b/src/liballoc/str.rs @@ -28,7 +28,7 @@ // It's cleaner to just turn off the unused_imports warning than to fix them. #![allow(unused_imports)] -use core::borrow::Borrow; +use core::borrow::{Borrow, BorrowMut}; use core::str::pattern::{Pattern, Searcher, ReverseSearcher, DoubleEndedSearcher}; use core::mem; use core::ptr; @@ -190,6 +190,14 @@ impl Borrow for String { } } +#[stable(feature = "string_borrow_mut", since = "1.36.0")] +impl BorrowMut for String { + #[inline] + fn borrow_mut(&mut self) -> &mut str { + &mut self[..] + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl ToOwned for str { type Owned = String; -- cgit 1.4.1-3-g733a5 From adbaf7a9cdc3f67116e2034d0e5e235779dae286 Mon Sep 17 00:00:00 2001 From: Alexey Shmalko Date: Wed, 1 May 2019 23:26:06 +0300 Subject: BinaryHeap: add min-heap example --- src/liballoc/collections/binary_heap.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'src/liballoc') diff --git a/src/liballoc/collections/binary_heap.rs b/src/liballoc/collections/binary_heap.rs index 8c142a3d317..c355361b53c 100644 --- a/src/liballoc/collections/binary_heap.rs +++ b/src/liballoc/collections/binary_heap.rs @@ -207,6 +207,30 @@ use super::SpecExtend; /// // The heap should now be empty. /// assert!(heap.is_empty()) /// ``` +/// +/// ## Min-heap +/// +/// Either `std::cmp::Reverse` or a custom `Ord` implementation can be used to +/// make `BinaryHeap` a min-heap. This makes `heap.pop()` return the smallest +/// value instead of the greatest one. +/// +/// ``` +/// use std::collections::BinaryHeap; +/// use std::cmp::Reverse; +/// +/// let mut heap = BinaryHeap::new(); +/// +/// // Wrap values in `Reverse` +/// heap.push(Reverse(1)); +/// heap.push(Reverse(5)); +/// heap.push(Reverse(2)); +/// +/// // If we pop these scores now, they should come back in the reverse order. +/// assert_eq!(heap.pop(), Some(Reverse(1))); +/// assert_eq!(heap.pop(), Some(Reverse(2))); +/// assert_eq!(heap.pop(), Some(Reverse(5))); +/// assert_eq!(heap.pop(), None); +/// ``` #[stable(feature = "rust1", since = "1.0.0")] pub struct BinaryHeap { data: Vec, -- cgit 1.4.1-3-g733a5 From 639e452c5f0a76b11ebe3703a04b6ae13d96c887 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 4 May 2019 04:20:55 +0200 Subject: Remove unused feature(need_allocator). --- src/liballoc/lib.rs | 1 - 1 file changed, 1 deletion(-) (limited to 'src/liballoc') diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index eb673488170..2edd946ff11 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -87,7 +87,6 @@ #![feature(fundamental)] #![feature(lang_items)] #![feature(libc)] -#![feature(needs_allocator)] #![feature(nll)] #![feature(optin_builtin_traits)] #![feature(pattern)] -- cgit 1.4.1-3-g733a5 From ccb9dac5ed65341bf8d9ce01a83b9aad02f42526 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Sat, 4 May 2019 23:48:57 +0900 Subject: Fix intra-doc link resolution failure on re-exporting libstd --- src/liballoc/alloc.rs | 18 ++++++++++++++++++ src/libcore/task/wake.rs | 23 +++++++++++++++++++++++ src/libstd/alloc.rs | 5 +++++ src/libstd/collections/hash/map.rs | 5 ++++- src/libstd/error.rs | 18 ++++++++++++++++++ src/libstd/ffi/os_str.rs | 2 ++ src/libstd/fs.rs | 2 ++ src/libstd/io/buffered.rs | 2 +- src/libstd/net/addr.rs | 13 +++++++++++++ src/libstd/sync/mutex.rs | 2 ++ src/libstd/sync/rwlock.rs | 2 ++ src/libstd/thread/mod.rs | 1 + src/test/rustdoc/intra-link-libstd-re-export.rs | 3 +++ 13 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 src/test/rustdoc/intra-link-libstd-re-export.rs (limited to 'src/liballoc') diff --git a/src/liballoc/alloc.rs b/src/liballoc/alloc.rs index ddc6481eec7..41ff06d70ff 100644 --- a/src/liballoc/alloc.rs +++ b/src/liballoc/alloc.rs @@ -37,6 +37,8 @@ extern "Rust" { /// /// Note: while this type is unstable, the functionality it provides can be /// accessed through the [free functions in `alloc`](index.html#functions). +/// +/// [`Alloc`]: trait.Alloc.html #[unstable(feature = "allocator_api", issue = "32838")] #[derive(Copy, Clone, Default, Debug)] pub struct Global; @@ -54,6 +56,10 @@ pub struct Global; /// /// See [`GlobalAlloc::alloc`]. /// +/// [`Global`]: struct.Global.html +/// [`Alloc`]: trait.Alloc.html +/// [`GlobalAlloc::alloc`]: trait.GlobalAlloc.html#tymethod.alloc +/// /// # Examples /// /// ``` @@ -87,6 +93,10 @@ pub unsafe fn alloc(layout: Layout) -> *mut u8 { /// # Safety /// /// See [`GlobalAlloc::dealloc`]. +/// +/// [`Global`]: struct.Global.html +/// [`Alloc`]: trait.Alloc.html +/// [`GlobalAlloc::dealloc`]: trait.GlobalAlloc.html#tymethod.dealloc #[stable(feature = "global_alloc", since = "1.28.0")] #[inline] pub unsafe fn dealloc(ptr: *mut u8, layout: Layout) { @@ -105,6 +115,10 @@ pub unsafe fn dealloc(ptr: *mut u8, layout: Layout) { /// # Safety /// /// See [`GlobalAlloc::realloc`]. +/// +/// [`Global`]: struct.Global.html +/// [`Alloc`]: trait.Alloc.html +/// [`GlobalAlloc::realloc`]: trait.GlobalAlloc.html#method.realloc #[stable(feature = "global_alloc", since = "1.28.0")] #[inline] pub unsafe fn realloc(ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { @@ -124,6 +138,10 @@ pub unsafe fn realloc(ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 /// /// See [`GlobalAlloc::alloc_zeroed`]. /// +/// [`Global`]: struct.Global.html +/// [`Alloc`]: trait.Alloc.html +/// [`GlobalAlloc::alloc_zeroed`]: trait.GlobalAlloc.html#method.alloc_zeroed +/// /// # Examples /// /// ``` diff --git a/src/libcore/task/wake.rs b/src/libcore/task/wake.rs index b4e91249832..a6d611d2e93 100644 --- a/src/libcore/task/wake.rs +++ b/src/libcore/task/wake.rs @@ -10,6 +10,8 @@ use crate::marker::{PhantomData, Unpin}; /// /// It consists of a data pointer and a [virtual function pointer table (vtable)][vtable] that /// customizes the behavior of the `RawWaker`. +/// +/// [`Waker`]: struct.Waker.html #[derive(PartialEq, Debug)] #[stable(feature = "futures_api", since = "1.36.0")] pub struct RawWaker { @@ -55,6 +57,8 @@ impl RawWaker { /// pointer of a properly constructed [`RawWaker`] object from inside the /// [`RawWaker`] implementation. Calling one of the contained functions using /// any other `data` pointer will cause undefined behavior. +/// +/// [`RawWaker`]: struct.RawWaker.html #[stable(feature = "futures_api", since = "1.36.0")] #[derive(PartialEq, Copy, Clone, Debug)] pub struct RawWakerVTable { @@ -65,6 +69,9 @@ pub struct RawWakerVTable { /// required for this additional instance of a [`RawWaker`] and associated /// task. Calling `wake` on the resulting [`RawWaker`] should result in a wakeup /// of the same task that would have been awoken by the original [`RawWaker`]. + /// + /// [`Waker`]: struct.Waker.html + /// [`RawWaker`]: struct.RawWaker.html clone: unsafe fn(*const ()) -> RawWaker, /// This function will be called when `wake` is called on the [`Waker`]. @@ -73,6 +80,9 @@ pub struct RawWakerVTable { /// The implementation of this function must make sure to release any /// resources that are associated with this instance of a [`RawWaker`] and /// associated task. + /// + /// [`Waker`]: struct.Waker.html + /// [`RawWaker`]: struct.RawWaker.html wake: unsafe fn(*const ()), /// This function will be called when `wake_by_ref` is called on the [`Waker`]. @@ -80,6 +90,9 @@ pub struct RawWakerVTable { /// /// This function is similar to `wake`, but must not consume the provided data /// pointer. + /// + /// [`Waker`]: struct.Waker.html + /// [`RawWaker`]: struct.RawWaker.html wake_by_ref: unsafe fn(*const ()), /// This function gets called when a [`RawWaker`] gets dropped. @@ -87,6 +100,8 @@ pub struct RawWakerVTable { /// The implementation of this function must make sure to release any /// resources that are associated with this instance of a [`RawWaker`] and /// associated task. + /// + /// [`RawWaker`]: struct.RawWaker.html drop: unsafe fn(*const ()), } @@ -128,6 +143,9 @@ impl RawWakerVTable { /// The implementation of this function must make sure to release any /// resources that are associated with this instance of a [`RawWaker`] and /// associated task. + /// + /// [`Waker`]: struct.Waker.html + /// [`RawWaker`]: struct.RawWaker.html #[rustc_promotable] #[cfg_attr(stage0, unstable(feature = "futures_api_const_fn_ptr", issue = "50547"))] #[cfg_attr(not(stage0), stable(feature = "futures_api", since = "1.36.0"))] @@ -201,6 +219,8 @@ impl fmt::Debug for Context<'_> { /// executor-specific wakeup behavior. /// /// Implements [`Clone`], [`Send`], and [`Sync`]. +/// +/// [`RawWaker`]: struct.RawWaker.html #[repr(transparent)] #[stable(feature = "futures_api", since = "1.36.0")] pub struct Waker { @@ -266,6 +286,9 @@ impl Waker { /// The behavior of the returned `Waker` is undefined if the contract defined /// in [`RawWaker`]'s and [`RawWakerVTable`]'s documentation is not upheld. /// Therefore this method is unsafe. + /// + /// [`RawWaker`]: struct.RawWaker.html + /// [`RawWakerVTable`]: struct.RawWakerVTable.html #[inline] #[stable(feature = "futures_api", since = "1.36.0")] pub unsafe fn from_raw(waker: RawWaker) -> Waker { diff --git a/src/libstd/alloc.rs b/src/libstd/alloc.rs index 4241f47b661..ff52974775b 100644 --- a/src/libstd/alloc.rs +++ b/src/libstd/alloc.rs @@ -173,6 +173,9 @@ static HOOK: AtomicPtr<()> = AtomicPtr::new(ptr::null_mut()); /// about the allocation that failed. /// /// The allocation error hook is a global resource. +/// +/// [`set_alloc_error_hook`]: fn.set_alloc_error_hook.html +/// [`take_alloc_error_hook`]: fn.take_alloc_error_hook.html #[unstable(feature = "alloc_error_hook", issue = "51245")] pub fn set_alloc_error_hook(hook: fn(Layout)) { HOOK.store(hook as *mut (), Ordering::SeqCst); @@ -183,6 +186,8 @@ pub fn set_alloc_error_hook(hook: fn(Layout)) { /// *See also the function [`set_alloc_error_hook`].* /// /// If no custom hook is registered, the default hook will be returned. +/// +/// [`set_alloc_error_hook`]: fn.set_alloc_error_hook.html #[unstable(feature = "alloc_error_hook", issue = "51245")] pub fn take_alloc_error_hook() -> fn(Layout) { let hook = HOOK.swap(ptr::null_mut(), Ordering::SeqCst); diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index f9fb392f9f5..af4f911a784 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -2492,7 +2492,10 @@ impl DefaultHasher { #[stable(feature = "hashmap_default_hasher", since = "1.13.0")] impl Default for DefaultHasher { - /// Creates a new `DefaultHasher` using [`new`][DefaultHasher::new]. + // FIXME: here should link `new` to [DefaultHasher::new], but it occurs intra-doc link + // resolution failure when re-exporting libstd items. When #56922 fixed, + // link `new` to [DefaultHasher::new] again. + /// Creates a new `DefaultHasher` using `new`. /// See its documentation for more. fn default() -> DefaultHasher { DefaultHasher::new() diff --git a/src/libstd/error.rs b/src/libstd/error.rs index 081fff0562b..71227c31c55 100644 --- a/src/libstd/error.rs +++ b/src/libstd/error.rs @@ -207,6 +207,8 @@ pub trait Error: Debug + Display { impl<'a, E: Error + 'a> From for Box { /// Converts a type of [`Error`] into a box of dyn [`Error`]. /// + /// [`Error`]: ../error/trait.Error.html + /// /// # Examples /// /// ``` @@ -244,6 +246,8 @@ impl<'a, E: Error + Send + Sync + 'a> From for Box From for Box for Box { /// Converts a [`String`] into a box of dyn [`Error`] + [`Send`] + [`Sync`]. /// + /// [`Error`]: ../error/trait.Error.html + /// /// # Examples /// /// ``` @@ -318,6 +324,8 @@ impl From for Box { impl From for Box { /// Converts a [`String`] into a box of dyn [`Error`]. /// + /// [`Error`]: ../error/trait.Error.html + /// /// # Examples /// /// ``` @@ -339,6 +347,8 @@ impl From for Box { impl<'a> From<&str> for Box { /// Converts a [`str`] into a box of dyn [`Error`] + [`Send`] + [`Sync`]. /// + /// [`Error`]: ../error/trait.Error.html + /// /// # Examples /// /// ``` @@ -359,6 +369,8 @@ impl<'a> From<&str> for Box { impl From<&str> for Box { /// Converts a [`str`] into a box of dyn [`Error`]. /// + /// [`Error`]: ../error/trait.Error.html + /// /// # Examples /// /// ``` @@ -378,6 +390,9 @@ impl From<&str> for Box { impl<'a, 'b> From> for Box { /// Converts a [`Cow`] into a box of dyn [`Error`] + [`Send`] + [`Sync`]. /// + /// [`Cow`]: ../borrow/enum.Cow.html + /// [`Error`]: ../error/trait.Error.html + /// /// # Examples /// /// ``` @@ -399,6 +414,9 @@ impl<'a, 'b> From> for Box { impl<'a> From> for Box { /// Converts a [`Cow`] into a box of dyn [`Error`]. /// + /// [`Cow`]: ../borrow/enum.Cow.html + /// [`Error`]: ../error/trait.Error.html + /// /// # Examples /// /// ``` diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs index 13aee783750..c7c5849a00f 100644 --- a/src/libstd/ffi/os_str.rs +++ b/src/libstd/ffi/os_str.rs @@ -351,6 +351,8 @@ impl From for OsString { /// Converts a [`String`] into a [`OsString`]. /// /// The conversion copies the data, and includes an allocation on the heap. + /// + /// [`OsString`]: ../../std/ffi/struct.OsString.html fn from(s: String) -> OsString { OsString { inner: Buf::from_string(s) } } diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index 991b45fd4a2..616b5eb836f 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -1812,6 +1812,8 @@ pub fn canonicalize>(path: P) -> io::Result { /// function.) /// * `path` already exists. /// +/// [`create_dir_all`]: fn.create_dir_all.html +/// /// # Examples /// /// ```no_run diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index 5be2687d8f5..e309f81192c 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -754,7 +754,7 @@ impl fmt::Display for IntoInnerError { /// completed, rather than the entire buffer at once. Enter `LineWriter`. It /// does exactly that. /// -/// Like [`BufWriter`], a `LineWriter`’s buffer will also be flushed when the +/// Like [`BufWriter`][bufwriter], a `LineWriter`’s buffer will also be flushed when the /// `LineWriter` goes out of scope or when its internal buffer is full. /// /// [bufwriter]: struct.BufWriter.html diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs index ec54d8a042a..b3f0508221a 100644 --- a/src/libstd/net/addr.rs +++ b/src/libstd/net/addr.rs @@ -546,6 +546,9 @@ impl FromInner for SocketAddrV6 { #[stable(feature = "ip_from_ip", since = "1.16.0")] impl From for SocketAddr { /// Converts a [`SocketAddrV4`] into a [`SocketAddr::V4`]. + /// + /// [`SocketAddrV4`]: ../../std/net/struct.SocketAddrV4.html + /// [`SocketAddr::V4`]: ../../std/net/enum.SocketAddr.html#variant.V4 fn from(sock4: SocketAddrV4) -> SocketAddr { SocketAddr::V4(sock4) } @@ -554,6 +557,9 @@ impl From for SocketAddr { #[stable(feature = "ip_from_ip", since = "1.16.0")] impl From for SocketAddr { /// Converts a [`SocketAddrV6`] into a [`SocketAddr::V6`]. + /// + /// [`SocketAddrV6`]: ../../std/net/struct.SocketAddrV6.html + /// [`SocketAddr::V6`]: ../../std/net/enum.SocketAddr.html#variant.V6 fn from(sock6: SocketAddrV6) -> SocketAddr { SocketAddr::V6(sock6) } @@ -567,6 +573,13 @@ impl> From<(I, u16)> for SocketAddr { /// and creates a [`SocketAddr::V6`] for a [`IpAddr::V6`]. /// /// `u16` is treated as port of the newly created [`SocketAddr`]. + /// + /// [`IpAddr`]: ../../std/net/enum.IpAddr.html + /// [`IpAddr::V4`]: ../../std/net/enum.IpAddr.html#variant.V4 + /// [`IpAddr::V6`]: ../../std/net/enum.IpAddr.html#variant.V6 + /// [`SocketAddr`]: ../../std/net/enum.SocketAddr.html + /// [`SocketAddr::V4`]: ../../std/net/enum.SocketAddr.html#variant.V4 + /// [`SocketAddr::V6`]: ../../std/net/enum.SocketAddr.html#variant.V6 fn from(pieces: (I, u16)) -> SocketAddr { SocketAddr::new(pieces.0.into(), pieces.1) } diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs index 11ac34fcb24..87c2318a937 100644 --- a/src/libstd/sync/mutex.rs +++ b/src/libstd/sync/mutex.rs @@ -376,6 +376,8 @@ unsafe impl<#[may_dangle] T: ?Sized> Drop for Mutex { impl From for Mutex { /// Creates a new mutex in an unlocked state ready for use. /// This is equivalent to [`Mutex::new`]. + /// + /// [`Mutex::new`]: ../../std/sync/struct.Mutex.html#method.new fn from(t: T) -> Self { Mutex::new(t) } diff --git a/src/libstd/sync/rwlock.rs b/src/libstd/sync/rwlock.rs index 1299a744095..b1b56f321fc 100644 --- a/src/libstd/sync/rwlock.rs +++ b/src/libstd/sync/rwlock.rs @@ -453,6 +453,8 @@ impl Default for RwLock { impl From for RwLock { /// Creates a new instance of an `RwLock` which is unlocked. /// This is equivalent to [`RwLock::new`]. + /// + /// [`RwLock::new`]: ../../std/sync/struct.RwLock.html#method.new fn from(t: T) -> Self { RwLock::new(t) } diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index fce28ffd9c3..35de4f4008b 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -443,6 +443,7 @@ impl Builder { /// [`Builder::spawn`]: ../../std/thread/struct.Builder.html#method.spawn /// [`io::Result`]: ../../std/io/type.Result.html /// [`JoinHandle`]: ../../std/thread/struct.JoinHandle.html + /// [`JoinHandle::join`]: ../../std/thread/struct.JoinHandle.html#method.join #[unstable(feature = "thread_spawn_unchecked", issue = "55132")] pub unsafe fn spawn_unchecked<'a, F, T>(self, f: F) -> io::Result> where F: FnOnce() -> T, F: Send + 'a, T: Send + 'a diff --git a/src/test/rustdoc/intra-link-libstd-re-export.rs b/src/test/rustdoc/intra-link-libstd-re-export.rs new file mode 100644 index 00000000000..6f239292ec2 --- /dev/null +++ b/src/test/rustdoc/intra-link-libstd-re-export.rs @@ -0,0 +1,3 @@ +#![deny(intra_doc_link_resolution_failure)] + +pub use std::*; -- cgit 1.4.1-3-g733a5 From 1acd37fde5b07c66853b925d7d91dd3be6dc2a78 Mon Sep 17 00:00:00 2001 From: Dodo Date: Thu, 9 May 2019 20:30:36 +0200 Subject: make vecdeque_rotate stable --- src/liballoc/collections/vec_deque.rs | 8 ++------ src/liballoc/tests/lib.rs | 1 - 2 files changed, 2 insertions(+), 7 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index d65c24f7350..7e7a854d2f3 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -1934,8 +1934,6 @@ impl VecDeque { /// # Examples /// /// ``` - /// #![feature(vecdeque_rotate)] - /// /// use std::collections::VecDeque; /// /// let mut buf: VecDeque<_> = (0..10).collect(); @@ -1949,7 +1947,7 @@ impl VecDeque { /// } /// assert_eq!(buf, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); /// ``` - #[unstable(feature = "vecdeque_rotate", issue = "56686")] + #[stable(feature = "vecdeque_rotate", since = "1.35.0")] pub fn rotate_left(&mut self, mid: usize) { assert!(mid <= self.len()); let k = self.len() - mid; @@ -1979,8 +1977,6 @@ impl VecDeque { /// # Examples /// /// ``` - /// #![feature(vecdeque_rotate)] - /// /// use std::collections::VecDeque; /// /// let mut buf: VecDeque<_> = (0..10).collect(); @@ -1994,7 +1990,7 @@ impl VecDeque { /// } /// assert_eq!(buf, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); /// ``` - #[unstable(feature = "vecdeque_rotate", issue = "56686")] + #[stable(feature = "vecdeque_rotate", since = "1.35.0")] pub fn rotate_right(&mut self, k: usize) { assert!(k <= self.len()); let mid = self.len() - k; diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs index b736750c576..ddb3120e89d 100644 --- a/src/liballoc/tests/lib.rs +++ b/src/liballoc/tests/lib.rs @@ -6,7 +6,6 @@ #![feature(repeat_generic_slice)] #![feature(try_reserve)] #![feature(unboxed_closures)] -#![feature(vecdeque_rotate)] #![deny(rust_2018_idioms)] use std::hash::{Hash, Hasher}; -- cgit 1.4.1-3-g733a5 From 4d033990fcb96023739a13c43e72b341de51e865 Mon Sep 17 00:00:00 2001 From: Dodo Date: Thu, 9 May 2019 20:50:02 +0200 Subject: supposed to be 1.36.0 --- src/liballoc/collections/vec_deque.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index 7e7a854d2f3..65a888a9703 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -1947,7 +1947,7 @@ impl VecDeque { /// } /// assert_eq!(buf, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); /// ``` - #[stable(feature = "vecdeque_rotate", since = "1.35.0")] + #[stable(feature = "vecdeque_rotate", since = "1.36.0")] pub fn rotate_left(&mut self, mid: usize) { assert!(mid <= self.len()); let k = self.len() - mid; @@ -1990,7 +1990,7 @@ impl VecDeque { /// } /// assert_eq!(buf, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); /// ``` - #[stable(feature = "vecdeque_rotate", since = "1.35.0")] + #[stable(feature = "vecdeque_rotate", since = "1.36.0")] pub fn rotate_right(&mut self, k: usize) { assert!(k <= self.len()); let mid = self.len() - k; -- cgit 1.4.1-3-g733a5 From 0545375ca6822b4b140cd853f368473d69b76227 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 10 May 2019 18:01:50 -0700 Subject: Add examples of ordered retain --- src/liballoc/collections/vec_deque.rs | 14 ++++++++++++++ src/liballoc/string.rs | 10 ++++++++++ src/liballoc/vec.rs | 10 ++++++++++ 3 files changed, 34 insertions(+) (limited to 'src/liballoc') diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index 82a60f92444..9a8d48083e6 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -1848,6 +1848,20 @@ impl VecDeque { /// buf.retain(|&x| x%2 == 0); /// assert_eq!(buf, [2, 4]); /// ``` + /// + /// The exact order may be useful for tracking external state, like an index. + /// + /// ``` + /// use std::collections::VecDeque; + /// + /// let mut buf = VecDeque::new(); + /// buf.extend(1..6); + /// + /// let keep = [false, true, true, false, true]; + /// let mut i = 0; + /// buf.retain(|_| (keep[i], i += 1).0); + /// assert_eq!(buf, [2, 3, 5]); + /// ``` #[stable(feature = "vec_deque_retain", since = "1.4.0")] pub fn retain(&mut self, mut f: F) where F: FnMut(&T) -> bool diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index aaa38142693..3fdcf95ccaa 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -1212,6 +1212,16 @@ impl String { /// /// assert_eq!(s, "foobar"); /// ``` + /// + /// The exact order may be useful for tracking external state, like an index. + /// + /// ``` + /// let mut s = String::from("abcde"); + /// let keep = [false, true, true, false, true]; + /// let mut i = 0; + /// s.retain(|_| (keep[i], i += 1).0); + /// assert_eq!(s, "bce"); + /// ``` #[inline] #[stable(feature = "string_retain", since = "1.26.0")] pub fn retain(&mut self, mut f: F) diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index a9bc835010f..073d3ab5937 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -947,6 +947,16 @@ impl Vec { /// vec.retain(|&x| x%2 == 0); /// assert_eq!(vec, [2, 4]); /// ``` + /// + /// The exact order may be useful for tracking external state, like an index. + /// + /// ``` + /// let mut vec = vec![1, 2, 3, 4, 5]; + /// let keep = [false, true, true, false, true]; + /// let mut i = 0; + /// vec.retain(|_| (keep[i], i += 1).0); + /// assert_eq!(vec, [2, 3, 5]); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn retain(&mut self, mut f: F) where F: FnMut(&T) -> bool -- cgit 1.4.1-3-g733a5 From 740a8dabb413abecd88a202f2370252b33e73a7f Mon Sep 17 00:00:00 2001 From: Thomas Heck Date: Sat, 11 May 2019 10:23:07 +0200 Subject: add comment to `Rc`/`Arc`'s `Eq` specialization --- src/liballoc/rc.rs | 5 +++++ src/liballoc/sync.rs | 5 +++++ 2 files changed, 10 insertions(+) (limited to 'src/liballoc') diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 68eecd97ea1..0dffb19476f 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -932,6 +932,11 @@ impl RcEqIdent for Rc { } } +/// We're doing this specialization here, and not as a more general optimization on `&T`, because it +/// would otherwise add a cost to all equality checks on refs. We assume that `Rc`s are used to +/// store large values, that are slow to clone, but also heavy to check for equality, causing this +/// cost to pay off more easily. It's also more likely to have two `Rc` clones, that point to +/// the same value, than two `&T`s. #[stable(feature = "rust1", since = "1.0.0")] impl RcEqIdent for Rc { #[inline] diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index 466e806663c..90c7859b3db 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -1377,6 +1377,11 @@ impl ArcEqIdent for Arc { } } +/// We're doing this specialization here, and not as a more general optimization on `&T`, because it +/// would otherwise add a cost to all equality checks on refs. We assume that `Arc`s are used to +/// store large values, that are slow to clone, but also heavy to check for equality, causing this +/// cost to pay off more easily. It's also more likely to have two `Arc` clones, that point to +/// the same value, than two `&T`s. #[stable(feature = "rust1", since = "1.0.0")] impl ArcEqIdent for Arc { #[inline] -- cgit 1.4.1-3-g733a5 From 3c9790e4293e41a1a45a50eaee4e76a1fb64d5f8 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 14 May 2019 14:43:43 -0700 Subject: Update the compiler_builtins crate This updates to 0.1.13 for `compiler_builtins`, published to fix a few issues. The feature changes here are updated because `compiler_builtins` no longer enables the `c` feature by default but we want to do so through our build still. Closes #60747 Closes #60782 --- Cargo.lock | 34 +++++++++++++++++----------------- src/bootstrap/compile.rs | 2 +- src/liballoc/Cargo.toml | 1 + src/libstd/Cargo.toml | 4 ++-- 4 files changed, 21 insertions(+), 20 deletions(-) (limited to 'src/liballoc') diff --git a/Cargo.lock b/Cargo.lock index a4f30d1ebcf..db9f0069ced 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -25,7 +25,7 @@ dependencies = [ name = "alloc" version = "0.0.0" dependencies = [ - "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_xorshift 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -123,7 +123,7 @@ version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-std-workspace-core 1.0.0", ] @@ -462,7 +462,7 @@ dependencies = [ [[package]] name = "compiler_builtins" -version = "0.1.12" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", @@ -744,7 +744,7 @@ name = "dlmalloc" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-std-workspace-core 1.0.0", ] @@ -910,7 +910,7 @@ name = "fortanix-sgx-abi" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-std-workspace-core 1.0.0", ] @@ -1071,7 +1071,7 @@ name = "hashbrown" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-std-workspace-alloc 1.0.0", "rustc-std-workspace-core 1.0.0", ] @@ -1772,7 +1772,7 @@ dependencies = [ name = "panic_abort" version = "0.0.0" dependencies = [ - "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1782,7 +1782,7 @@ name = "panic_unwind" version = "0.0.0" dependencies = [ "alloc 0.0.0", - "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", "unwind 0.0.0", @@ -1967,7 +1967,7 @@ name = "profiler_builtins" version = "0.0.0" dependencies = [ "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -2492,7 +2492,7 @@ name = "rustc-demangle" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-std-workspace-core 1.0.0", ] @@ -2620,7 +2620,7 @@ dependencies = [ "alloc 0.0.0", "build_helper 0.1.0", "cmake 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -2850,7 +2850,7 @@ dependencies = [ "alloc 0.0.0", "build_helper 0.1.0", "cmake 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -2912,7 +2912,7 @@ dependencies = [ "alloc 0.0.0", "build_helper 0.1.0", "cmake 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -3029,7 +3029,7 @@ dependencies = [ "alloc 0.0.0", "build_helper 0.1.0", "cmake 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -3298,7 +3298,7 @@ dependencies = [ "alloc 0.0.0", "backtrace-sys 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", "dlmalloc 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "fortanix-sgx-abi 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3889,7 +3889,7 @@ name = "unwind" version = "0.0.0" dependencies = [ "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4087,7 +4087,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum colored 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b0aa3473e85a3161b59845d6096b289bb577874cafeaf75ea1b1beaa6572c7fc" "checksum commoncrypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d056a8586ba25a1e4d61cb090900e495952c7886786fc55f909ab2f819b69007" "checksum commoncrypto-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fed34f46747aa73dfaa578069fd8279d2818ade2b55f38f22a9401c7f4083e2" -"checksum compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "6549720ae78db799196d4af8f719facb4c7946710b4b64148482553e54b56d15" +"checksum compiler_builtins 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "e3f235c329e5cb9fa3d2ca2cc36256ba9a7f23fa76e0f4db6f68c23b73b2ac69" "checksum compiletest_rs 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "f40ecc9332b68270998995c00f8051ee856121764a0d3230e64c9efd059d27b6" "checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e" "checksum core-foundation 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4e2640d6d0bf22e82bed1b73c6aef8d5dd31e5abe6666c57e6d45e2649f4f887" diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 9c4e856f0b8..e1cdd226fd6 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -168,7 +168,7 @@ pub fn std_cargo(builder: &Builder<'_>, .arg("--manifest-path") .arg(builder.src.join("src/liballoc/Cargo.toml")) .arg("--features") - .arg("compiler-builtins-mem"); + .arg("compiler-builtins-mem compiler-builtins-c"); } else { let features = builder.std_features(); diff --git a/src/liballoc/Cargo.toml b/src/liballoc/Cargo.toml index ddf0044c506..bcb27bb5161 100644 --- a/src/liballoc/Cargo.toml +++ b/src/liballoc/Cargo.toml @@ -33,3 +33,4 @@ harness = false [features] compiler-builtins-mem = ['compiler_builtins/mem'] +compiler-builtins-c = ["compiler_builtins/c"] diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml index 5d797b75621..55e8b39974e 100644 --- a/src/libstd/Cargo.toml +++ b/src/libstd/Cargo.toml @@ -19,7 +19,7 @@ panic_unwind = { path = "../libpanic_unwind", optional = true } panic_abort = { path = "../libpanic_abort" } core = { path = "../libcore" } libc = { version = "0.2.51", default-features = false, features = ['rustc-dep-of-std'] } -compiler_builtins = { version = "0.1.12" } +compiler_builtins = { version = "0.1.14" } profiler_builtins = { path = "../libprofiler_builtins", optional = true } unwind = { path = "../libunwind" } hashbrown = { version = "0.3.0", features = ['rustc-dep-of-std'] } @@ -54,7 +54,7 @@ default = ["compiler_builtins_c", "std_detect_file_io", "std_detect_dlsym_getaux backtrace = ["backtrace-sys"] panic-unwind = ["panic_unwind"] profiler = ["profiler_builtins"] -compiler_builtins_c = ["compiler_builtins/c"] +compiler_builtins_c = ["alloc/compiler-builtins-c"] llvm-libunwind = ["unwind/llvm-libunwind"] # Make panics and failed asserts immediately abort without formatting any message -- cgit 1.4.1-3-g733a5 From 90dd35918de13994cf06058de33860dfbd8ab51f Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 17 May 2019 19:56:35 -0700 Subject: Use iter() for iterating arrays by slice These `into_iter()` calls will change from iterating references to values if we ever get `IntoIterator` for arrays, which may break the code using that iterator. Calling `iter()` is future proof. --- src/liballoc/tests/btree/set.rs | 4 ++-- src/libcore/iter/traits/iterator.rs | 32 ++++++++++++++++---------------- src/librustdoc/config.rs | 2 +- src/librustdoc/html/render.rs | 2 +- 4 files changed, 20 insertions(+), 20 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/tests/btree/set.rs b/src/liballoc/tests/btree/set.rs index d52814118b3..989beb3b1bf 100644 --- a/src/liballoc/tests/btree/set.rs +++ b/src/liballoc/tests/btree/set.rs @@ -143,8 +143,8 @@ fn test_union() { #[test] // Only tests the simple function definition with respect to intersection fn test_is_disjoint() { - let one = [1].into_iter().collect::>(); - let two = [2].into_iter().collect::>(); + let one = [1].iter().collect::>(); + let two = [2].iter().collect::>(); assert!(one.is_disjoint(&two)); } diff --git a/src/libcore/iter/traits/iterator.rs b/src/libcore/iter/traits/iterator.rs index 403f3358105..38c7c9bc4d0 100644 --- a/src/libcore/iter/traits/iterator.rs +++ b/src/libcore/iter/traits/iterator.rs @@ -356,7 +356,7 @@ pub trait Iterator { /// /// ``` /// let a = [0, 1, 2, 3, 4, 5]; - /// let mut iter = a.into_iter().step_by(2); + /// let mut iter = a.iter().step_by(2); /// /// assert_eq!(iter.next(), Some(&0)); /// assert_eq!(iter.next(), Some(&2)); @@ -531,7 +531,7 @@ pub trait Iterator { /// ``` /// let a = [1, 2, 3]; /// - /// let mut iter = a.into_iter().map(|x| 2 * x); + /// let mut iter = a.iter().map(|x| 2 * x); /// /// assert_eq!(iter.next(), Some(2)); /// assert_eq!(iter.next(), Some(4)); @@ -620,7 +620,7 @@ pub trait Iterator { /// ``` /// let a = [0i32, 1, 2]; /// - /// let mut iter = a.into_iter().filter(|x| x.is_positive()); + /// let mut iter = a.iter().filter(|x| x.is_positive()); /// /// assert_eq!(iter.next(), Some(&1)); /// assert_eq!(iter.next(), Some(&2)); @@ -634,7 +634,7 @@ pub trait Iterator { /// ``` /// let a = [0, 1, 2]; /// - /// let mut iter = a.into_iter().filter(|x| **x > 1); // need two *s! + /// let mut iter = a.iter().filter(|x| **x > 1); // need two *s! /// /// assert_eq!(iter.next(), Some(&2)); /// assert_eq!(iter.next(), None); @@ -646,7 +646,7 @@ pub trait Iterator { /// ``` /// let a = [0, 1, 2]; /// - /// let mut iter = a.into_iter().filter(|&x| *x > 1); // both & and * + /// let mut iter = a.iter().filter(|&x| *x > 1); // both & and * /// /// assert_eq!(iter.next(), Some(&2)); /// assert_eq!(iter.next(), None); @@ -657,7 +657,7 @@ pub trait Iterator { /// ``` /// let a = [0, 1, 2]; /// - /// let mut iter = a.into_iter().filter(|&&x| x > 1); // two &s + /// let mut iter = a.iter().filter(|&&x| x > 1); // two &s /// /// assert_eq!(iter.next(), Some(&2)); /// assert_eq!(iter.next(), None); @@ -837,7 +837,7 @@ pub trait Iterator { /// ``` /// let a = [-1i32, 0, 1]; /// - /// let mut iter = a.into_iter().skip_while(|x| x.is_negative()); + /// let mut iter = a.iter().skip_while(|x| x.is_negative()); /// /// assert_eq!(iter.next(), Some(&0)); /// assert_eq!(iter.next(), Some(&1)); @@ -851,7 +851,7 @@ pub trait Iterator { /// ``` /// let a = [-1, 0, 1]; /// - /// let mut iter = a.into_iter().skip_while(|x| **x < 0); // need two *s! + /// let mut iter = a.iter().skip_while(|x| **x < 0); // need two *s! /// /// assert_eq!(iter.next(), Some(&0)); /// assert_eq!(iter.next(), Some(&1)); @@ -863,7 +863,7 @@ pub trait Iterator { /// ``` /// let a = [-1, 0, 1, -2]; /// - /// let mut iter = a.into_iter().skip_while(|x| **x < 0); + /// let mut iter = a.iter().skip_while(|x| **x < 0); /// /// assert_eq!(iter.next(), Some(&0)); /// assert_eq!(iter.next(), Some(&1)); @@ -898,7 +898,7 @@ pub trait Iterator { /// ``` /// let a = [-1i32, 0, 1]; /// - /// let mut iter = a.into_iter().take_while(|x| x.is_negative()); + /// let mut iter = a.iter().take_while(|x| x.is_negative()); /// /// assert_eq!(iter.next(), Some(&-1)); /// assert_eq!(iter.next(), None); @@ -911,7 +911,7 @@ pub trait Iterator { /// ``` /// let a = [-1, 0, 1]; /// - /// let mut iter = a.into_iter().take_while(|x| **x < 0); // need two *s! + /// let mut iter = a.iter().take_while(|x| **x < 0); // need two *s! /// /// assert_eq!(iter.next(), Some(&-1)); /// assert_eq!(iter.next(), None); @@ -922,7 +922,7 @@ pub trait Iterator { /// ``` /// let a = [-1, 0, 1, -2]; /// - /// let mut iter = a.into_iter().take_while(|x| **x < 0); + /// let mut iter = a.iter().take_while(|x| **x < 0); /// /// assert_eq!(iter.next(), Some(&-1)); /// @@ -937,7 +937,7 @@ pub trait Iterator { /// /// ``` /// let a = [1, 2, 3, 4]; - /// let mut iter = a.into_iter(); + /// let mut iter = a.iter(); /// /// let result: Vec = iter.by_ref() /// .take_while(|n| **n != 3) @@ -1321,7 +1321,7 @@ pub trait Iterator { /// ``` /// let a = [1, 2, 3]; /// - /// let iter = a.into_iter(); + /// let iter = a.iter(); /// /// let sum: i32 = iter.take(5).fold(0, |acc, i| acc + i ); /// @@ -1334,7 +1334,7 @@ pub trait Iterator { /// // let's try that again /// let a = [1, 2, 3]; /// - /// let mut iter = a.into_iter(); + /// let mut iter = a.iter(); /// /// // instead, we add in a .by_ref() /// let sum: i32 = iter.by_ref().take(2).fold(0, |acc, i| acc + i ); @@ -1479,7 +1479,7 @@ pub trait Iterator { /// let a = [1, 2, 3]; /// /// let (even, odd): (Vec, Vec) = a - /// .into_iter() + /// .iter() /// .partition(|&n| n % 2 == 0); /// /// assert_eq!(even, vec![2]); diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 72421c9decc..4fae7e080b1 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -538,7 +538,7 @@ fn check_deprecated_options(matches: &getopts::Matches, diag: &errors::Handler) "passes", ]; - for flag in deprecated_flags.into_iter() { + for flag in deprecated_flags.iter() { if matches.opt_present(flag) { let mut err = diag.struct_warn(&format!("the '{}' flag is considered deprecated", flag)); diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 0207fcda9e8..964789224de 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -506,7 +506,7 @@ pub fn initial_ids() -> Vec { "methods", "deref-methods", "implementations", - ].into_iter().map(|id| (String::from(*id))).collect() + ].iter().map(|id| (String::from(*id))).collect() } /// Generates the documentation for `crate` into the directory `dst` -- cgit 1.4.1-3-g733a5 From ea7aa76911b6b896d503a812b26bfd6227fa90d9 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 18 May 2019 20:25:15 -0700 Subject: Document BinaryHeap time complexity I went into some detail on the time complexity of `push` because it is relevant for using BinaryHeap efficiently -- specifically that you should avoid pushing many elements in ascending order when possible. --- src/liballoc/collections/binary_heap.rs | 43 +++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'src/liballoc') diff --git a/src/liballoc/collections/binary_heap.rs b/src/liballoc/collections/binary_heap.rs index 39fcfaa7893..c5a0b6e877b 100644 --- a/src/liballoc/collections/binary_heap.rs +++ b/src/liballoc/collections/binary_heap.rs @@ -231,6 +231,20 @@ use super::SpecExtend; /// assert_eq!(heap.pop(), Some(Reverse(5))); /// assert_eq!(heap.pop(), None); /// ``` +/// +/// # Time complexity +/// +/// | [push] | [pop] | [peek]/[peek\_mut] | +/// |--------|----------|--------------------| +/// | O(1)~ | O(log n) | O(1) | +/// +/// The value for `push` is an expected cost; the method documentation gives a +/// more detailed analysis. +/// +/// [push]: #method.push +/// [pop]: #method.pop +/// [peek]: #method.peek +/// [peek\_mut]: #method.peek_mut #[stable(feature = "rust1", since = "1.0.0")] pub struct BinaryHeap { data: Vec, @@ -384,6 +398,10 @@ impl BinaryHeap { /// } /// assert_eq!(heap.peek(), Some(&2)); /// ``` + /// + /// # Time complexity + /// + /// Cost is O(1) in the worst case. #[stable(feature = "binary_heap_peek_mut", since = "1.12.0")] pub fn peek_mut(&mut self) -> Option> { if self.is_empty() { @@ -411,6 +429,11 @@ impl BinaryHeap { /// assert_eq!(heap.pop(), Some(1)); /// assert_eq!(heap.pop(), None); /// ``` + /// + /// # Time complexity + /// + /// The worst case cost of `pop` on a heap containing *n* elements is O(log + /// n). #[stable(feature = "rust1", since = "1.0.0")] pub fn pop(&mut self) -> Option { self.data.pop().map(|mut item| { @@ -438,6 +461,22 @@ impl BinaryHeap { /// assert_eq!(heap.len(), 3); /// assert_eq!(heap.peek(), Some(&5)); /// ``` + /// + /// # Time complexity + /// + /// The expected cost of `push`, averaged over every possible ordering of + /// the elements being pushed, and over a sufficiently large number of + /// pushes, is O(1). This is the most meaningful cost metric when pushing + /// elements that are *not* already in any sorted pattern. + /// + /// The time complexity degrades if elements are pushed in predominantly + /// ascending order. In the worst case, elements are pushed in ascending + /// sorted order and the amortized cost per push is O(log n) against a heap + /// containing *n* elements. + /// + /// The worst case cost of a *single* call to `push` is O(n). The worst case + /// occurs when capacity is exhausted and needs a resize. The resize cost + /// has been amortized in the previous figures. #[stable(feature = "rust1", since = "1.0.0")] pub fn push(&mut self, item: T) { let old_len = self.len(); @@ -650,6 +689,10 @@ impl BinaryHeap { /// assert_eq!(heap.peek(), Some(&5)); /// /// ``` + /// + /// # Time complexity + /// + /// Cost is O(1) in the worst case. #[stable(feature = "rust1", since = "1.0.0")] pub fn peek(&self) -> Option<&T> { self.data.get(0) -- cgit 1.4.1-3-g733a5 From b7afe777f79462c9023a30b31785b81e8346c96c Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 1 May 2019 19:39:52 +0200 Subject: stabilize core parts of MaybeUninit and deprecate mem::uninitialized in the future Also expand the documentation a bit --- src/liballoc/lib.rs | 2 +- src/libcore/lib.rs | 2 +- src/libcore/mem.rs | 300 +++++++++++------------- src/libstd/lib.rs | 1 - src/test/codegen/box-maybe-uninit.rs | 1 - src/test/run-pass/panic-uninitialized-zeroed.rs | 2 +- 6 files changed, 138 insertions(+), 170 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 2edd946ff11..d90036eaf49 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -109,7 +109,7 @@ #![feature(rustc_const_unstable)] #![feature(const_vec_new)] #![feature(slice_partition_dedup)] -#![feature(maybe_uninit, maybe_uninit_slice, maybe_uninit_array)] +#![feature(maybe_uninit_extra, maybe_uninit_slice, maybe_uninit_array)] #![feature(alloc_layout_extra)] #![feature(try_trait)] #![feature(iter_nth_back)] diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 28db55578c3..4a70329b64b 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -125,7 +125,7 @@ #![feature(structural_match)] #![feature(abi_unadjusted)] #![feature(adx_target_feature)] -#![feature(maybe_uninit, maybe_uninit_slice, maybe_uninit_array)] +#![feature(maybe_uninit_slice, maybe_uninit_array)] #![feature(external_doc)] #[prelude_import] diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 9fb071d2952..9e23a5e61e4 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -465,29 +465,39 @@ pub const fn needs_drop() -> bool { /// Creates a value whose bytes are all zero. /// -/// This has the same effect as allocating space with -/// [`mem::uninitialized`][uninit] and then zeroing it out. It is useful for -/// FFI sometimes, but should generally be avoided. +/// This has the same effect as [`MaybeUninit::zeroed().assume_init()`][zeroed]. +/// It is useful for FFI sometimes, but should generally be avoided. /// /// There is no guarantee that an all-zero byte-pattern represents a valid value of -/// some type `T`. If `T` has a destructor and the value is destroyed (due to -/// a panic or the end of a scope) before being initialized, then the destructor -/// will run on zeroed data, likely leading to [undefined behavior][ub]. +/// some type `T`. For example, the all-zero byte-pattern is not a valid value +/// for reference types (`&T` and `&mut T`). Using `zeroed` on such types +/// causes immediate [undefined behavior][ub]. /// -/// See also the documentation for [`mem::uninitialized`][uninit], which has -/// many of the same caveats. +/// See the documentation of [`MaybeUninit`] and [`MaybeUninit::zeroed()`][zeroed] +/// for more discussion on how to initialize values. /// -/// [uninit]: fn.uninitialized.html +/// [zeroed]: union.MaybeUninit.html#method.zeroed +/// [`MaybeUninit`]: union.MaybeUninit.html /// [ub]: ../../reference/behavior-considered-undefined.html /// /// # Examples /// +/// Correct usage of this function: initializing an integer with zero. +/// /// ``` /// use std::mem; /// /// let x: i32 = unsafe { mem::zeroed() }; /// assert_eq!(0, x); /// ``` +/// +/// *Incorrect* usage of this function: initializing a reference with zero. +/// +/// ```no_run +/// use std::mem; +/// +/// let _x: &i32 = unsafe { mem::zeroed() }; // Undefined behavior! +/// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn zeroed() -> T { @@ -498,130 +508,13 @@ pub unsafe fn zeroed() -> T { /// Bypasses Rust's normal memory-initialization checks by pretending to /// produce a value of type `T`, while doing nothing at all. /// -/// **This is incredibly dangerous and should not be done lightly. Deeply -/// consider initializing your memory with a default value instead.** -/// -/// This is useful for FFI functions and initializing arrays sometimes, -/// but should generally be avoided. -/// -/// # Undefined behavior -/// -/// It is [undefined behavior][ub] to read uninitialized memory, even just an -/// uninitialized boolean. For instance, if you branch on the value of such -/// a boolean, your program may take one, both, or neither of the branches. -/// -/// Writing to the uninitialized value is similarly dangerous. Rust believes the -/// value is initialized, and will therefore try to [`Drop`] the uninitialized -/// value and its fields if you try to overwrite it in a normal manner. The only way -/// to safely initialize an uninitialized value is with [`ptr::write`][write], -/// [`ptr::copy`][copy], or [`ptr::copy_nonoverlapping`][copy_no]. -/// -/// If the value does implement [`Drop`], it must be initialized before -/// it goes out of scope (and therefore would be dropped). Note that this -/// includes a `panic` occurring and unwinding the stack suddenly. -/// -/// If you partially initialize an array, you may need to use -/// [`ptr::drop_in_place`][drop_in_place] to remove the elements you have fully -/// initialized followed by [`mem::forget`][mem_forget] to prevent drop running -/// on the array. If a partially allocated array is dropped this will lead to -/// undefined behaviour. +/// **This functon is deprecated because it basically cannot be used correctly.** /// -/// # Examples -/// -/// Here's how to safely initialize an array of [`Vec`]s. -/// -/// ``` -/// use std::mem; -/// use std::ptr; -/// -/// // Only declare the array. This safely leaves it -/// // uninitialized in a way that Rust will track for us. -/// // However we can't initialize it element-by-element -/// // safely, and we can't use the `[value; 1000]` -/// // constructor because it only works with `Copy` data. -/// let mut data: [Vec; 1000]; -/// -/// unsafe { -/// // So we need to do this to initialize it. -/// data = mem::uninitialized(); -/// -/// // DANGER ZONE: if anything panics or otherwise -/// // incorrectly reads the array here, we will have -/// // Undefined Behavior. -/// -/// // It's ok to mutably iterate the data, since this -/// // doesn't involve reading it at all. -/// // (ptr and len are statically known for arrays) -/// for elem in &mut data[..] { -/// // *elem = Vec::new() would try to drop the -/// // uninitialized memory at `elem` -- bad! -/// // -/// // Vec::new doesn't allocate or do really -/// // anything. It's only safe to call here -/// // because we know it won't panic. -/// ptr::write(elem, Vec::new()); -/// } +/// Use [`MaybeUninit`] instead. /// -/// // SAFE ZONE: everything is initialized. -/// } -/// -/// println!("{:?}", &data[0]); -/// ``` -/// -/// This example emphasizes exactly how delicate and dangerous using `mem::uninitialized` -/// can be. Note that the [`vec!`] macro *does* let you initialize every element with a -/// value that is only [`Clone`], so the following is semantically equivalent and -/// vastly less dangerous, as long as you can live with an extra heap -/// allocation: -/// -/// ``` -/// let data: Vec> = vec![Vec::new(); 1000]; -/// println!("{:?}", &data[0]); -/// ``` -/// -/// This example shows how to handle partially initialized arrays, which could -/// be found in low-level datastructures. -/// -/// ``` -/// use std::mem; -/// use std::ptr; -/// -/// // Count the number of elements we have assigned. -/// let mut data_len: usize = 0; -/// let mut data: [String; 1000]; -/// -/// unsafe { -/// data = mem::uninitialized(); -/// -/// for elem in &mut data[0..500] { -/// ptr::write(elem, String::from("hello")); -/// data_len += 1; -/// } -/// -/// // For each item in the array, drop if we allocated it. -/// for i in &mut data[0..data_len] { -/// ptr::drop_in_place(i); -/// } -/// } -/// // Forget the data. If this is allowed to drop, you may see a crash such as: -/// // 'mem_uninit_test(2457,0x7fffb55dd380) malloc: *** error for object -/// // 0x7ff3b8402920: pointer being freed was not allocated' -/// mem::forget(data); -/// ``` -/// -/// [`Vec`]: ../../std/vec/struct.Vec.html -/// [`vec!`]: ../../std/macro.vec.html -/// [`Clone`]: ../../std/clone/trait.Clone.html -/// [ub]: ../../reference/behavior-considered-undefined.html -/// [write]: ../ptr/fn.write.html -/// [drop_in_place]: ../ptr/fn.drop_in_place.html -/// [mem_zeroed]: fn.zeroed.html -/// [mem_forget]: fn.forget.html -/// [copy]: ../intrinsics/fn.copy.html -/// [copy_no]: ../intrinsics/fn.copy_nonoverlapping.html -/// [`Drop`]: ../ops/trait.Drop.html +/// [`MaybeUninit`]: union.MaybeUninit.html #[inline] -#[rustc_deprecated(since = "2.0.0", reason = "use `mem::MaybeUninit::uninit` instead")] +#[rustc_deprecated(since = "1.40.0", reason = "use `mem::MaybeUninit` instead")] #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn uninitialized() -> T { intrinsics::panic_if_uninhabited::(); @@ -899,7 +792,6 @@ pub fn discriminant(v: &T) -> Discriminant { } } -// FIXME: Reference `MaybeUninit` from these docs, once that is stable. /// A wrapper to inhibit compiler from automatically calling `T`’s destructor. /// /// This wrapper is 0-cost. @@ -908,6 +800,7 @@ pub fn discriminant(v: &T) -> Discriminant { /// As a consequence, it has *no effect* on the assumptions that the compiler makes /// about all values being initialized at their type. In particular, initializing /// a `ManuallyDrop<&mut T>` with [`mem::zeroed`] is undefined behavior. +/// If you need to handle uninitialized data, use [`MaybeUninit`] instead. /// /// # Examples /// @@ -942,6 +835,7 @@ pub fn discriminant(v: &T) -> Discriminant { /// ``` /// /// [`mem::zeroed`]: fn.zeroed.html +/// [`MaybeUninit`]: union.MaybeUninit.html #[stable(feature = "manually_drop", since = "1.20.0")] #[lang = "manually_drop"] #[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -1042,17 +936,18 @@ impl DerefMut for ManuallyDrop { } } -/// A wrapper to construct uninitialized instances of `T`. +/// A wrapper type to construct uninitialized instances of `T`. +/// +/// # Initialization invariant /// /// The compiler, in general, assumes that variables are properly initialized /// at their respective type. For example, a variable of reference type must /// be aligned and non-NULL. This is an invariant that must *always* be upheld, /// even in unsafe code. As a consequence, zero-initializing a variable of reference -/// type causes instantaneous undefined behavior, no matter whether that reference +/// type causes instantaneous [undefined behavior][ub], no matter whether that reference /// ever gets used to access memory: /// /// ```rust,no_run -/// #![feature(maybe_uninit)] /// use std::mem::{self, MaybeUninit}; /// /// let x: &i32 = unsafe { mem::zeroed() }; // undefined behavior! @@ -1067,7 +962,6 @@ impl DerefMut for ManuallyDrop { /// always be `true` or `false`. Hence, creating an uninitialized `bool` is undefined behavior: /// /// ```rust,no_run -/// #![feature(maybe_uninit)] /// use std::mem::{self, MaybeUninit}; /// /// let b: bool = unsafe { mem::uninitialized() }; // undefined behavior! @@ -1078,10 +972,9 @@ impl DerefMut for ManuallyDrop { /// Moreover, uninitialized memory is special in that the compiler knows that /// it does not have a fixed value. This makes it undefined behavior to have /// uninitialized data in a variable even if that variable has an integer type, -/// which otherwise can hold any bit pattern: +/// which otherwise can hold any *fixed* bit pattern: /// /// ```rust,no_run -/// #![feature(maybe_uninit)] /// use std::mem::{self, MaybeUninit}; /// /// let x: i32 = unsafe { mem::uninitialized() }; // undefined behavior! @@ -1091,37 +984,108 @@ impl DerefMut for ManuallyDrop { /// (Notice that the rules around uninitialized integers are not finalized yet, but /// until they are, it is advisable to avoid them.) /// +/// On top of that, remember that most types have additional invariants beyond merely +/// being considered initialized at the type level. For example, a `1`-initialized [`Vec`] +/// is considered initialized because the only requirement the compiler knows about it +/// is that the data pointer must be non-null. Creating such a `Vec` does not cause +/// *immediate* undefined behavior, but will cause undefined behavior with most +/// safe operations (including dropping it). +/// +/// [`Vec`]: ../../std/vec/struct.Vec.html +/// +/// # Examples +/// /// `MaybeUninit` serves to enable unsafe code to deal with uninitialized data. /// It is a signal to the compiler indicating that the data here might *not* /// be initialized: /// /// ```rust -/// #![feature(maybe_uninit)] /// use std::mem::MaybeUninit; /// /// // Create an explicitly uninitialized reference. The compiler knows that data inside /// // a `MaybeUninit` may be invalid, and hence this is not UB: /// let mut x = MaybeUninit::<&i32>::uninit(); /// // Set it to a valid value. -/// x.write(&0); +/// unsafe { x.as_mut_ptr().write(&0); } /// // Extract the initialized data -- this is only allowed *after* properly /// // initializing `x`! /// let x = unsafe { x.assume_init() }; /// ``` /// /// The compiler then knows to not make any incorrect assumptions or optimizations on this code. -// -// FIXME before stabilizing, explain how to initialize a struct field-by-field. +/// +/// ## Initializing an array element-by-element +/// +/// `MaybeUninit` can be used to initialize a large array element-by-element: +/// +/// ``` +/// use std::mem::{self, MaybeUninit}; +/// use std::ptr; +/// +/// let data = unsafe { +/// // Create an uninitialized array of `MaybeUninit`. The `assume_init` is +/// // safe because the type we are claiming to have initialized here is a +/// // bunch of `MaybeUninit`s, which do not require initialization. +/// let mut data: [MaybeUninit>; 1000] = MaybeUninit::uninit().assume_init(); +/// +/// // Dropping a `MaybeUninit` does nothing, so if there is a panic during this loop, +/// // we have a memory leak, but there is no memory safety issue. +/// for elem in &mut data[..] { +/// ptr::write(elem.as_mut_ptr(), vec![42]); +/// } +/// +/// // Everything is initialized. Transmute the array to the +/// // initialized type. +/// mem::transmute::<_, [Vec; 1000]>(data) +/// }; +/// +/// println!("{:?}", &data[0]); +/// ``` +/// +/// You can also work with partially initialized arrays, which could +/// be found in low-level datastructures. +/// +/// ``` +/// use std::mem::MaybeUninit; +/// use std::ptr; +/// +/// unsafe { +/// // Create an uninitialized array of `MaybeUninit`. The `assume_init` is +/// // safe because the type we are claiming to have initialized here is a +/// // bunch of `MaybeUninit`s, which do not require initialization. +/// let mut data: [MaybeUninit; 1000] = MaybeUninit::uninit().assume_init(); +/// // Count the number of elements we have assigned. +/// let mut data_len: usize = 0; +/// +/// for elem in &mut data[0..500] { +/// ptr::write(elem.as_mut_ptr(), String::from("hello")); +/// data_len += 1; +/// } +/// +/// // For each item in the array, drop if we allocated it. +/// for elem in &mut data[0..data_len] { +/// ptr::drop_in_place(elem.as_mut_ptr()); +/// } +/// } +/// ``` +/// +/// ## Initializing a struct field-by-field +/// +/// There is unfortunately currently no supported way to create a raw pointer or reference +/// to a field of a struct inside `MaybeUninit`. That means it is not possible +/// to create a struct by calling `MaybeUninit::uninit::()` and then writing +/// to its fields. +/// +/// [ub]: ../../reference/behavior-considered-undefined.html #[allow(missing_debug_implementations)] -#[unstable(feature = "maybe_uninit", issue = "53491")] +#[stable(feature = "maybe_uninit", since = "1.36.0")] #[derive(Copy)] -// NOTE: after stabilizing `MaybeUninit`, proceed to deprecate `mem::uninitialized`. pub union MaybeUninit { uninit: (), value: ManuallyDrop, } -#[unstable(feature = "maybe_uninit", issue = "53491")] +#[stable(feature = "maybe_uninit", since = "1.36.0")] impl Clone for MaybeUninit { #[inline(always)] fn clone(&self) -> Self { @@ -1132,10 +1096,13 @@ impl Clone for MaybeUninit { impl MaybeUninit { /// Creates a new `MaybeUninit` initialized with the given value. + /// It is safe to call [`assume_init`] on the return value of this function. /// /// Note that dropping a `MaybeUninit` will never call `T`'s drop code. /// It is your responsibility to make sure `T` gets dropped if it got initialized. - #[unstable(feature = "maybe_uninit", issue = "53491")] + /// + /// [`assume_init`]: #method.assume_init + #[stable(feature = "maybe_uninit", since = "1.36.0")] #[inline(always)] pub const fn new(val: T) -> MaybeUninit { MaybeUninit { value: ManuallyDrop::new(val) } @@ -1145,7 +1112,11 @@ impl MaybeUninit { /// /// Note that dropping a `MaybeUninit` will never call `T`'s drop code. /// It is your responsibility to make sure `T` gets dropped if it got initialized. - #[unstable(feature = "maybe_uninit", issue = "53491")] + /// + /// See the [type-level documentation][type] for some examples. + /// + /// [type]: union.MaybeUninit.html + #[stable(feature = "maybe_uninit", since = "1.36.0")] #[inline(always)] pub const fn uninit() -> MaybeUninit { MaybeUninit { uninit: () } @@ -1166,7 +1137,6 @@ impl MaybeUninit { /// fields of the struct can hold the bit-pattern 0 as a valid value. /// /// ```rust - /// #![feature(maybe_uninit)] /// use std::mem::MaybeUninit; /// /// let x = MaybeUninit::<(u8, bool)>::zeroed(); @@ -1178,7 +1148,6 @@ impl MaybeUninit { /// cannot hold 0 as a valid value. /// /// ```rust,no_run - /// #![feature(maybe_uninit)] /// use std::mem::MaybeUninit; /// /// enum NotZero { One = 1, Two = 2 }; @@ -1188,7 +1157,7 @@ impl MaybeUninit { /// // Inside a pair, we create a `NotZero` that does not have a valid discriminant. /// // This is undefined behavior. /// ``` - #[unstable(feature = "maybe_uninit", issue = "53491")] + #[stable(feature = "maybe_uninit", since = "1.36.0")] #[inline] pub fn zeroed() -> MaybeUninit { let mut u = MaybeUninit::::uninit(); @@ -1202,7 +1171,7 @@ impl MaybeUninit { /// without dropping it, so be careful not to use this twice unless you want to /// skip running the destructor. For your convenience, this also returns a mutable /// reference to the (now safely initialized) contents of `self`. - #[unstable(feature = "maybe_uninit", issue = "53491")] + #[unstable(feature = "maybe_uninit_extra", issue = "53491")] #[inline(always)] pub fn write(&mut self, val: T) -> &mut T { unsafe { @@ -1213,13 +1182,14 @@ impl MaybeUninit { /// Gets a pointer to the contained value. Reading from this pointer or turning it /// into a reference is undefined behavior unless the `MaybeUninit` is initialized. + /// Writing to memory that this pointer (non-transitively) points to is undefined behavior + /// (except inside an `UnsafeCell`). /// /// # Examples /// /// Correct usage of this method: /// /// ```rust - /// #![feature(maybe_uninit)] /// use std::mem::MaybeUninit; /// /// let mut x = MaybeUninit::>::uninit(); @@ -1232,7 +1202,6 @@ impl MaybeUninit { /// *Incorrect* usage of this method: /// /// ```rust,no_run - /// #![feature(maybe_uninit)] /// use std::mem::MaybeUninit; /// /// let x = MaybeUninit::>::uninit(); @@ -1242,7 +1211,7 @@ impl MaybeUninit { /// /// (Notice that the rules around references to uninitialized data are not finalized yet, but /// until they are, it is advisable to avoid them.) - #[unstable(feature = "maybe_uninit", issue = "53491")] + #[stable(feature = "maybe_uninit", since = "1.36.0")] #[inline(always)] pub fn as_ptr(&self) -> *const T { unsafe { &*self.value as *const T } @@ -1256,7 +1225,6 @@ impl MaybeUninit { /// Correct usage of this method: /// /// ```rust - /// #![feature(maybe_uninit)] /// use std::mem::MaybeUninit; /// /// let mut x = MaybeUninit::>::uninit(); @@ -1271,7 +1239,6 @@ impl MaybeUninit { /// *Incorrect* usage of this method: /// /// ```rust,no_run - /// #![feature(maybe_uninit)] /// use std::mem::MaybeUninit; /// /// let mut x = MaybeUninit::>::uninit(); @@ -1281,7 +1248,7 @@ impl MaybeUninit { /// /// (Notice that the rules around references to uninitialized data are not finalized yet, but /// until they are, it is advisable to avoid them.) - #[unstable(feature = "maybe_uninit", issue = "53491")] + #[stable(feature = "maybe_uninit", since = "1.36.0")] #[inline(always)] pub fn as_mut_ptr(&mut self) -> *mut T { unsafe { &mut *self.value as *mut T } @@ -1294,15 +1261,17 @@ impl MaybeUninit { /// # Safety /// /// It is up to the caller to guarantee that the `MaybeUninit` really is in an initialized - /// state. Calling this when the content is not yet fully initialized causes undefined - /// behavior. + /// state. Calling this when the content is not yet fully initialized causes immediate undefined + /// behavior. The [type-level documentation][inv] contains more information about + /// this initialization invariant. + /// + /// [inv]: #initialization-invariant /// /// # Examples /// /// Correct usage of this method: /// /// ```rust - /// #![feature(maybe_uninit)] /// use std::mem::MaybeUninit; /// /// let mut x = MaybeUninit::::uninit(); @@ -1314,14 +1283,13 @@ impl MaybeUninit { /// *Incorrect* usage of this method: /// /// ```rust,no_run - /// #![feature(maybe_uninit)] /// use std::mem::MaybeUninit; /// /// let x = MaybeUninit::>::uninit(); /// let x_init = unsafe { x.assume_init() }; /// // `x` had not been initialized yet, so this last line caused undefined behavior. /// ``` - #[unstable(feature = "maybe_uninit", issue = "53491")] + #[stable(feature = "maybe_uninit", since = "1.36.0")] #[inline(always)] pub unsafe fn assume_init(self) -> T { intrinsics::panic_if_uninhabited::(); @@ -1338,13 +1306,15 @@ impl MaybeUninit { /// /// It is up to the caller to guarantee that the `MaybeUninit` really is in an initialized /// state. Calling this when the content is not yet fully initialized causes undefined - /// behavior. + /// behavior. The [type-level documentation][inv] contains more information about + /// this initialization invariant. /// /// Moreover, this leaves a copy of the same data behind in the `MaybeUninit`. When using /// multiple copies of the data (by calling `read` multiple times, or first /// calling `read` and then [`assume_init`]), it is your responsibility /// to ensure that that data may indeed be duplicated. /// + /// [inv]: #initialization-invariant /// [`assume_init`]: #method.assume_init /// /// # Examples @@ -1352,7 +1322,7 @@ impl MaybeUninit { /// Correct usage of this method: /// /// ```rust - /// #![feature(maybe_uninit)] + /// #![feature(maybe_uninit_extra)] /// use std::mem::MaybeUninit; /// /// let mut x = MaybeUninit::::uninit(); @@ -1373,7 +1343,7 @@ impl MaybeUninit { /// *Incorrect* usage of this method: /// /// ```rust,no_run - /// #![feature(maybe_uninit)] + /// #![feature(maybe_uninit_extra)] /// use std::mem::MaybeUninit; /// /// let mut x = MaybeUninit::>>::uninit(); @@ -1383,7 +1353,7 @@ impl MaybeUninit { /// // We now created two copies of the same vector, leading to a double-free when /// // they both get dropped! /// ``` - #[unstable(feature = "maybe_uninit", issue = "53491")] + #[unstable(feature = "maybe_uninit_extra", issue = "53491")] #[inline(always)] pub unsafe fn read(&self) -> T { intrinsics::panic_if_uninhabited::(); diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 2401946536f..e044b46e0d0 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -272,7 +272,6 @@ #![feature(libc)] #![feature(link_args)] #![feature(linkage)] -#![feature(maybe_uninit)] #![feature(needs_panic_runtime)] #![feature(never_type)] #![feature(nll)] diff --git a/src/test/codegen/box-maybe-uninit.rs b/src/test/codegen/box-maybe-uninit.rs index 0dd67bb95cc..5004f787cde 100644 --- a/src/test/codegen/box-maybe-uninit.rs +++ b/src/test/codegen/box-maybe-uninit.rs @@ -1,6 +1,5 @@ // compile-flags: -O #![crate_type="lib"] -#![feature(maybe_uninit)] use std::mem::MaybeUninit; diff --git a/src/test/run-pass/panic-uninitialized-zeroed.rs b/src/test/run-pass/panic-uninitialized-zeroed.rs index 3f6e489bb83..4ca4b407bd4 100644 --- a/src/test/run-pass/panic-uninitialized-zeroed.rs +++ b/src/test/run-pass/panic-uninitialized-zeroed.rs @@ -2,7 +2,7 @@ // This test checks that instantiating an uninhabited type via `mem::{uninitialized,zeroed}` results // in a runtime panic. -#![feature(never_type, maybe_uninit)] +#![feature(never_type)] use std::{mem, panic}; -- cgit 1.4.1-3-g733a5 From a7e1431941406eeb341c4e3b7e929c2e65514ac3 Mon Sep 17 00:00:00 2001 From: Brent Kerby Date: Sun, 19 May 2019 09:21:03 -0600 Subject: Update boxed::Box docs on memory layout --- src/liballoc/boxed.rs | 59 +++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 45 insertions(+), 14 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 207359ed696..90bec03beb0 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -127,24 +127,38 @@ impl Box { /// /// After calling this function, the raw pointer is owned by the /// resulting `Box`. Specifically, the `Box` destructor will call - /// the destructor of `T` and free the allocated memory. Since the - /// way `Box` allocates and releases memory is unspecified, the - /// only valid pointer to pass to this function is the one taken - /// from another `Box` via the [`Box::into_raw`] function. + /// the destructor of `T` and free the allocated memory. For this + /// to be safe, the memory must have been allocated in the precise + /// way that `Box` expects, namely, using the global allocator + /// with the correct [`Layout`] for holding a value of type `T`. In + /// particular, this will be satisfied for a pointer obtained + /// from a previously existing `Box` using [`Box::into_raw`]. + /// + /// # Safety /// /// This function is unsafe because improper use may lead to /// memory problems. For example, a double-free may occur if the /// function is called twice on the same raw pointer. /// - /// [`Box::into_raw`]: struct.Box.html#method.into_raw - /// /// # Examples - /// + /// Recreate a `Box` which was previously converted to a raw pointer using [`Box::into_raw`]: /// ``` /// let x = Box::new(5); /// let ptr = Box::into_raw(x); /// let x = unsafe { Box::from_raw(ptr) }; /// ``` + /// Manually create a `Box` from scratch by using the global allocator: + /// ``` + /// use std::alloc::{Layout, alloc}; + /// + /// let ptr = unsafe{ alloc(Layout::new::()) } as *mut i32; + /// unsafe{ *ptr = 5; } + /// let x = unsafe{ Box::from_raw(ptr) }; + /// ``` + /// + /// [`Layout`]: ../alloc/struct.Layout.html + /// [`Box::into_raw`]: struct.Box.html#method.into_raw + /// #[stable(feature = "box_raw", since = "1.4.0")] #[inline] pub unsafe fn from_raw(raw: *mut T) -> Self { @@ -158,21 +172,34 @@ impl Box { /// After calling this function, the caller is responsible for the /// memory previously managed by the `Box`. In particular, the /// caller should properly destroy `T` and release the memory. The - /// proper way to do so is to convert the raw pointer back into a - /// `Box` with the [`Box::from_raw`] function. + /// easiest way to do so is to convert the raw pointer back into a `Box` + /// with the [`Box::from_raw`] function. /// /// Note: this is an associated function, which means that you have /// to call it as `Box::into_raw(b)` instead of `b.into_raw()`. This /// is so that there is no conflict with a method on the inner type. /// - /// [`Box::from_raw`]: struct.Box.html#method.from_raw - /// /// # Examples - /// + /// Converting the raw pointer back into a `Box` with [`Box::from_raw`] + /// for automatic cleanup: /// ``` - /// let x = Box::new(5); + /// let x = Box::new(String::from("Hello")); /// let ptr = Box::into_raw(x); + /// let x = unsafe{ Box::from_raw(ptr) }; + /// ``` + /// Manual cleanup by running the destructor and deallocating the memory: /// ``` + /// use std::alloc::{Layout, dealloc}; + /// use std::ptr; + /// + /// let x = Box::new(String::from("Hello")); + /// let p = Box::into_raw(x); + /// unsafe{ ptr::drop_in_place(p); } + /// unsafe{ dealloc(p as *mut u8, Layout::new::()); } + /// ``` + /// + /// [`Box::from_raw`]: struct.Box.html#method.from_raw + /// #[stable(feature = "box_raw", since = "1.4.0")] #[inline] pub fn into_raw(b: Box) -> *mut T { @@ -184,7 +211,7 @@ impl Box { /// After calling this function, the caller is responsible for the /// memory previously managed by the `Box`. In particular, the /// caller should properly destroy `T` and release the memory. The - /// proper way to do so is to convert the `NonNull` pointer + /// easiest way to do so is to convert the `NonNull` pointer /// into a raw pointer and back into a `Box` with the [`Box::from_raw`] /// function. /// @@ -203,6 +230,10 @@ impl Box { /// fn main() { /// let x = Box::new(5); /// let ptr = Box::into_raw_non_null(x); + /// + /// // Clean up the memory by converting the NonNull pointer back + /// // into a Box and letting the Box be dropped. + /// let x = unsafe{ Box::from_raw(ptr.as_ptr()) }; /// } /// ``` #[unstable(feature = "box_into_raw_non_null", issue = "47336")] -- cgit 1.4.1-3-g733a5 From 178b753a4a202ad96ccbd10e037194d15ca8f805 Mon Sep 17 00:00:00 2001 From: Brent Kerby Date: Sun, 19 May 2019 17:47:18 -0600 Subject: Remove trailing whitespaces to satisfy tidy --- src/liballoc/boxed.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 90bec03beb0..4e712a946b8 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -130,9 +130,9 @@ impl Box { /// the destructor of `T` and free the allocated memory. For this /// to be safe, the memory must have been allocated in the precise /// way that `Box` expects, namely, using the global allocator - /// with the correct [`Layout`] for holding a value of type `T`. In + /// with the correct [`Layout`] for holding a value of type `T`. In /// particular, this will be satisfied for a pointer obtained - /// from a previously existing `Box` using [`Box::into_raw`]. + /// from a previously existing `Box` using [`Box::into_raw`]. /// /// # Safety /// @@ -172,7 +172,7 @@ impl Box { /// After calling this function, the caller is responsible for the /// memory previously managed by the `Box`. In particular, the /// caller should properly destroy `T` and release the memory. The - /// easiest way to do so is to convert the raw pointer back into a `Box` + /// easiest way to do so is to convert the raw pointer back into a `Box` /// with the [`Box::from_raw`] function. /// /// Note: this is an associated function, which means that you have @@ -180,7 +180,7 @@ impl Box { /// is so that there is no conflict with a method on the inner type. /// /// # Examples - /// Converting the raw pointer back into a `Box` with [`Box::from_raw`] + /// Converting the raw pointer back into a `Box` with [`Box::from_raw`] /// for automatic cleanup: /// ``` /// let x = Box::new(String::from("Hello")); @@ -191,7 +191,7 @@ impl Box { /// ``` /// use std::alloc::{Layout, dealloc}; /// use std::ptr; - /// + /// /// let x = Box::new(String::from("Hello")); /// let p = Box::into_raw(x); /// unsafe{ ptr::drop_in_place(p); } -- cgit 1.4.1-3-g733a5 From 9f800457dda7ee9b8579394d1c07761f3008e573 Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Tue, 26 Mar 2019 17:34:32 +0000 Subject: Ban multi-trait objects via trait aliases. --- src/liballoc/slice.rs | 8 +- src/librustc/hir/map/mod.rs | 2 +- src/librustc/hir/mod.rs | 8 +- src/librustc/infer/outlives/verify.rs | 4 +- src/librustc/traits/mod.rs | 3 +- src/librustc/traits/select.rs | 3 +- src/librustc/traits/util.rs | 215 +++++++++++++++++++++-------- src/librustc/ty/mod.rs | 4 +- src/librustc_save_analysis/dump_visitor.rs | 6 +- src/librustc_typeck/astconv.rs | 87 +++++------- src/librustc_typeck/check/method/probe.rs | 2 +- src/librustc_typeck/check/wfcheck.rs | 2 +- src/libsyntax/ast.rs | 4 +- 13 files changed, 215 insertions(+), 133 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index 6eac8487401..8768f1ff081 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -123,12 +123,12 @@ pub use core::slice::{RChunks, RChunksMut, RChunksExact, RChunksExactMut}; //////////////////////////////////////////////////////////////////////////////// // HACK(japaric) needed for the implementation of `vec!` macro during testing -// NB see the hack module in this file for more details +// N.B., see the `hack` module in this file for more details. #[cfg(test)] pub use hack::into_vec; // HACK(japaric) needed for the implementation of `Vec::clone` during testing -// NB see the hack module in this file for more details +// N.B., see the `hack` module in this file for more details. #[cfg(test)] pub use hack::to_vec; @@ -376,7 +376,7 @@ impl [T] { pub fn to_vec(&self) -> Vec where T: Clone { - // NB see hack module in this file + // N.B., see the `hack` module in this file for more details. hack::to_vec(self) } @@ -397,7 +397,7 @@ impl [T] { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn into_vec(self: Box) -> Vec { - // NB see hack module in this file + // N.B., see the `hack` module in this file for more details. hack::into_vec(self) } diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 4b94f772554..23f4d208571 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -957,7 +957,7 @@ impl<'hir> Map<'hir> { } } - /// Returns the name associated with the given NodeId's AST. + /// Returns the name associated with the given `NodeId`'s AST. pub fn name(&self, id: NodeId) -> Name { let hir_id = self.node_to_hir_id(id); self.name_by_hir_id(hir_id) diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 22312e7459b..fafe1cf85a3 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -2143,11 +2143,11 @@ pub enum UseKind { ListStem, } -/// TraitRef's appear in impls. +/// `TraitRef` are references to traits in impls. /// -/// resolve maps each TraitRef's ref_id to its defining trait; that's all -/// that the ref_id is for. Note that ref_id's value is not the NodeId of the -/// trait being referred to but just a unique NodeId that serves as a key +/// `resolve` maps each `TraitRef`'s `ref_id` to its defining trait; that's all +/// that the `ref_id` is for. Note that `ref_id`'s value is not the `NodeId` of the +/// trait being referred to but just a unique `NodeId` that serves as a key /// within the resolution map. #[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct TraitRef { diff --git a/src/librustc/infer/outlives/verify.rs b/src/librustc/infer/outlives/verify.rs index e1ad5aeea19..5b8d89c865a 100644 --- a/src/librustc/infer/outlives/verify.rs +++ b/src/librustc/infer/outlives/verify.rs @@ -141,9 +141,9 @@ impl<'cx, 'gcx, 'tcx> VerifyBoundCx<'cx, 'gcx, 'tcx> { } fn recursive_type_bound(&self, ty: Ty<'tcx>) -> VerifyBound<'tcx> { - let mut bounds = ty.walk_shallow() + let mut bounds: Vec<_> = ty.walk_shallow() .map(|subty| self.type_bound(subty)) - .collect::>(); + .collect(); let mut regions = smallvec![]; ty.push_regions(&mut regions); diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index 846924fb591..627f923399b 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -62,6 +62,7 @@ pub use self::engine::{TraitEngine, TraitEngineExt}; pub use self::util::{elaborate_predicates, elaborate_trait_ref, elaborate_trait_refs}; pub use self::util::{supertraits, supertrait_def_ids, transitive_bounds, Supertraits, SupertraitDefIds}; +pub use self::util::{expand_trait_refs, TraitRefExpander}; pub use self::chalk_fulfill::{ CanonicalGoal as ChalkCanonicalGoal, @@ -1043,7 +1044,7 @@ fn vtable_methods<'a, 'tcx>( ) } -impl<'tcx,O> Obligation<'tcx,O> { +impl<'tcx, O> Obligation<'tcx,O> { pub fn new(cause: ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, predicate: O) diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index c4be85050db..ec5e127a5ec 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -1772,7 +1772,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { bounds ); - let matching_bound = util::elaborate_predicates(self.tcx(), bounds.predicates) + let elaborated_predicates = util::elaborate_predicates(self.tcx(), bounds.predicates); + let matching_bound = elaborated_predicates .filter_to_traits() .find(|bound| { self.infcx.probe(|_| { diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs index 578d8bbedf3..897681e538e 100644 --- a/src/librustc/traits/util.rs +++ b/src/librustc/traits/util.rs @@ -1,3 +1,5 @@ +use syntax_pos::Span; + use crate::hir; use crate::hir::def_id::DefId; use crate::traits::specialize::specialization_graph::NodeItem; @@ -41,7 +43,6 @@ fn anonymize_predicate<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, } } - struct PredicateSet<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { tcx: TyCtxt<'a, 'gcx, 'tcx>, set: FxHashSet>, @@ -73,12 +74,11 @@ impl<'a, 'gcx, 'tcx> PredicateSet<'a, 'gcx, 'tcx> { /// "Elaboration" is the process of identifying all the predicates that /// are implied by a source predicate. Currently this basically means -/// walking the "supertraits" and other similar assumptions. For -/// example, if we know that `T : Ord`, the elaborator would deduce -/// that `T : PartialOrd` holds as well. Similarly, if we have `trait -/// Foo : 'static`, and we know that `T : Foo`, then we know that `T : -/// 'static`. -pub struct Elaborator<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { +/// walking the "supertraits" and other similar assumptions. For example, +/// if we know that `T: Ord`, the elaborator would deduce that `T: PartialOrd` +/// holds as well. Similarly, if we have `trait Foo: 'static`, and we know that +/// `T: Foo`, then we know that `T: 'static`. +pub struct Elaborator<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { stack: Vec>, visited: PredicateSet<'a, 'gcx, 'tcx>, } @@ -96,8 +96,7 @@ pub fn elaborate_trait_refs<'cx, 'gcx, 'tcx>( trait_refs: impl Iterator>) -> Elaborator<'cx, 'gcx, 'tcx> { - let predicates = trait_refs.map(|trait_ref| trait_ref.to_predicate()) - .collect(); + let predicates = trait_refs.map(|trait_ref| trait_ref.to_predicate()).collect(); elaborate_predicates(tcx, predicates) } @@ -120,7 +119,7 @@ impl<'cx, 'gcx, 'tcx> Elaborator<'cx, 'gcx, 'tcx> { let tcx = self.visited.tcx; match *predicate { ty::Predicate::Trait(ref data) => { - // Predicates declared on the trait. + // Get predicates declared on the trait. let predicates = tcx.super_predicates_of(data.def_id()); let mut predicates: Vec<_> = predicates.predicates @@ -130,12 +129,11 @@ impl<'cx, 'gcx, 'tcx> Elaborator<'cx, 'gcx, 'tcx> { debug!("super_predicates: data={:?} predicates={:?}", data, predicates); - // Only keep those bounds that we haven't already - // seen. This is necessary to prevent infinite - // recursion in some cases. One common case is when - // people define `trait Sized: Sized { }` rather than `trait - // Sized { }`. - predicates.retain(|r| self.visited.insert(r)); + // Only keep those bounds that we haven't already seen. + // This is necessary to prevent infinite recursion in some + // cases. One common case is when people define + // `trait Sized: Sized { }` rather than `trait Sized { }`. + predicates.retain(|p| self.visited.insert(p)); self.stack.extend(predicates); } @@ -161,11 +159,9 @@ impl<'cx, 'gcx, 'tcx> Elaborator<'cx, 'gcx, 'tcx> { // Currently, we do not elaborate const-evaluatable // predicates. } - ty::Predicate::RegionOutlives(..) => { // Nothing to elaborate from `'a: 'b`. } - ty::Predicate::TypeOutlives(ref data) => { // We know that `T: 'a` for some type `T`. We can // often elaborate this. For example, if we know that @@ -192,34 +188,35 @@ impl<'cx, 'gcx, 'tcx> Elaborator<'cx, 'gcx, 'tcx> { tcx.push_outlives_components(ty_max, &mut components); self.stack.extend( components - .into_iter() - .filter_map(|component| match component { - Component::Region(r) => if r.is_late_bound() { - None - } else { - Some(ty::Predicate::RegionOutlives( - ty::Binder::dummy(ty::OutlivesPredicate(r, r_min)))) - }, - - Component::Param(p) => { - let ty = tcx.mk_ty_param(p.index, p.name); - Some(ty::Predicate::TypeOutlives( - ty::Binder::dummy(ty::OutlivesPredicate(ty, r_min)))) - }, - - Component::UnresolvedInferenceVariable(_) => { - None - }, - - Component::Projection(_) | - Component::EscapingProjection(_) => { - // We can probably do more here. This - // corresponds to a case like `>::U: 'b`. - None - }, - }) - .filter(|p| visited.insert(p))); + .into_iter() + .filter_map(|component| match component { + Component::Region(r) => if r.is_late_bound() { + None + } else { + Some(ty::Predicate::RegionOutlives( + ty::Binder::dummy(ty::OutlivesPredicate(r, r_min)))) + } + + Component::Param(p) => { + let ty = tcx.mk_ty_param(p.index, p.name); + Some(ty::Predicate::TypeOutlives( + ty::Binder::dummy(ty::OutlivesPredicate(ty, r_min)))) + } + + Component::UnresolvedInferenceVariable(_) => { + None + } + + Component::Projection(_) | + Component::EscapingProjection(_) => { + // We can probably do more here. This + // corresponds to a case like `>::U: 'b`. + None + } + }) + .filter(|p| visited.insert(p)) + ); } } } @@ -233,16 +230,10 @@ impl<'cx, 'gcx, 'tcx> Iterator for Elaborator<'cx, 'gcx, 'tcx> { } fn next(&mut self) -> Option> { - // Extract next item from top-most stack frame, if any. - let next_predicate = match self.stack.pop() { - Some(predicate) => predicate, - None => { - // No more stack frames. Done. - return None; - } - }; - self.push(&next_predicate); - return Some(next_predicate); + self.stack.pop().map(|item| { + self.push(&item); + item + }) } } @@ -254,20 +245,124 @@ pub type Supertraits<'cx, 'gcx, 'tcx> = FilterToTraits(tcx: TyCtxt<'cx, 'gcx, 'tcx>, trait_ref: ty::PolyTraitRef<'tcx>) - -> Supertraits<'cx, 'gcx, 'tcx> -{ + -> Supertraits<'cx, 'gcx, 'tcx> { elaborate_trait_ref(tcx, trait_ref).filter_to_traits() } pub fn transitive_bounds<'cx, 'gcx, 'tcx>(tcx: TyCtxt<'cx, 'gcx, 'tcx>, bounds: impl Iterator>) - -> Supertraits<'cx, 'gcx, 'tcx> -{ + -> Supertraits<'cx, 'gcx, 'tcx> { elaborate_trait_refs(tcx, bounds).filter_to_traits() } +/////////////////////////////////////////////////////////////////////////// +// `TraitRefExpander` iterator +/////////////////////////////////////////////////////////////////////////// + +/// "Trait reference expansion" is the process of expanding a sequence of trait +/// references into another sequence by transitively following all trait +/// aliases. e.g. If you have bounds like `Foo + Send`, a trait alias +/// `trait Foo = Bar + Sync;`, and another trait alias +/// `trait Bar = Read + Write`, then the bounds would expand to +/// `Read + Write + Sync + Send`. +pub struct TraitRefExpander<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { + stack: Vec>, + visited: PredicateSet<'a, 'gcx, 'tcx>, +} + +#[derive(Debug, Clone)] +pub struct TraitRefExpansionInfo<'tcx> { + pub top_level_trait_ref: ty::PolyTraitRef<'tcx>, + pub top_level_span: Span, + pub trait_ref: ty::PolyTraitRef<'tcx>, + pub span: Span, +} + +pub fn expand_trait_refs<'cx, 'gcx, 'tcx>( + tcx: TyCtxt<'cx, 'gcx, 'tcx>, + trait_refs: impl IntoIterator, Span)> +) -> TraitRefExpander<'cx, 'gcx, 'tcx> { + let mut visited = PredicateSet::new(tcx); + let mut items: Vec<_> = + trait_refs + .into_iter() + .map(|(tr, sp)| TraitRefExpansionInfo { + top_level_trait_ref: tr.clone(), + top_level_span: sp, + trait_ref: tr, + span: sp, + }) + .collect(); + items.retain(|item| visited.insert(&item.trait_ref.to_predicate())); + TraitRefExpander { stack: items, visited: visited, } +} + +impl<'cx, 'gcx, 'tcx> TraitRefExpander<'cx, 'gcx, 'tcx> { + // Returns `true` if `item` refers to a trait. + fn push(&mut self, item: &TraitRefExpansionInfo<'tcx>) -> bool { + let tcx = self.visited.tcx; + + if !tcx.is_trait_alias(item.trait_ref.def_id()) { + return true; + } + + // Get predicates declared on the trait. + let predicates = tcx.super_predicates_of(item.trait_ref.def_id()); + + let mut items: Vec<_> = predicates.predicates + .iter() + .rev() + .filter_map(|(pred, sp)| { + pred.subst_supertrait(tcx, &item.trait_ref) + .to_opt_poly_trait_ref() + .map(|trait_ref| + TraitRefExpansionInfo { + trait_ref, + span: *sp, + ..*item + } + ) + }) + .collect(); + + debug!("expand_trait_refs: trait_ref={:?} items={:?}", + item.trait_ref, items); + + // Only keep those items that we haven't already seen. + items.retain(|i| self.visited.insert(&i.trait_ref.to_predicate())); + + self.stack.extend(items); + false + } +} + +impl<'cx, 'gcx, 'tcx> Iterator for TraitRefExpander<'cx, 'gcx, 'tcx> { + type Item = TraitRefExpansionInfo<'tcx>; + + fn size_hint(&self) -> (usize, Option) { + (self.stack.len(), None) + } + + fn next(&mut self) -> Option> { + loop { + let item = self.stack.pop(); + match item { + Some(item) => { + if self.push(&item) { + return Some(item); + } + } + None => { + return None; + } + } + } + } +} + /////////////////////////////////////////////////////////////////////////// // Iterator over def-ids of supertraits +/////////////////////////////////////////////////////////////////////////// pub struct SupertraitDefIds<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { tcx: TyCtxt<'a, 'gcx, 'tcx>, diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index c55e508c8b5..6020a737853 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1234,7 +1234,7 @@ impl<'tcx> TraitPredicate<'tcx> { self.trait_ref.def_id } - pub fn input_types<'a>(&'a self) -> impl DoubleEndedIterator> + 'a { + pub fn input_types<'a>(&'a self) -> impl DoubleEndedIterator> + 'a { self.trait_ref.input_types() } @@ -2400,7 +2400,7 @@ impl<'a, 'gcx, 'tcx> AdtDef { pub fn discriminants( &'a self, tcx: TyCtxt<'a, 'gcx, 'tcx>, - ) -> impl Iterator)> + Captures<'gcx> + 'a { + ) -> impl Iterator)> + Captures<'gcx> + 'a { let repr_type = self.repr.discr_type(); let initial = repr_type.initial_discriminant(tcx.global_tcx()); let mut prev_discr = None::>; diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 1e65f868eba..5f184bf4a7d 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -1177,13 +1177,13 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { ); } ast::ImplItemKind::Type(ref ty) => { - // FIXME uses of the assoc type should ideally point to this + // FIXME: uses of the assoc type should ideally point to this // 'def' and the name here should be a ref to the def in the // trait. self.visit_ty(ty) } ast::ImplItemKind::Existential(ref bounds) => { - // FIXME uses of the assoc type should ideally point to this + // FIXME: uses of the assoc type should ideally point to this // 'def' and the name here should be a ref to the def in the // trait. for bound in bounds.iter() { @@ -1216,7 +1216,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { let hir_id = self.tcx.hir().node_to_hir_id(id); let access = access_from!(self.save_ctxt, root_item, hir_id); - // The parent def id of a given use tree is always the enclosing item. + // The parent def-ID of a given use tree is always the enclosing item. let parent = self.save_ctxt.tcx.hir().opt_local_def_id(id) .and_then(|id| self.save_ctxt.tcx.parent(id)) .map(id_from_def_id); diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 06605695630..fc6edc2627b 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -975,12 +975,13 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { if trait_bounds.is_empty() { span_err!(tcx.sess, span, E0224, - "at least one non-builtin trait is required for an object type"); + "at least one non-builtin trait is required for an object type"); return tcx.types.err; } let mut projection_bounds = Vec::new(); let dummy_self = self.tcx().types.trait_object_dummy_self; + let mut bound_trait_refs = Vec::with_capacity(trait_bounds.len()); let (principal, potential_assoc_types) = self.instantiate_poly_trait_ref( &trait_bounds[0], dummy_self, @@ -988,22 +989,29 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { ); debug!("principal: {:?}", principal); - for trait_bound in trait_bounds[1..].iter() { - // sanity check for non-principal trait bounds - self.instantiate_poly_trait_ref(trait_bound, - dummy_self, - &mut vec![]); + for trait_bound in trait_bounds[1..].iter().rev() { + // Sanity check for non-principal trait bounds. + let (tr, _) = self.instantiate_poly_trait_ref( + trait_bound, + dummy_self, + &mut Vec::new() + ); + bound_trait_refs.push((tr, trait_bound.span)); } - - let (mut auto_traits, trait_bounds) = split_auto_traits(tcx, &trait_bounds[1..]); - - if !trait_bounds.is_empty() { - let b = &trait_bounds[0]; - let span = b.trait_ref.path.span; - struct_span_err!(self.tcx().sess, span, E0225, - "only auto traits can be used as additional traits in a trait object") - .span_label(span, "non-auto additional trait") - .emit(); + bound_trait_refs.push((principal, trait_bounds[0].span)); + + let expanded_traits = traits::expand_trait_refs(tcx, bound_trait_refs); + let (auto_traits, regular_traits): (Vec<_>, Vec<_>) = + expanded_traits.partition(|i| tcx.trait_is_auto(i.trait_ref.def_id())); + if regular_traits.len() > 1 { + let extra_trait = ®ular_traits[1]; + let mut err = struct_span_err!(tcx.sess, extra_trait.top_level_span, E0225, + "only auto traits can be used as additional traits in a trait object"); + err.span_label(extra_trait.span, "non-auto additional trait"); + if extra_trait.span != extra_trait.top_level_span { + err.span_label(extra_trait.top_level_span, "expanded from this alias"); + } + err.emit(); } // Check that there are no gross object safety violations; @@ -1024,9 +1032,10 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { debug!("conv_object_ty_poly_trait_ref: observing object predicate `{:?}`", tr); match tr { ty::Predicate::Trait(pred) => { - associated_types.extend(tcx.associated_items(pred.def_id()) - .filter(|item| item.kind == ty::AssociatedKind::Type) - .map(|item| item.def_id)); + associated_types + .extend(tcx.associated_items(pred.def_id()) + .filter(|item| item.kind == ty::AssociatedKind::Type) + .map(|item| item.def_id)); } ty::Predicate::Projection(pred) => { // A `Self` within the original bound will be substituted with a @@ -1145,11 +1154,15 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { }) }); - // Dedup auto traits so that `dyn Trait + Send + Send` is the same as `dyn Trait + Send`. + // De-duplicate auto traits so that, e.g., `dyn Trait + Send + Send` is the same as + // `dyn Trait + Send`. + let mut auto_traits: Vec<_> = + auto_traits.into_iter().map(|i| i.trait_ref.def_id()).collect(); auto_traits.sort(); auto_traits.dedup(); + debug!("auto_traits: {:?}", auto_traits); - // Calling `skip_binder` is okay, because the predicates are re-bound. + // Calling `skip_binder` is okay because the predicates are re-bound. let principal = if tcx.trait_is_auto(existential_principal.def_id()) { ty::ExistentialPredicate::AutoTrait(existential_principal.def_id()) } else { @@ -1175,14 +1188,13 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { } else { self.re_infer(span, None).unwrap_or_else(|| { span_err!(tcx.sess, span, E0228, - "the lifetime bound for this object type cannot be deduced \ - from context; please supply an explicit bound"); + "the lifetime bound for this object type cannot be deduced \ + from context; please supply an explicit bound"); tcx.lifetimes.re_static }) } }) }; - debug!("region_bound: {:?}", region_bound); let ty = tcx.mk_dynamic(existential_predicates, region_bound); @@ -2097,33 +2109,6 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { } } -/// Divides a list of general trait bounds into two groups: auto traits (e.g., Sync and Send) and -/// the remaining general trait bounds. -fn split_auto_traits<'a, 'b, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, - trait_bounds: &'b [hir::PolyTraitRef]) - -> (Vec, Vec<&'b hir::PolyTraitRef>) -{ - let (auto_traits, trait_bounds): (Vec<_>, _) = trait_bounds.iter().partition(|bound| { - // Checks whether `trait_did` is an auto trait and adds it to `auto_traits` if so. - match bound.trait_ref.path.res { - Res::Def(DefKind::Trait, trait_did) if tcx.trait_is_auto(trait_did) => { - true - } - _ => false - } - }); - - let auto_traits = auto_traits.into_iter().map(|tr| { - if let Res::Def(DefKind::Trait, trait_did) = tr.trait_ref.path.res { - trait_did - } else { - unreachable!() - } - }).collect::>(); - - (auto_traits, trait_bounds) -} - // A helper struct for conveniently grouping a set of bounds which we pass to // and return from functions in multiple places. #[derive(PartialEq, Eq, Clone, Debug)] diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 251400e65f3..590ae9d46e8 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -758,7 +758,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { } fn assemble_inherent_candidates_from_param(&mut self, param_ty: ty::ParamTy) { - // FIXME -- Do we want to commit to this behavior for param bounds? + // FIXME: do we want to commit to this behavior for param bounds? let bounds = self.param_env .caller_bounds diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index b009c8ea6dc..7e7a8d59266 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -1019,7 +1019,7 @@ fn check_false_global_bounds<'a, 'gcx, 'tcx>( .iter() .map(|(p, _)| *p) .collect(); - // Check elaborated bounds + // Check elaborated bounds. let implied_obligations = traits::elaborate_predicates(fcx.tcx, predicates); for pred in implied_obligations { diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index d12240655e6..e299518af0b 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -2133,10 +2133,10 @@ pub struct TraitRef { #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct PolyTraitRef { - /// The `'a` in `<'a> Foo<&'a T>` + /// The `'a` in `<'a> Foo<&'a T>`. pub bound_generic_params: Vec, - /// The `Foo<&'a T>` in `<'a> Foo<&'a T>` + /// The `Foo<&'a T>` in `<'a> Foo<&'a T>`. pub trait_ref: TraitRef, pub span: Span, -- cgit 1.4.1-3-g733a5 From 4e37785c7d6ef85d00833e93943cdee28baf97b3 Mon Sep 17 00:00:00 2001 From: Brent Kerby Date: Mon, 20 May 2019 21:03:40 -0600 Subject: Create and reference Memory Layout section of boxed docs --- src/liballoc/boxed.rs | 70 ++++++++++++++++++++++++++++----------------------- 1 file changed, 39 insertions(+), 31 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 4e712a946b8..024594517d9 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -4,16 +4,6 @@ //! heap allocation in Rust. Boxes provide ownership for this allocation, and //! drop their contents when they go out of scope. //! -//! For non-zero-sized values, a [`Box`] will use the [`Global`] allocator for -//! its allocation. It is valid to convert both ways between a [`Box`] and a -//! raw pointer allocated with the [`Global`] allocator, given that the -//! [`Layout`] used with the allocator is correct for the type. More precisely, -//! a `value: *mut T` that has been allocated with the [`Global`] allocator -//! with `Layout::for_value(&*value)` may be converted into a box using -//! `Box::::from_raw(value)`. Conversely, the memory backing a `value: *mut -//! T` obtained from `Box::::into_raw` may be deallocated using the -//! [`Global`] allocator with `Layout::for_value(&*value)`. -//! //! # Examples //! //! Move a value from the stack to the heap by creating a [`Box`]: @@ -61,6 +51,19 @@ //! for a `Cons`. By introducing a `Box`, which has a defined size, we know how //! big `Cons` needs to be. //! +//! # Memory layout +//! +//! For non-zero-sized values, a [`Box`] will use the [`Global`] allocator for +//! its allocation. It is valid to convert both ways between a [`Box`] and a +//! raw pointer allocated with the [`Global`] allocator, given that the +//! [`Layout`] used with the allocator is correct for the type. More precisely, +//! a `value: *mut T` that has been allocated with the [`Global`] allocator +//! with `Layout::for_value(&*value)` may be converted into a box using +//! `Box::::from_raw(value)`. Conversely, the memory backing a `value: *mut +//! T` obtained from `Box::::into_raw` may be deallocated using the +//! [`Global`] allocator with `Layout::for_value(&*value)`. +//! +//! //! [dereferencing]: ../../std/ops/trait.Deref.html //! [`Box`]: struct.Box.html //! [`Global`]: ../alloc/struct.Global.html @@ -128,11 +131,8 @@ impl Box { /// After calling this function, the raw pointer is owned by the /// resulting `Box`. Specifically, the `Box` destructor will call /// the destructor of `T` and free the allocated memory. For this - /// to be safe, the memory must have been allocated in the precise - /// way that `Box` expects, namely, using the global allocator - /// with the correct [`Layout`] for holding a value of type `T`. In - /// particular, this will be satisfied for a pointer obtained - /// from a previously existing `Box` using [`Box::into_raw`]. + /// to be safe, the memory must have been allocated in accordance + /// with the [memory layout] used by `Box` . /// /// # Safety /// @@ -141,7 +141,8 @@ impl Box { /// function is called twice on the same raw pointer. /// /// # Examples - /// Recreate a `Box` which was previously converted to a raw pointer using [`Box::into_raw`]: + /// Recreate a `Box` which was previously converted to a raw pointer + /// using [`Box::into_raw`]: /// ``` /// let x = Box::new(5); /// let ptr = Box::into_raw(x); @@ -149,16 +150,18 @@ impl Box { /// ``` /// Manually create a `Box` from scratch by using the global allocator: /// ``` - /// use std::alloc::{Layout, alloc}; + /// use std::alloc::{alloc, Layout}; /// - /// let ptr = unsafe{ alloc(Layout::new::()) } as *mut i32; - /// unsafe{ *ptr = 5; } - /// let x = unsafe{ Box::from_raw(ptr) }; + /// unsafe { + /// let ptr = alloc(Layout::new::()) as *mut i32; + /// *ptr = 5; + /// let x = Box::from_raw(ptr); + /// } /// ``` /// + /// [memory layout]: index.html#memory-layout /// [`Layout`]: ../alloc/struct.Layout.html /// [`Box::into_raw`]: struct.Box.html#method.into_raw - /// #[stable(feature = "box_raw", since = "1.4.0")] #[inline] pub unsafe fn from_raw(raw: *mut T) -> Self { @@ -171,9 +174,11 @@ impl Box { /// /// After calling this function, the caller is responsible for the /// memory previously managed by the `Box`. In particular, the - /// caller should properly destroy `T` and release the memory. The - /// easiest way to do so is to convert the raw pointer back into a `Box` - /// with the [`Box::from_raw`] function. + /// caller should properly destroy `T` and release the memory, taking + /// into account the [memory layout] used by `Box`. The easiest way to + /// do this is to convert the raw pointer back into a `Box` with the + /// [`Box::from_raw`] function, allowing the `Box` destructor to perform + /// the cleanup. /// /// Note: this is an associated function, which means that you have /// to call it as `Box::into_raw(b)` instead of `b.into_raw()`. This @@ -185,21 +190,24 @@ impl Box { /// ``` /// let x = Box::new(String::from("Hello")); /// let ptr = Box::into_raw(x); - /// let x = unsafe{ Box::from_raw(ptr) }; + /// let x = unsafe { Box::from_raw(ptr) }; /// ``` - /// Manual cleanup by running the destructor and deallocating the memory: + /// Manual cleanup by explicitly running the destructor and deallocating + /// the memory: /// ``` - /// use std::alloc::{Layout, dealloc}; + /// use std::alloc::{dealloc, Layout}; /// use std::ptr; /// /// let x = Box::new(String::from("Hello")); /// let p = Box::into_raw(x); - /// unsafe{ ptr::drop_in_place(p); } - /// unsafe{ dealloc(p as *mut u8, Layout::new::()); } + /// unsafe { + /// ptr::drop_in_place(p); + /// dealloc(p as *mut u8, Layout::new::()); + /// } /// ``` /// + /// [memory layout]: index.html#memory-layout /// [`Box::from_raw`]: struct.Box.html#method.from_raw - /// #[stable(feature = "box_raw", since = "1.4.0")] #[inline] pub fn into_raw(b: Box) -> *mut T { @@ -233,7 +241,7 @@ impl Box { /// /// // Clean up the memory by converting the NonNull pointer back /// // into a Box and letting the Box be dropped. - /// let x = unsafe{ Box::from_raw(ptr.as_ptr()) }; + /// let x = unsafe { Box::from_raw(ptr.as_ptr()) }; /// } /// ``` #[unstable(feature = "box_into_raw_non_null", issue = "47336")] -- cgit 1.4.1-3-g733a5 From 8a22bc3b30e81568db25cf57aa9e7629bfa449c7 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Wed, 22 May 2019 14:09:34 -0700 Subject: Revert "Add implementations of last in terms of next_back on a bunch of DoubleEndedIterators." This reverts commit 3e86cf36b5114f201868bf459934fe346a76a2d4. --- src/liballoc/collections/binary_heap.rs | 15 ------------- src/liballoc/collections/btree/map.rs | 40 --------------------------------- src/liballoc/collections/btree/set.rs | 15 ------------- src/liballoc/string.rs | 4 ---- src/liballoc/vec.rs | 14 ------------ src/libcore/ascii.rs | 2 -- src/libcore/iter/adapters/mod.rs | 5 ----- src/libcore/slice/mod.rs | 20 ----------------- src/libcore/str/mod.rs | 20 ----------------- src/libstd/env.rs | 6 ----- src/libstd/path.rs | 10 --------- src/libstd/sys/unix/args.rs | 2 -- src/libstd/sys/wasm/args.rs | 4 ---- src/libstd/sys/windows/args.rs | 2 -- 14 files changed, 159 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/collections/binary_heap.rs b/src/liballoc/collections/binary_heap.rs index c5a0b6e877b..c898f064fd0 100644 --- a/src/liballoc/collections/binary_heap.rs +++ b/src/liballoc/collections/binary_heap.rs @@ -1035,11 +1035,6 @@ impl<'a, T> Iterator for Iter<'a, T> { fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } - - #[inline] - fn last(mut self) -> Option<&'a T> { - self.next_back() - } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1095,11 +1090,6 @@ impl Iterator for IntoIter { fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } - - #[inline] - fn last(mut self) -> Option { - self.next_back() - } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1146,11 +1136,6 @@ impl Iterator for Drain<'_, T> { fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } - - #[inline] - fn last(mut self) -> Option { - self.next_back() - } } #[stable(feature = "drain", since = "1.6.0")] diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs index 414abb00ef1..6b079fc87cc 100644 --- a/src/liballoc/collections/btree/map.rs +++ b/src/liballoc/collections/btree/map.rs @@ -1193,11 +1193,6 @@ impl<'a, K: 'a, V: 'a> Iterator for Iter<'a, K, V> { fn size_hint(&self) -> (usize, Option) { (self.length, Some(self.length)) } - - #[inline] - fn last(mut self) -> Option<(&'a K, &'a V)> { - self.next_back() - } } #[stable(feature = "fused", since = "1.26.0")] @@ -1258,11 +1253,6 @@ impl<'a, K: 'a, V: 'a> Iterator for IterMut<'a, K, V> { fn size_hint(&self) -> (usize, Option) { (self.length, Some(self.length)) } - - #[inline] - fn last(mut self) -> Option<(&'a K, &'a mut V)> { - self.next_back() - } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1369,11 +1359,6 @@ impl Iterator for IntoIter { fn size_hint(&self) -> (usize, Option) { (self.length, Some(self.length)) } - - #[inline] - fn last(mut self) -> Option<(K, V)> { - self.next_back() - } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1436,11 +1421,6 @@ impl<'a, K, V> Iterator for Keys<'a, K, V> { fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } - - #[inline] - fn last(mut self) -> Option<&'a K> { - self.next_back() - } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1478,11 +1458,6 @@ impl<'a, K, V> Iterator for Values<'a, K, V> { fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } - - #[inline] - fn last(mut self) -> Option<&'a V> { - self.next_back() - } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1520,11 +1495,6 @@ impl<'a, K, V> Iterator for Range<'a, K, V> { unsafe { Some(self.next_unchecked()) } } } - - #[inline] - fn last(mut self) -> Option<(&'a K, &'a V)> { - self.next_back() - } } #[stable(feature = "map_values_mut", since = "1.10.0")] @@ -1538,11 +1508,6 @@ impl<'a, K, V> Iterator for ValuesMut<'a, K, V> { fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } - - #[inline] - fn last(mut self) -> Option<&'a mut V> { - self.next_back() - } } #[stable(feature = "map_values_mut", since = "1.10.0")] @@ -1661,11 +1626,6 @@ impl<'a, K, V> Iterator for RangeMut<'a, K, V> { unsafe { Some(self.next_unchecked()) } } } - - #[inline] - fn last(mut self) -> Option<(&'a K, &'a mut V)> { - self.next_back() - } } impl<'a, K, V> RangeMut<'a, K, V> { diff --git a/src/liballoc/collections/btree/set.rs b/src/liballoc/collections/btree/set.rs index 6f2467dfd6b..16a96ca19b8 100644 --- a/src/liballoc/collections/btree/set.rs +++ b/src/liballoc/collections/btree/set.rs @@ -1019,11 +1019,6 @@ impl<'a, T> Iterator for Iter<'a, T> { fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } - - #[inline] - fn last(mut self) -> Option<&'a T> { - self.next_back() - } } #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> DoubleEndedIterator for Iter<'a, T> { @@ -1049,11 +1044,6 @@ impl Iterator for IntoIter { fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } - - #[inline] - fn last(mut self) -> Option { - self.next_back() - } } #[stable(feature = "rust1", since = "1.0.0")] impl DoubleEndedIterator for IntoIter { @@ -1083,11 +1073,6 @@ impl<'a, T> Iterator for Range<'a, T> { fn next(&mut self) -> Option<&'a T> { self.iter.next().map(|(k, _)| k) } - - #[inline] - fn last(mut self) -> Option<&'a T> { - self.next_back() - } } #[stable(feature = "btree_range", since = "1.17.0")] diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index e74d37c1c2b..7f7722548f5 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -2385,10 +2385,6 @@ impl Iterator for Drain<'_> { fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } - #[inline] - fn last(mut self) -> Option { - self.next_back() - } } #[stable(feature = "drain", since = "1.6.0")] diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index c0cdffe596b..073d3ab5937 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -2395,11 +2395,6 @@ impl Iterator for IntoIter { fn count(self) -> usize { self.len() } - - #[inline] - fn last(mut self) -> Option { - self.next_back() - } } #[stable(feature = "rust1", since = "1.0.0")] @@ -2519,11 +2514,6 @@ impl Iterator for Drain<'_, T> { fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } - - #[inline] - fn last(mut self) -> Option { - self.next_back() - } } #[stable(feature = "drain", since = "1.6.0")] @@ -2593,10 +2583,6 @@ impl Iterator for Splice<'_, I> { fn size_hint(&self) -> (usize, Option) { self.drain.size_hint() } - - fn last(mut self) -> Option { - self.next_back() - } } #[stable(feature = "vec_splice", since = "1.21.0")] diff --git a/src/libcore/ascii.rs b/src/libcore/ascii.rs index ddee02ea232..c0ab364380f 100644 --- a/src/libcore/ascii.rs +++ b/src/libcore/ascii.rs @@ -117,8 +117,6 @@ impl Iterator for EscapeDefault { type Item = u8; fn next(&mut self) -> Option { self.range.next().map(|i| self.data[i]) } fn size_hint(&self) -> (usize, Option) { self.range.size_hint() } - #[inline] - fn last(mut self) -> Option { self.next_back() } } #[stable(feature = "rust1", since = "1.0.0")] impl DoubleEndedIterator for EscapeDefault { diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs index 64e588f65b4..518442efe74 100644 --- a/src/libcore/iter/adapters/mod.rs +++ b/src/libcore/iter/adapters/mod.rs @@ -73,11 +73,6 @@ impl Iterator for Rev where I: DoubleEndedIterator { { self.iter.position(predicate) } - - #[inline] - fn last(mut self) -> Option { - self.next_back() - } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index d06d107d32a..50d2ba0d3ef 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -3547,11 +3547,6 @@ impl<'a, T, P> Iterator for Split<'a, T, P> where P: FnMut(&T) -> bool { (1, Some(self.v.len() + 1)) } } - - #[inline] - fn last(mut self) -> Option { - self.next_back() - } } #[stable(feature = "rust1", since = "1.0.0")] @@ -3650,11 +3645,6 @@ impl<'a, T, P> Iterator for SplitMut<'a, T, P> where P: FnMut(&T) -> bool { (1, Some(self.v.len() + 1)) } } - - #[inline] - fn last(mut self) -> Option { - self.next_back() - } } #[stable(feature = "rust1", since = "1.0.0")] @@ -3720,11 +3710,6 @@ impl<'a, T, P> Iterator for RSplit<'a, T, P> where P: FnMut(&T) -> bool { fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } - - #[inline] - fn last(mut self) -> Option { - self.next_back() - } } #[stable(feature = "slice_rsplit", since = "1.27.0")] @@ -3789,11 +3774,6 @@ impl<'a, T, P> Iterator for RSplitMut<'a, T, P> where P: FnMut(&T) -> bool { fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } - - #[inline] - fn last(mut self) -> Option { - self.next_back() - } } #[stable(feature = "slice_rsplit", since = "1.27.0")] diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 0e8a2da3c11..ef4bd83cbc5 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -1333,11 +1333,6 @@ impl<'a> Iterator for Lines<'a> { fn size_hint(&self) -> (usize, Option) { self.0.size_hint() } - - #[inline] - fn last(mut self) -> Option { - self.next_back() - } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1384,11 +1379,6 @@ impl<'a> Iterator for LinesAny<'a> { fn size_hint(&self) -> (usize, Option) { self.0.size_hint() } - - #[inline] - fn last(mut self) -> Option { - self.next_back() - } } #[stable(feature = "rust1", since = "1.0.0")] @@ -4231,11 +4221,6 @@ impl<'a> Iterator for SplitWhitespace<'a> { fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } - - #[inline] - fn last(mut self) -> Option { - self.next_back() - } } #[stable(feature = "split_whitespace", since = "1.1.0")] @@ -4262,11 +4247,6 @@ impl<'a> Iterator for SplitAsciiWhitespace<'a> { fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } - - #[inline] - fn last(mut self) -> Option { - self.next_back() - } } #[stable(feature = "split_ascii_whitespace", since = "1.34.0")] diff --git a/src/libstd/env.rs b/src/libstd/env.rs index 260624a8bd8..9058ea93d6d 100644 --- a/src/libstd/env.rs +++ b/src/libstd/env.rs @@ -746,10 +746,6 @@ impl Iterator for Args { self.inner.next().map(|s| s.into_string().unwrap()) } fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } - #[inline] - fn last(mut self) -> Option { - self.next_back() - } } #[stable(feature = "env", since = "1.0.0")] @@ -785,8 +781,6 @@ impl Iterator for ArgsOs { type Item = OsString; fn next(&mut self) -> Option { self.inner.next() } fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } - #[inline] - fn last(mut self) -> Option { self.next_back() } } #[stable(feature = "env", since = "1.0.0")] diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 59f9e439add..126bc3754da 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -888,11 +888,6 @@ impl<'a> Iterator for Iter<'a> { fn next(&mut self) -> Option<&'a OsStr> { self.inner.next().map(Component::as_os_str) } - - #[inline] - fn last(mut self) -> Option<&'a OsStr> { - self.next_back() - } } #[stable(feature = "rust1", since = "1.0.0")] @@ -956,11 +951,6 @@ impl<'a> Iterator for Components<'a> { } None } - - #[inline] - fn last(mut self) -> Option { - self.next_back() - } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libstd/sys/unix/args.rs b/src/libstd/sys/unix/args.rs index 6ba947d4598..3b4de56f2c9 100644 --- a/src/libstd/sys/unix/args.rs +++ b/src/libstd/sys/unix/args.rs @@ -35,8 +35,6 @@ impl Iterator for Args { type Item = OsString; fn next(&mut self) -> Option { self.iter.next() } fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } - #[inline] - fn last(mut self) -> Option { self.next_back() } } impl ExactSizeIterator for Args { diff --git a/src/libstd/sys/wasm/args.rs b/src/libstd/sys/wasm/args.rs index 6766099c1ec..b3c77b86995 100644 --- a/src/libstd/sys/wasm/args.rs +++ b/src/libstd/sys/wasm/args.rs @@ -37,10 +37,6 @@ impl Iterator for Args { fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } - #[inline] - fn last(mut self) -> Option { - self.next_back() - } } impl ExactSizeIterator for Args { diff --git a/src/libstd/sys/windows/args.rs b/src/libstd/sys/windows/args.rs index 744d7ec59d3..b04bb484eed 100644 --- a/src/libstd/sys/windows/args.rs +++ b/src/libstd/sys/windows/args.rs @@ -181,8 +181,6 @@ impl Iterator for Args { type Item = OsString; fn next(&mut self) -> Option { self.parsed_args_list.next() } fn size_hint(&self) -> (usize, Option) { self.parsed_args_list.size_hint() } - #[inline] - fn last(mut self) -> Option { self.next_back() } } impl DoubleEndedIterator for Args { -- cgit 1.4.1-3-g733a5 From f44b264447f0d1b42676e7ea99a04d140749f65b Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 23 May 2019 16:30:16 +0200 Subject: fix dangling reference in Vec::append --- src/liballoc/tests/vec.rs | 5 +++-- src/liballoc/vec.rs | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/tests/vec.rs b/src/liballoc/tests/vec.rs index 545332bcd6a..3307bdf94f9 100644 --- a/src/liballoc/tests/vec.rs +++ b/src/liballoc/tests/vec.rs @@ -1,5 +1,3 @@ -#![cfg(not(miri))] - use std::borrow::Cow; use std::mem::size_of; use std::{usize, isize}; @@ -763,6 +761,7 @@ fn from_into_inner() { it.next().unwrap(); let vec = it.collect::>(); assert_eq!(vec, [2, 3]); + #[cfg(not(miri))] // Miri does not support comparing dangling pointers assert!(ptr != vec.as_ptr()); } @@ -971,6 +970,7 @@ fn test_reserve_exact() { } #[test] +#[cfg(not(miri))] // Miri does not support signalling OOM fn test_try_reserve() { // These are the interesting cases: @@ -1073,6 +1073,7 @@ fn test_try_reserve() { } #[test] +#[cfg(not(miri))] // Miri does not support signalling OOM fn test_try_reserve_exact() { // This is exactly the same as test_try_reserve with the method changed. diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 073d3ab5937..dc661a267e2 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -1094,7 +1094,7 @@ impl Vec { let count = (*other).len(); self.reserve(count); let len = self.len(); - ptr::copy_nonoverlapping(other as *const T, self.get_unchecked_mut(len), count); + ptr::copy_nonoverlapping(other as *const T, self.as_mut_ptr().add(len), count); self.len += count; } -- cgit 1.4.1-3-g733a5 From 6116f19f7baa3c1f7ed4659aa3b9b5ec5ff8ac3e Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 23 May 2019 17:58:25 +0200 Subject: Box::into_unique: do the reborrow-to-raw *after* destroying the Box --- src/liballoc/boxed.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 024594517d9..0e40e4f371a 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -253,15 +253,15 @@ impl Box { #[unstable(feature = "ptr_internals", issue = "0", reason = "use into_raw_non_null instead")] #[inline] #[doc(hidden)] - pub fn into_unique(mut b: Box) -> Unique { + pub fn into_unique(b: Box) -> Unique { + let mut unique = b.0; + mem::forget(b); // Box is kind-of a library type, but recognized as a "unique pointer" by // Stacked Borrows. This function here corresponds to "reborrowing to // a raw pointer", but there is no actual reborrow here -- so // without some care, the pointer we are returning here still carries // the `Uniq` tag. We round-trip through a mutable reference to avoid that. - let unique = unsafe { b.0.as_mut() as *mut T }; - mem::forget(b); - unsafe { Unique::new_unchecked(unique) } + unsafe { Unique::new_unchecked(unique.as_mut() as *mut T) } } /// Consumes and leaks the `Box`, returning a mutable reference, -- cgit 1.4.1-3-g733a5 From 8d4e7fde479e018d3caf37d1d12f47710183252e Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 23 May 2019 18:13:02 +0200 Subject: adjust comment --- src/liballoc/boxed.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/liballoc') diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 0e40e4f371a..97c2d8e7a8e 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -260,7 +260,8 @@ impl Box { // Stacked Borrows. This function here corresponds to "reborrowing to // a raw pointer", but there is no actual reborrow here -- so // without some care, the pointer we are returning here still carries - // the `Uniq` tag. We round-trip through a mutable reference to avoid that. + // the tag of `b`, with `Unique` permission. + // We round-trip through a mutable reference to avoid that. unsafe { Unique::new_unchecked(unique.as_mut() as *mut T) } } -- cgit 1.4.1-3-g733a5 From 73fd3497d4cc65c733cc1848bea363c00cb87878 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Fri, 24 May 2019 08:55:33 +0200 Subject: Deprecate `FnBox`. `Box` can be called directly, since 1.35 FCP completion: https://github.com/rust-lang/rust/issues/28796#issuecomment-439731515 --- src/liballoc/boxed.rs | 42 +++++++++++++++++----- src/test/run-pass/unsized-locals/fnbox-compat.rs | 1 + src/test/ui/confuse-field-and-method/issue-2392.rs | 12 +++---- .../ui/confuse-field-and-method/issue-2392.stderr | 28 +++++++-------- 4 files changed, 52 insertions(+), 31 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 97c2d8e7a8e..bf8f5b8b91a 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -759,13 +759,14 @@ impl + ?Sized> Fn for Box { } } +/// `FnBox` is deprecated and will be removed. +/// `Box` can be called directly, since Rust 1.35.0. +/// /// `FnBox` is a version of the `FnOnce` intended for use with boxed -/// closure objects. The idea is that where one would normally store a -/// `Box` in a data structure, you should use +/// closure objects. The idea was that where one would normally store a +/// `Box` in a data structure, you whould use /// `Box`. The two traits behave essentially the same, except -/// that a `FnBox` closure can only be called if it is boxed. (Note -/// that `FnBox` may be deprecated in the future if `Box` -/// closures become directly usable.) +/// that a `FnBox` closure can only be called if it is boxed. /// /// # Examples /// @@ -777,6 +778,7 @@ impl + ?Sized> Fn for Box { /// /// ``` /// #![feature(fnbox)] +/// #![allow(deprecated)] /// /// use std::boxed::FnBox; /// use std::collections::HashMap; @@ -796,16 +798,38 @@ impl + ?Sized> Fn for Box { /// } /// } /// ``` +/// +/// In Rust 1.35.0 or later, use `FnOnce`, `FnMut`, or `Fn` instead: +/// +/// ``` +/// use std::collections::HashMap; +/// +/// fn make_map() -> HashMap i32>> { +/// let mut map: HashMap i32>> = HashMap::new(); +/// map.insert(1, Box::new(|| 22)); +/// map.insert(2, Box::new(|| 44)); +/// map +/// } +/// +/// fn main() { +/// let mut map = make_map(); +/// for i in &[1, 2] { +/// let f = map.remove(&i).unwrap(); +/// assert_eq!(f(), i * 22); +/// } +/// } +/// ``` #[rustc_paren_sugar] -#[unstable(feature = "fnbox", - reason = "will be deprecated if and when `Box` becomes usable", issue = "28796")] +#[unstable(feature = "fnbox", issue = "28796")] +#[rustc_deprecated(reason = "use `FnOnce`, `FnMut`, or `Fn` instead", since = "1.37.0")] pub trait FnBox: FnOnce { /// Performs the call operation. fn call_box(self: Box, args: A) -> Self::Output; } -#[unstable(feature = "fnbox", - reason = "will be deprecated if and when `Box` becomes usable", issue = "28796")] +#[unstable(feature = "fnbox", issue = "28796")] +#[rustc_deprecated(reason = "use `FnOnce`, `FnMut`, or `Fn` instead", since = "1.37.0")] +#[allow(deprecated, deprecated_in_future)] impl FnBox for F where F: FnOnce { diff --git a/src/test/run-pass/unsized-locals/fnbox-compat.rs b/src/test/run-pass/unsized-locals/fnbox-compat.rs index 5ec54ada13b..74a4dd5d851 100644 --- a/src/test/run-pass/unsized-locals/fnbox-compat.rs +++ b/src/test/run-pass/unsized-locals/fnbox-compat.rs @@ -1,4 +1,5 @@ #![feature(fnbox)] +#![allow(deprecated, deprecated_in_future)] use std::boxed::FnBox; diff --git a/src/test/ui/confuse-field-and-method/issue-2392.rs b/src/test/ui/confuse-field-and-method/issue-2392.rs index 41287c25914..c242b6c2c20 100644 --- a/src/test/ui/confuse-field-and-method/issue-2392.rs +++ b/src/test/ui/confuse-field-and-method/issue-2392.rs @@ -1,7 +1,3 @@ -#![feature(core, fnbox)] - -use std::boxed::FnBox; - struct FuncContainer { f1: fn(data: u8), f2: extern "C" fn(data: u8), @@ -18,7 +14,7 @@ struct Obj where F: FnOnce() -> u32 { } struct BoxedObj { - boxed_closure: Box u32>, + boxed_closure: Box u32>, } struct Wrapper where F: FnMut() -> u32 { @@ -29,8 +25,8 @@ fn func() -> u32 { 0 } -fn check_expression() -> Obj u32>> { - Obj { closure: Box::new(|| 42_u32) as Box u32>, not_closure: 42 } +fn check_expression() -> Obj u32>> { + Obj { closure: Box::new(|| 42_u32) as Box u32>, not_closure: 42 } } fn main() { @@ -48,7 +44,7 @@ fn main() { let boxed_fn = BoxedObj { boxed_closure: Box::new(func) }; boxed_fn.boxed_closure();//~ ERROR no method named `boxed_closure` found - let boxed_closure = BoxedObj { boxed_closure: Box::new(|| 42_u32) as Box u32> }; + let boxed_closure = BoxedObj { boxed_closure: Box::new(|| 42_u32) as Box u32> }; boxed_closure.boxed_closure();//~ ERROR no method named `boxed_closure` found // test expression writing in the notes diff --git a/src/test/ui/confuse-field-and-method/issue-2392.stderr b/src/test/ui/confuse-field-and-method/issue-2392.stderr index 2107318d87b..351cfef1b53 100644 --- a/src/test/ui/confuse-field-and-method/issue-2392.stderr +++ b/src/test/ui/confuse-field-and-method/issue-2392.stderr @@ -1,5 +1,5 @@ -error[E0599]: no method named `closure` found for type `Obj<[closure@$DIR/issue-2392.rs:39:36: 39:41]>` in the current scope - --> $DIR/issue-2392.rs:40:15 +error[E0599]: no method named `closure` found for type `Obj<[closure@$DIR/issue-2392.rs:35:36: 35:41]>` in the current scope + --> $DIR/issue-2392.rs:36:15 | LL | struct Obj where F: FnOnce() -> u32 { | -------------------------------------- method `closure` not found for this @@ -11,8 +11,8 @@ help: to call the function stored in `closure`, surround the field access with p LL | (o_closure.closure)(); | ^ ^ -error[E0599]: no method named `not_closure` found for type `Obj<[closure@$DIR/issue-2392.rs:39:36: 39:41]>` in the current scope - --> $DIR/issue-2392.rs:42:15 +error[E0599]: no method named `not_closure` found for type `Obj<[closure@$DIR/issue-2392.rs:35:36: 35:41]>` in the current scope + --> $DIR/issue-2392.rs:38:15 | LL | struct Obj where F: FnOnce() -> u32 { | -------------------------------------- method `not_closure` not found for this @@ -23,7 +23,7 @@ LL | o_closure.not_closure(); | field, not a method error[E0599]: no method named `closure` found for type `Obj u32 {func}>` in the current scope - --> $DIR/issue-2392.rs:46:12 + --> $DIR/issue-2392.rs:42:12 | LL | struct Obj where F: FnOnce() -> u32 { | -------------------------------------- method `closure` not found for this @@ -36,7 +36,7 @@ LL | (o_func.closure)(); | ^ ^ error[E0599]: no method named `boxed_closure` found for type `BoxedObj` in the current scope - --> $DIR/issue-2392.rs:49:14 + --> $DIR/issue-2392.rs:45:14 | LL | struct BoxedObj { | --------------- method `boxed_closure` not found for this @@ -49,7 +49,7 @@ LL | (boxed_fn.boxed_closure)(); | ^ ^ error[E0599]: no method named `boxed_closure` found for type `BoxedObj` in the current scope - --> $DIR/issue-2392.rs:52:19 + --> $DIR/issue-2392.rs:48:19 | LL | struct BoxedObj { | --------------- method `boxed_closure` not found for this @@ -62,7 +62,7 @@ LL | (boxed_closure.boxed_closure)(); | ^ ^ error[E0599]: no method named `closure` found for type `Obj u32 {func}>` in the current scope - --> $DIR/issue-2392.rs:57:12 + --> $DIR/issue-2392.rs:53:12 | LL | struct Obj where F: FnOnce() -> u32 { | -------------------------------------- method `closure` not found for this @@ -75,7 +75,7 @@ LL | (w.wrap.closure)(); | ^ ^ error[E0599]: no method named `not_closure` found for type `Obj u32 {func}>` in the current scope - --> $DIR/issue-2392.rs:59:12 + --> $DIR/issue-2392.rs:55:12 | LL | struct Obj where F: FnOnce() -> u32 { | -------------------------------------- method `not_closure` not found for this @@ -85,8 +85,8 @@ LL | w.wrap.not_closure(); | | | field, not a method -error[E0599]: no method named `closure` found for type `Obj + 'static)>>` in the current scope - --> $DIR/issue-2392.rs:62:24 +error[E0599]: no method named `closure` found for type `Obj u32 + 'static)>>` in the current scope + --> $DIR/issue-2392.rs:58:24 | LL | struct Obj where F: FnOnce() -> u32 { | -------------------------------------- method `closure` not found for this @@ -99,7 +99,7 @@ LL | (check_expression().closure)(); | ^ ^ error[E0599]: no method named `f1` found for type `FuncContainer` in the current scope - --> $DIR/issue-2392.rs:68:31 + --> $DIR/issue-2392.rs:64:31 | LL | struct FuncContainer { | -------------------- method `f1` not found for this @@ -112,7 +112,7 @@ LL | ((*self.container).f1)(1); | ^ ^ error[E0599]: no method named `f2` found for type `FuncContainer` in the current scope - --> $DIR/issue-2392.rs:69:31 + --> $DIR/issue-2392.rs:65:31 | LL | struct FuncContainer { | -------------------- method `f2` not found for this @@ -125,7 +125,7 @@ LL | ((*self.container).f2)(1); | ^ ^ error[E0599]: no method named `f3` found for type `FuncContainer` in the current scope - --> $DIR/issue-2392.rs:70:31 + --> $DIR/issue-2392.rs:66:31 | LL | struct FuncContainer { | -------------------- method `f3` not found for this -- cgit 1.4.1-3-g733a5 From 15241a4d4106b12cb6cbe25837cc56b629aad2dd Mon Sep 17 00:00:00 2001 From: Chris Gregory Date: Fri, 24 May 2019 15:28:55 -0500 Subject: Fix documentation of `Rc::make_mut` regarding `rc::Weak`. --- src/liballoc/rc.rs | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 0dffb19476f..40fae408a57 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -584,15 +584,18 @@ impl Rc { impl Rc { /// Makes a mutable reference into the given `Rc`. /// - /// If there are other `Rc` or [`Weak`][weak] pointers to the same value, - /// then `make_mut` will invoke [`clone`][clone] on the inner value to - /// ensure unique ownership. This is also referred to as clone-on-write. + /// If there are other `Rc` pointers to the same value, then `make_mut` will + /// [`clone`] the inner value to ensure unique ownership. This is also + /// referred to as clone-on-write. /// - /// See also [`get_mut`][get_mut], which will fail rather than cloning. + /// If there are not other `Rc` pointers to this value, then [`Weak`] + /// pointers to this value will be dissassociated. /// - /// [weak]: struct.Weak.html - /// [clone]: ../../std/clone/trait.Clone.html#tymethod.clone - /// [get_mut]: struct.Rc.html#method.get_mut + /// See also [`get_mut`], which will fail rather than cloning. + /// + /// [`Weak`]: struct.Weak.html + /// [`clone`]: ../../std/clone/trait.Clone.html#tymethod.clone + /// [`get_mut`]: struct.Rc.html#method.get_mut /// /// # Examples /// @@ -611,6 +614,23 @@ impl Rc { /// assert_eq!(*data, 8); /// assert_eq!(*other_data, 12); /// ``` + /// + /// [`Weak`] pointers will be dissassociated: + /// + /// ``` + /// use std::rc::{Rc, Weak}; + /// + /// let mut data = Rc::new(75); + /// let weak = Rc::downgrade(&data); + /// + /// assert!(75 == *data); + /// assert!(75 == *weak.upgrade().unwrap()); + /// + /// *Rc::make_mut(&mut data) += 1; + /// + /// assert!(76 == *data); + /// assert!(weak.upgrade().is_none()); + /// ``` #[inline] #[stable(feature = "rc_unique", since = "1.4.0")] pub fn make_mut(this: &mut Self) -> &mut T { -- cgit 1.4.1-3-g733a5 From 3dd114e1cb24ce56d136dfd0af00780f06a2975c Mon Sep 17 00:00:00 2001 From: Chris Gregory Date: Fri, 24 May 2019 21:04:56 -0500 Subject: SliceConcatExt::connect defaults to calling join --- src/liballoc/slice.rs | 8 +++----- src/liballoc/str.rs | 4 ---- 2 files changed, 3 insertions(+), 9 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index 8768f1ff081..04bef58774b 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -582,7 +582,9 @@ pub trait SliceConcatExt { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[rustc_deprecated(since = "1.3.0", reason = "renamed to join")] - fn connect(&self, sep: &T) -> Self::Output; + fn connect(&self, sep: &T) -> Self::Output { + self.join(sep) + } } #[unstable(feature = "slice_concat_ext", @@ -616,10 +618,6 @@ impl> SliceConcatExt for [V] { } result } - - fn connect(&self, sep: &T) -> Vec { - self.join(sep) - } } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs index f66ff894ae8..0b7374fd8e4 100644 --- a/src/liballoc/str.rs +++ b/src/liballoc/str.rs @@ -86,10 +86,6 @@ impl> SliceConcatExt for [S] { String::from_utf8_unchecked( join_generic_copy(self, sep.as_bytes()) ) } } - - fn connect(&self, sep: &str) -> String { - self.join(sep) - } } macro_rules! spezialize_for_lengths { -- cgit 1.4.1-3-g733a5 From fbe9f16bc2102b2450384a103d9799debd4c914e Mon Sep 17 00:00:00 2001 From: Chris Gregory Date: Fri, 24 May 2019 21:08:59 -0500 Subject: Reword `are not other` to `are no other` Co-Authored-By: Jonas Schievink --- src/liballoc/rc.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/liballoc') diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 40fae408a57..ce9067c2ff9 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -588,7 +588,7 @@ impl Rc { /// [`clone`] the inner value to ensure unique ownership. This is also /// referred to as clone-on-write. /// - /// If there are not other `Rc` pointers to this value, then [`Weak`] + /// If there are no other `Rc` pointers to this value, then [`Weak`] /// pointers to this value will be dissassociated. /// /// See also [`get_mut`], which will fail rather than cloning. -- cgit 1.4.1-3-g733a5 From b34b714a896644c7ac5787b214f4115fc0226d96 Mon Sep 17 00:00:00 2001 From: Chris Gregory Date: Fri, 24 May 2019 21:10:17 -0500 Subject: Remove unused import in doctest --- src/liballoc/rc.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/liballoc') diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index ce9067c2ff9..2cca8d4a396 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -618,7 +618,7 @@ impl Rc { /// [`Weak`] pointers will be dissassociated: /// /// ``` - /// use std::rc::{Rc, Weak}; + /// use std::rc::Rc; /// /// let mut data = Rc::new(75); /// let weak = Rc::downgrade(&data); -- cgit 1.4.1-3-g733a5 From 9d82826e555e658680cf6ef246ae6d088f300d1d Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 25 May 2019 10:11:00 +0200 Subject: add test checking that Vec push/pop does not invalidate pointers --- src/liballoc/tests/vec.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'src/liballoc') diff --git a/src/liballoc/tests/vec.rs b/src/liballoc/tests/vec.rs index 3307bdf94f9..5ddac673c9f 100644 --- a/src/liballoc/tests/vec.rs +++ b/src/liballoc/tests/vec.rs @@ -1152,3 +1152,24 @@ fn test_try_reserve_exact() { } } + +#[test] +fn test_stable_push_pop() { + // Test that, if we reserved enough space, adding and removing elements does not + // invalidate references into the vector (such as `v0`). This test also + // runs in Miri, which would detect such problems. + let mut v = Vec::with_capacity(10); + v.push(13); + + // laundering the lifetime -- we take care that `v` does not reallocate, so that's okay. + let v0 = unsafe { &*(&v[0] as *const _) }; + + // Now do a bunch of things and occasionally use `v0` again to assert it is still valid. + v.push(1); + v.push(2); + v.insert(1, 1); + assert_eq!(*v0, 13); + v.remove(1); + v.pop().unwrap(); + assert_eq!(*v0, 13); +} -- cgit 1.4.1-3-g733a5 From 428ab7e1bd77b82db30dc574b3f9c4fe0a7c77f6 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 25 May 2019 10:36:07 +0200 Subject: shadow as_ptr as as_mut_ptr in Vec to avoid going through Deref --- src/liballoc/vec.rs | 78 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 71 insertions(+), 7 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index dc661a267e2..5cb91395b7b 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -735,6 +735,75 @@ impl Vec { self } + /// Returns a raw pointer to the vector's buffer. + /// + /// The caller must ensure that the vector outlives the pointer this + /// function returns, or else it will end up pointing to garbage. + /// Modifying the vector may cause its buffer to be reallocated, + /// which would also make any pointers to it invalid. + /// + /// The caller must also ensure that the memory the pointer (non-transitively) points to + /// is never written to (except inside an `UnsafeCell`) using this pointer or any pointer + /// derived from it. If you need to mutate the contents of the slice, use [`as_mut_ptr`]. + /// + /// # Examples + /// + /// ``` + /// let x = vec![1, 2, 4]; + /// let x_ptr = x.as_ptr(); + /// + /// unsafe { + /// for i in 0..x.len() { + /// assert_eq!(*x_ptr.add(i), 1 << i); + /// } + /// } + /// ``` + /// + /// [`as_mut_ptr`]: #method.as_mut_ptr + #[stable(feature = "vec_as_ptr", since = "1.37.0")] + #[inline] + pub fn as_ptr(&self) -> *const T { + // We shadow the slice method of the same name to avoid going through + // `deref`, which creates an intermediate reference. + let ptr = self.buf.ptr(); + unsafe { assume(!ptr.is_null()); } + ptr + } + + /// Returns an unsafe mutable pointer to the vector's buffer. + /// + /// The caller must ensure that the vector outlives the pointer this + /// function returns, or else it will end up pointing to garbage. + /// Modifying the vector may cause its buffer to be reallocated, + /// which would also make any pointers to it invalid. + /// + /// # Examples + /// + /// ``` + /// // Allocate vector big enough for 4 elements. + /// let size = 4; + /// let mut x: Vec = Vec::with_capacity(size); + /// let x_ptr = x.as_mut_ptr(); + /// + /// // Initialize elements via raw pointer writes, then set length. + /// unsafe { + /// for i in 0..size { + /// *x_ptr.add(i) = i as i32; + /// } + /// x.set_len(size); + /// } + /// assert_eq!(&*x, &[0,1,2,3]); + /// ``` + #[stable(feature = "vec_as_ptr", since = "1.37.0")] + #[inline] + pub fn as_mut_ptr(&mut self) -> *mut T { + // We shadow the slice method of the same name to avoid going through + // `deref_mut`, which creates an intermediate reference. + let ptr = self.buf.ptr(); + unsafe { assume(!ptr.is_null()); } + ptr + } + /// Forces the length of the vector to `new_len`. /// /// This is a low-level operation that maintains none of the normal @@ -1706,9 +1775,7 @@ impl ops::Deref for Vec { fn deref(&self) -> &[T] { unsafe { - let p = self.buf.ptr(); - assume(!p.is_null()); - slice::from_raw_parts(p, self.len) + slice::from_raw_parts(self.as_ptr(), self.len) } } } @@ -1717,9 +1784,7 @@ impl ops::Deref for Vec { impl ops::DerefMut for Vec { fn deref_mut(&mut self) -> &mut [T] { unsafe { - let ptr = self.buf.ptr(); - assume(!ptr.is_null()); - slice::from_raw_parts_mut(ptr, self.len) + slice::from_raw_parts_mut(self.as_mut_ptr(), self.len) } } } @@ -1754,7 +1819,6 @@ impl IntoIterator for Vec { fn into_iter(mut self) -> IntoIter { unsafe { let begin = self.as_mut_ptr(); - assume(!begin.is_null()); let end = if mem::size_of::() == 0 { arith_offset(begin as *const i8, self.len() as isize) as *const T } else { -- cgit 1.4.1-3-g733a5 From f9d328d7ffa17ab78eaa62a2976033a7176886d9 Mon Sep 17 00:00:00 2001 From: Michal 'vorner' Vaner Date: Sun, 12 May 2019 14:53:01 +0200 Subject: sync::Weak::{as,from,into}_raw Methods on the Weak to access it as raw pointer to the data. --- src/liballoc/sync.rs | 164 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 158 insertions(+), 6 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index 90c7859b3db..70865656c51 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -13,7 +13,7 @@ use core::borrow; use core::fmt; use core::cmp::{self, Ordering}; use core::intrinsics::abort; -use core::mem::{self, align_of_val, size_of_val}; +use core::mem::{self, align_of, align_of_val, size_of_val}; use core::ops::{Deref, Receiver, CoerceUnsized, DispatchFromDyn}; use core::pin::Pin; use core::ptr::{self, NonNull}; @@ -397,11 +397,7 @@ impl Arc { /// ``` #[stable(feature = "rc_raw", since = "1.17.0")] pub unsafe fn from_raw(ptr: *const T) -> Self { - // Align the unsized value to the end of the ArcInner. - // Because it is ?Sized, it will always be the last field in memory. - let align = align_of_val(&*ptr); - let layout = Layout::new::>(); - let offset = (layout.size() + layout.padding_needed_for(align)) as isize; + let offset = data_offset(ptr); // Reverse the offset to find the original ArcInner. let fake_ptr = ptr as *mut ArcInner; @@ -1071,6 +1067,144 @@ impl Weak { ptr: NonNull::new(usize::MAX as *mut ArcInner).expect("MAX is not 0"), } } + + /// Returns a raw pointer to the object `T` pointed to by this `Weak`. + /// + /// It is up to the caller to ensure that the object is still alive when accessing it through + /// the pointer. + /// + /// The pointer may be [`null`] or be dangling in case the object has already been destroyed. + /// + /// # Examples + /// + /// ``` + /// #![feature(weak_into_raw)] + /// + /// use std::sync::{Arc, Weak}; + /// use std::ptr; + /// + /// let strong = Arc::new(42); + /// let weak = Arc::downgrade(&strong); + /// // Both point to the same object + /// assert!(ptr::eq(&*strong, Weak::as_raw(&weak))); + /// // The strong here keeps it alive, so we can still access the object. + /// assert_eq!(42, unsafe { *Weak::as_raw(&weak) }); + /// + /// drop(strong); + /// // But not any more. We can do Weak::as_raw(&weak), but accessing the pointer would lead to + /// // undefined behaviour. + /// // assert_eq!(42, unsafe { *Weak::as_raw(&weak) }); + /// ``` + /// + /// [`null`]: ../../std/ptr/fn.null.html + #[unstable(feature = "weak_into_raw", issue = "60728")] + pub fn as_raw(this: &Self) -> *const T { + match this.inner() { + None => ptr::null(), + Some(inner) => { + let offset = data_offset_sized::(); + let ptr = inner as *const ArcInner; + // Note: while the pointer we create may already point to dropped value, the + // allocation still lives (it must hold the weak point as long as we are alive). + // Therefore, the offset is OK to do, it won't get out of the allocation. + let ptr = unsafe { (ptr as *const u8).offset(offset) }; + ptr as *const T + } + } + } + + /// Consumes the `Weak` and turns it into a raw pointer. + /// + /// This converts the weak pointer into a raw pointer, preserving the original weak count. It + /// can be turned back into the `Weak` with [`from_raw`]. + /// + /// The same restrictions of accessing the target of the pointer as with + /// [`as_raw`] apply. + /// + /// # Examples + /// + /// ``` + /// #![feature(weak_into_raw)] + /// + /// use std::sync::{Arc, Weak}; + /// + /// let strong = Arc::new(42); + /// let weak = Arc::downgrade(&strong); + /// let raw = Weak::into_raw(weak); + /// + /// assert_eq!(1, Arc::weak_count(&strong)); + /// assert_eq!(42, unsafe { *raw }); + /// + /// drop(unsafe { Weak::from_raw(raw) }); + /// assert_eq!(0, Arc::weak_count(&strong)); + /// ``` + /// + /// [`from_raw`]: struct.Weak.html#method.from_raw + /// [`as_raw`]: struct.Weak.html#method.as_raw + #[unstable(feature = "weak_into_raw", issue = "60728")] + pub fn into_raw(this: Self) -> *const T { + let result = Self::as_raw(&this); + mem::forget(this); + result + } + + /// Converts a raw pointer previously created by [`into_raw`] back into + /// `Weak`. + /// + /// This can be used to safely get a strong reference (by calling [`upgrade`] + /// later) or to deallocate the weak count by dropping the `Weak`. + /// + /// It takes ownership of one weak count. In case a [`null`] is passed, a dangling [`Weak`] is + /// returned. + /// + /// # Safety + /// + /// The pointer must represent one valid weak count. In other words, it must point to `T` which + /// is or *was* managed by an [`Arc`] and the weak count of that [`Arc`] must not have reached + /// 0. It is allowed for the strong count to be 0. + /// + /// # Examples + /// + /// ``` + /// #![feature(weak_into_raw)] + /// + /// use std::sync::{Arc, Weak}; + /// + /// let strong = Arc::new(42); + /// + /// let raw_1 = Weak::into_raw(Arc::downgrade(&strong)); + /// let raw_2 = Weak::into_raw(Arc::downgrade(&strong)); + /// + /// assert_eq!(2, Arc::weak_count(&strong)); + /// + /// assert_eq!(42, *Weak::upgrade(&unsafe { Weak::from_raw(raw_1) }).unwrap()); + /// assert_eq!(1, Arc::weak_count(&strong)); + /// + /// drop(strong); + /// + /// // Decrement the last weak count. + /// assert!(Weak::upgrade(&unsafe { Weak::from_raw(raw_2) }).is_none()); + /// ``` + /// + /// [`null`]: ../../std/ptr/fn.null.html + /// [`into_raw`]: struct.Weak.html#method.into_raw + /// [`upgrade`]: struct.Weak.html#method.upgrade + /// [`Weak`]: struct.Weak.html + /// [`Arc`]: struct.Arc.html + #[unstable(feature = "weak_into_raw", issue = "60728")] + pub unsafe fn from_raw(ptr: *const T) -> Self { + if ptr.is_null() { + Self::new() + } else { + // See Arc::from_raw for details + let offset = data_offset(ptr); + let fake_ptr = ptr as *mut ArcInner; + let ptr = set_data_ptr(fake_ptr, (ptr as *mut u8).offset(-offset)); + Weak { + ptr: NonNull::new(ptr).expect("Invalid pointer passed to from_raw"), + } + } + } } impl Weak { @@ -2150,3 +2284,21 @@ impl AsRef for Arc { #[stable(feature = "pin", since = "1.33.0")] impl Unpin for Arc { } + +/// Computes the offset of the data field within ArcInner. +unsafe fn data_offset(ptr: *const T) -> isize { + // Align the unsized value to the end of the ArcInner. + // Because it is ?Sized, it will always be the last field in memory. + let align = align_of_val(&*ptr); + let layout = Layout::new::>(); + (layout.size() + layout.padding_needed_for(align)) as isize +} + +/// Computes the offset of the data field within ArcInner. +/// +/// Unlike [`data_offset`], this doesn't need the pointer, but it works only on `T: Sized`. +fn data_offset_sized() -> isize { + let align = align_of::(); + let layout = Layout::new::>(); + (layout.size() + layout.padding_needed_for(align)) as isize +} -- cgit 1.4.1-3-g733a5 From 4f1dcb34dffc26a23fa8c2cac69a31d7557fd173 Mon Sep 17 00:00:00 2001 From: Michal 'vorner' Vaner Date: Sun, 19 May 2019 12:46:37 +0200 Subject: rc::Weak::{as,from,into}_raw Methods on the Weak to access it as a raw pointer to the data. --- src/liballoc/rc.rs | 162 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 156 insertions(+), 6 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 0dffb19476f..1f357a719bb 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -239,7 +239,7 @@ use core::fmt; use core::hash::{Hash, Hasher}; use core::intrinsics::abort; use core::marker::{self, Unpin, Unsize, PhantomData}; -use core::mem::{self, align_of_val, forget, size_of_val}; +use core::mem::{self, align_of, align_of_val, forget, size_of_val}; use core::ops::{Deref, Receiver, CoerceUnsized, DispatchFromDyn}; use core::pin::Pin; use core::ptr::{self, NonNull}; @@ -416,11 +416,7 @@ impl Rc { /// ``` #[stable(feature = "rc_raw", since = "1.17.0")] pub unsafe fn from_raw(ptr: *const T) -> Self { - // Align the unsized value to the end of the RcBox. - // Because it is ?Sized, it will always be the last field in memory. - let align = align_of_val(&*ptr); - let layout = Layout::new::>(); - let offset = (layout.size() + layout.padding_needed_for(align)) as isize; + let offset = data_offset(ptr); // Reverse the offset to find the original RcBox. let fake_ptr = ptr as *mut RcBox; @@ -1262,6 +1258,143 @@ impl Weak { ptr: NonNull::new(usize::MAX as *mut RcBox).expect("MAX is not 0"), } } + + /// Returns a raw pointer to the object `T` pointed to by this `Weak`. + /// + /// It is up to the caller to ensure that the object is still alive when accessing it through + /// the pointer. + /// + /// The pointer may be [`null`] or be dangling in case the object has already been destroyed. + /// + /// # Examples + /// + /// ``` + /// #![feature(weak_into_raw)] + /// + /// use std::rc::{Rc, Weak}; + /// use std::ptr; + /// + /// let strong = Rc::new(42); + /// let weak = Rc::downgrade(&strong); + /// // Both point to the same object + /// assert!(ptr::eq(&*strong, Weak::as_raw(&weak))); + /// // The strong here keeps it alive, so we can still access the object. + /// assert_eq!(42, unsafe { *Weak::as_raw(&weak) }); + /// + /// drop(strong); + /// // But not any more. We can do Weak::as_raw(&weak), but accessing the pointer would lead to + /// // undefined behaviour. + /// // assert_eq!(42, unsafe { *Weak::as_raw(&weak) }); + /// ``` + /// + /// [`null`]: ../../std/ptr/fn.null.html + #[unstable(feature = "weak_into_raw", issue = "60728")] + pub fn as_raw(this: &Self) -> *const T { + match this.inner() { + None => ptr::null(), + Some(inner) => { + let offset = data_offset_sized::(); + let ptr = inner as *const RcBox; + // Note: while the pointer we create may already point to dropped value, the + // allocation still lives (it must hold the weak point as long as we are alive). + // Therefore, the offset is OK to do, it won't get out of the allocation. + let ptr = unsafe { (ptr as *const u8).offset(offset) }; + ptr as *const T + } + } + } + + /// Consumes the `Weak` and turns it into a raw pointer. + /// + /// This converts the weak pointer into a raw pointer, preserving the original weak count. It + /// can be turned back into the `Weak` with [`from_raw`]. + /// + /// The same restrictions of accessing the target of the pointer as with + /// [`as_raw`] apply. + /// + /// # Examples + /// + /// ``` + /// #![feature(weak_into_raw)] + /// + /// use std::rc::{Rc, Weak}; + /// + /// let strong = Rc::new(42); + /// let weak = Rc::downgrade(&strong); + /// let raw = Weak::into_raw(weak); + /// + /// assert_eq!(1, Rc::weak_count(&strong)); + /// assert_eq!(42, unsafe { *raw }); + /// + /// drop(unsafe { Weak::from_raw(raw) }); + /// assert_eq!(0, Rc::weak_count(&strong)); + /// ``` + /// + /// [`from_raw`]: struct.Weak.html#method.from_raw + /// [`as_raw`]: struct.Weak.html#method.as_raw + #[unstable(feature = "weak_into_raw", issue = "60728")] + pub fn into_raw(this: Self) -> *const T { + let result = Self::as_raw(&this); + mem::forget(this); + result + } + + /// Converts a raw pointer previously created by [`into_raw`] back into `Weak`. + /// + /// This can be used to safely get a strong reference (by calling [`upgrade`] + /// later) or to deallocate the weak count by dropping the `Weak`. + /// + /// It takes ownership of one weak count. In case a [`null`] is passed, a dangling [`Weak`] is + /// returned. + /// + /// # Safety + /// + /// The pointer must represent one valid weak count. In other words, it must point to `T` which + /// is or *was* managed by an [`Rc`] and the weak count of that [`Rc`] must not have reached + /// 0. It is allowed for the strong count to be 0. + /// + /// # Examples + /// + /// ``` + /// #![feature(weak_into_raw)] + /// + /// use std::rc::{Rc, Weak}; + /// + /// let strong = Rc::new(42); + /// + /// let raw_1 = Weak::into_raw(Rc::downgrade(&strong)); + /// let raw_2 = Weak::into_raw(Rc::downgrade(&strong)); + /// + /// assert_eq!(2, Rc::weak_count(&strong)); + /// + /// assert_eq!(42, *Weak::upgrade(&unsafe { Weak::from_raw(raw_1) }).unwrap()); + /// assert_eq!(1, Rc::weak_count(&strong)); + /// + /// drop(strong); + /// + /// // Decrement the last weak count. + /// assert!(Weak::upgrade(&unsafe { Weak::from_raw(raw_2) }).is_none()); + /// ``` + /// + /// [`null`]: ../../std/ptr/fn.null.html + /// [`into_raw`]: struct.Weak.html#method.into_raw + /// [`upgrade`]: struct.Weak.html#method.upgrade + /// [`Rc`]: struct.Rc.html + /// [`Weak`]: struct.Weak.html + #[unstable(feature = "weak_into_raw", issue = "60728")] + pub unsafe fn from_raw(ptr: *const T) -> Self { + if ptr.is_null() { + Self::new() + } else { + // See Rc::from_raw for details + let offset = data_offset(ptr); + let fake_ptr = ptr as *mut RcBox; + let ptr = set_data_ptr(fake_ptr, (ptr as *mut u8).offset(-offset)); + Weak { + ptr: NonNull::new(ptr).expect("Invalid pointer passed to from_raw"), + } + } + } } pub(crate) fn is_dangling(ptr: NonNull) -> bool { @@ -2007,3 +2140,20 @@ impl AsRef for Rc { #[stable(feature = "pin", since = "1.33.0")] impl Unpin for Rc { } + +unsafe fn data_offset(ptr: *const T) -> isize { + // Align the unsized value to the end of the RcBox. + // Because it is ?Sized, it will always be the last field in memory. + let align = align_of_val(&*ptr); + let layout = Layout::new::>(); + (layout.size() + layout.padding_needed_for(align)) as isize +} + +/// Computes the offset of the data field within ArcInner. +/// +/// Unlike [`data_offset`], this doesn't need the pointer, but it works only on `T: Sized`. +fn data_offset_sized() -> isize { + let align = align_of::(); + let layout = Layout::new::>(); + (layout.size() + layout.padding_needed_for(align)) as isize +} -- cgit 1.4.1-3-g733a5 From 84ae9699c6bb60b07329b1cf5e644d3d30eb24f3 Mon Sep 17 00:00:00 2001 From: Aaron Loucks Date: Sun, 26 May 2019 22:41:34 -0400 Subject: Prevent Vec::drain_filter from double dropping on panic Fixes: #60977 --- src/liballoc/tests/vec.rs | 99 +++++++++++++++++++++++++++++++++++++++++++++++ src/liballoc/vec.rs | 73 +++++++++++++++++++++++++++++----- 2 files changed, 162 insertions(+), 10 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/tests/vec.rs b/src/liballoc/tests/vec.rs index 5ddac673c9f..c0967cd374d 100644 --- a/src/liballoc/tests/vec.rs +++ b/src/liballoc/tests/vec.rs @@ -945,6 +945,105 @@ fn drain_filter_complex() { } } +#[test] +fn drain_filter_consumed_panic() { + use std::rc::Rc; + use std::sync::Mutex; + + struct Check { + index: usize, + drop_counts: Rc>>, + }; + + impl Drop for Check { + fn drop(&mut self) { + self.drop_counts.lock().unwrap()[self.index] += 1; + println!("drop: {}", self.index); + } + } + + let check_count = 10; + let drop_counts = Rc::new(Mutex::new(vec![0_usize; check_count])); + let mut data: Vec = (0..check_count) + .map(|index| Check { index, drop_counts: Rc::clone(&drop_counts) }) + .collect(); + + let _ = std::panic::catch_unwind(move || { + let filter = |c: &mut Check| { + if c.index == 2 { + panic!("panic at index: {}", c.index); + } + // Verify that if the filter could panic again on another element + // that it would not cause a double panic and all elements of the + // vec would still be dropped exactly once. + if c.index == 4 { + panic!("panic at index: {}", c.index); + } + c.index < 6 + }; + let drain = data.drain_filter(filter); + + // NOTE: The DrainFilter is explictly consumed + drain.for_each(drop); + }); + + let drop_counts = drop_counts.lock().unwrap(); + assert_eq!(check_count, drop_counts.len()); + + for (index, count) in drop_counts.iter().cloned().enumerate() { + assert_eq!(1, count, "unexpected drop count at index: {} (count: {})", index, count); + } +} + +#[test] +fn drain_filter_unconsumed_panic() { + use std::rc::Rc; + use std::sync::Mutex; + + struct Check { + index: usize, + drop_counts: Rc>>, + }; + + impl Drop for Check { + fn drop(&mut self) { + self.drop_counts.lock().unwrap()[self.index] += 1; + println!("drop: {}", self.index); + } + } + + let check_count = 10; + let drop_counts = Rc::new(Mutex::new(vec![0_usize; check_count])); + let mut data: Vec = (0..check_count) + .map(|index| Check { index, drop_counts: Rc::clone(&drop_counts) }) + .collect(); + + let _ = std::panic::catch_unwind(move || { + let filter = |c: &mut Check| { + if c.index == 2 { + panic!("panic at index: {}", c.index); + } + // Verify that if the filter could panic again on another element + // that it would not cause a double panic and all elements of the + // vec would still be dropped exactly once. + if c.index == 4 { + panic!("panic at index: {}", c.index); + } + c.index < 6 + }; + let _drain = data.drain_filter(filter); + + // NOTE: The DrainFilter is dropped without being consumed + }); + + let drop_counts = drop_counts.lock().unwrap(); + assert_eq!(check_count, drop_counts.len()); + + for (index, count) in drop_counts.iter().cloned().enumerate() { + assert_eq!(1, count, "unexpected drop count at index: {} (count: {})", index, count); + } +} + #[test] fn test_reserve_exact() { // This is all the same as test_reserve diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 5cb91395b7b..adc0929fdbe 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -2120,6 +2120,7 @@ impl Vec { del: 0, old_len, pred: filter, + panic_flag: false, } } } @@ -2751,6 +2752,7 @@ pub struct DrainFilter<'a, T, F> del: usize, old_len: usize, pred: F, + panic_flag: bool, } #[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] @@ -2760,21 +2762,34 @@ impl Iterator for DrainFilter<'_, T, F> type Item = T; fn next(&mut self) -> Option { + struct SetIdxOnDrop<'a> { + idx: &'a mut usize, + new_idx: usize, + } + + impl<'a> Drop for SetIdxOnDrop<'a> { + fn drop(&mut self) { + *self.idx = self.new_idx; + } + } + unsafe { - while self.idx != self.old_len { + while self.idx < self.old_len { let i = self.idx; - self.idx += 1; let v = slice::from_raw_parts_mut(self.vec.as_mut_ptr(), self.old_len); - if (self.pred)(&mut v[i]) { + let mut set_idx = SetIdxOnDrop { new_idx: self.idx, idx: &mut self.idx }; + self.panic_flag = true; + let drained = (self.pred)(&mut v[i]); + self.panic_flag = false; + set_idx.new_idx += 1; + if drained { self.del += 1; return Some(ptr::read(&v[i])); - } else if self.del > 0 { + } + else if self.del > 0 { let del = self.del; let src: *const T = &v[i]; let dst: *mut T = &mut v[i - del]; - // This is safe because self.vec has length 0 - // thus its elements will not have Drop::drop - // called on them in the event of a panic. ptr::copy_nonoverlapping(src, dst, 1); } } @@ -2792,9 +2807,47 @@ impl Drop for DrainFilter<'_, T, F> where F: FnMut(&mut T) -> bool, { fn drop(&mut self) { - self.for_each(drop); - unsafe { - self.vec.set_len(self.old_len - self.del); + // If the predicate panics, we still need to backshift everything + // down after the last successfully drained element, but no additional + // elements are drained or checked. + struct BackshiftOnDrop<'a, 'b, T, F> + where + F: FnMut(&mut T) -> bool, + { + drain: &'b mut DrainFilter<'a, T, F>, + } + + impl<'a, 'b, T, F> Drop for BackshiftOnDrop<'a, 'b, T, F> + where + F: FnMut(&mut T) -> bool + { + fn drop(&mut self) { + unsafe { + while self.drain.idx < self.drain.old_len { + let i = self.drain.idx; + self.drain.idx += 1; + let v = slice::from_raw_parts_mut( + self.drain.vec.as_mut_ptr(), + self.drain.old_len, + ); + if self.drain.del > 0 { + let del = self.drain.del; + let src: *const T = &v[i]; + let dst: *mut T = &mut v[i - del]; + ptr::copy_nonoverlapping(src, dst, 1); + } + } + self.drain.vec.set_len(self.drain.old_len - self.drain.del); + } + } + } + + let backshift = BackshiftOnDrop { + drain: self + }; + + if !backshift.drain.panic_flag { + backshift.drain.for_each(drop); } } } -- cgit 1.4.1-3-g733a5 From a23a77fb19b24adb22d0a3d3886acac1a7a31f68 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 27 May 2019 09:43:20 +0300 Subject: avoid materializing unintialized Boxes in RawVec --- src/liballoc/boxed.rs | 9 ++++++--- src/liballoc/raw_vec.rs | 10 ++++++---- 2 files changed, 12 insertions(+), 7 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index bf8f5b8b91a..5affdbdb7e9 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -546,9 +546,12 @@ impl From<&[T]> for Box<[T]> { /// println!("{:?}", boxed_slice); /// ``` fn from(slice: &[T]) -> Box<[T]> { - let mut boxed = unsafe { RawVec::with_capacity(slice.len()).into_box() }; - boxed.copy_from_slice(slice); - boxed + let len = slice.len(); + let buf = RawVec::with_capacity(len); + unsafe { + ptr::copy_nonoverlapping(slice.as_ptr(), buf.ptr(), len); + buf.into_box() + } } } diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs index d1fc5ac3b30..0454a564435 100644 --- a/src/liballoc/raw_vec.rs +++ b/src/liballoc/raw_vec.rs @@ -685,12 +685,14 @@ impl RawVec { impl RawVec { /// Converts the entire buffer into `Box<[T]>`. /// - /// While it is not *strictly* Undefined Behavior to call - /// this procedure while some of the RawVec is uninitialized, - /// it certainly makes it trivial to trigger it. - /// /// Note that this will correctly reconstitute any `cap` changes /// that may have been performed. (see description of type for details) + /// + /// # Undefined Behavior + /// + /// All elements of `RawVec` must be initialized. Notice that + /// the rules around uninitialized boxed values are not finalized yet, + /// but until they are, it is advisable to avoid them. pub unsafe fn into_box(self) -> Box<[T]> { // NOTE: not calling `cap()` here, actually using the real `cap` field! let slice = slice::from_raw_parts_mut(self.ptr(), self.cap); -- cgit 1.4.1-3-g733a5 From 17a517a42a403ec0275f1d5d286038b0acc758b6 Mon Sep 17 00:00:00 2001 From: Aaron Loucks Date: Mon, 27 May 2019 11:30:23 -0400 Subject: Fix formatting nit --- src/liballoc/vec.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index adc0929fdbe..e6ef5a8ebc9 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -2785,8 +2785,7 @@ impl Iterator for DrainFilter<'_, T, F> if drained { self.del += 1; return Some(ptr::read(&v[i])); - } - else if self.del > 0 { + } else if self.del > 0 { let del = self.del; let src: *const T = &v[i]; let dst: *mut T = &mut v[i - del]; -- cgit 1.4.1-3-g733a5 From 53d46ae96e2e8ac153680cb6711c9935d6dfe0f6 Mon Sep 17 00:00:00 2001 From: Aaron Loucks Date: Mon, 27 May 2019 11:47:14 -0400 Subject: Add drain_filter_unconsumed test --- src/liballoc/tests/vec.rs | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/liballoc') diff --git a/src/liballoc/tests/vec.rs b/src/liballoc/tests/vec.rs index c0967cd374d..a89b8aa4a71 100644 --- a/src/liballoc/tests/vec.rs +++ b/src/liballoc/tests/vec.rs @@ -1044,6 +1044,14 @@ fn drain_filter_unconsumed_panic() { } } +#[test] +fn drain_filter_unconsumed() { + let mut vec = vec![1, 2, 3, 4]; + let drain = vec.drain_filter(|&mut x| x % 2 != 0); + drop(drain); + assert_eq!(vec, [2, 4]); +} + #[test] fn test_reserve_exact() { // This is all the same as test_reserve -- cgit 1.4.1-3-g733a5 From b13ae65b8b995bc851708380d80eae301c39f1c6 Mon Sep 17 00:00:00 2001 From: Aaron Loucks Date: Mon, 27 May 2019 12:47:47 -0400 Subject: Refactor DrainFilter::next and update comments --- src/liballoc/vec.rs | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index e6ef5a8ebc9..99116ac2d2f 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -2762,26 +2762,17 @@ impl Iterator for DrainFilter<'_, T, F> type Item = T; fn next(&mut self) -> Option { - struct SetIdxOnDrop<'a> { - idx: &'a mut usize, - new_idx: usize, - } - - impl<'a> Drop for SetIdxOnDrop<'a> { - fn drop(&mut self) { - *self.idx = self.new_idx; - } - } - unsafe { while self.idx < self.old_len { let i = self.idx; let v = slice::from_raw_parts_mut(self.vec.as_mut_ptr(), self.old_len); - let mut set_idx = SetIdxOnDrop { new_idx: self.idx, idx: &mut self.idx }; self.panic_flag = true; let drained = (self.pred)(&mut v[i]); self.panic_flag = false; - set_idx.new_idx += 1; + // Update the index *after* the predicate is called. If the index + // is updated prior and the predicate panics, the element at this + // index would be leaked. + self.idx += 1; if drained { self.del += 1; return Some(ptr::read(&v[i])); @@ -2806,9 +2797,6 @@ impl Drop for DrainFilter<'_, T, F> where F: FnMut(&mut T) -> bool, { fn drop(&mut self) { - // If the predicate panics, we still need to backshift everything - // down after the last successfully drained element, but no additional - // elements are drained or checked. struct BackshiftOnDrop<'a, 'b, T, F> where F: FnMut(&mut T) -> bool, @@ -2822,6 +2810,12 @@ impl Drop for DrainFilter<'_, T, F> { fn drop(&mut self) { unsafe { + // Backshift any unprocessed elements, preventing double-drop + // of any element that *should* have been previously overwritten + // but was not due to a panic in the filter predicate. This is + // implemented via drop so that it's guaranteed to run even in + // the event of a panic while consuming the remainder of the + // DrainFilter. while self.drain.idx < self.drain.old_len { let i = self.drain.idx; self.drain.idx += 1; @@ -2845,6 +2839,9 @@ impl Drop for DrainFilter<'_, T, F> drain: self }; + // Attempt to consume any remaining elements if the filter predicate + // has not yet panicked. We'll backshift any remaining elements + // whether we've already panicked or if the consumption here panics. if !backshift.drain.panic_flag { backshift.drain.for_each(drop); } -- cgit 1.4.1-3-g733a5 From f5ab0313fe9330717e6697b148bcdd0bb78f3508 Mon Sep 17 00:00:00 2001 From: Aaron Loucks Date: Mon, 27 May 2019 12:55:59 -0400 Subject: Disable drain_filter tests that require catch_unwind on miri --- src/liballoc/tests/vec.rs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/liballoc') diff --git a/src/liballoc/tests/vec.rs b/src/liballoc/tests/vec.rs index a89b8aa4a71..07ee3741268 100644 --- a/src/liballoc/tests/vec.rs +++ b/src/liballoc/tests/vec.rs @@ -946,6 +946,7 @@ fn drain_filter_complex() { } #[test] +#[cfg(not(miri))] // Miri does not support catching panics fn drain_filter_consumed_panic() { use std::rc::Rc; use std::sync::Mutex; @@ -996,6 +997,7 @@ fn drain_filter_consumed_panic() { } #[test] +#[cfg(not(miri))] // Miri does not support catching panics fn drain_filter_unconsumed_panic() { use std::rc::Rc; use std::sync::Mutex; -- cgit 1.4.1-3-g733a5 From 0653e78ae1b35eb50e06423052a34d807f1ac2af Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 27 May 2019 09:43:20 +0300 Subject: make Box::clone simpler & safer --- src/liballoc/boxed.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 5affdbdb7e9..2f45ec7d643 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -395,11 +395,9 @@ impl Clone for Box { #[stable(feature = "box_slice_clone", since = "1.3.0")] impl Clone for Box { fn clone(&self) -> Self { - let len = self.len(); - let buf = RawVec::with_capacity(len); + let buf: Box<[u8]> = self.as_bytes().into(); unsafe { - ptr::copy_nonoverlapping(self.as_ptr(), buf.ptr(), len); - from_boxed_utf8_unchecked(buf.into_box()) + from_boxed_utf8_unchecked(buf) } } } -- cgit 1.4.1-3-g733a5 From fe31ad38cb5c6fba5be871ab63082d7cdf430374 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 27 May 2019 22:42:50 +0300 Subject: Update src/liballoc/boxed.rs Co-Authored-By: Ralf Jung --- src/liballoc/boxed.rs | 1 + 1 file changed, 1 insertion(+) (limited to 'src/liballoc') diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 2f45ec7d643..76b660fba68 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -395,6 +395,7 @@ impl Clone for Box { #[stable(feature = "box_slice_clone", since = "1.3.0")] impl Clone for Box { fn clone(&self) -> Self { + // this makes a copy of the data let buf: Box<[u8]> = self.as_bytes().into(); unsafe { from_boxed_utf8_unchecked(buf) -- cgit 1.4.1-3-g733a5 From 645f685e1b05f3f62de26ea1579861e83cbd0d74 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 27 May 2019 22:40:13 +0200 Subject: Box::into_vec: use Box::into_raw instead of mem::forget --- src/liballoc/slice.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index 8768f1ff081..aeb7f90d3e6 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -137,17 +137,16 @@ pub use hack::to_vec; // `core::slice::SliceExt` - we need to supply these functions for the // `test_permutations` test mod hack { - use core::mem; - use crate::boxed::Box; use crate::vec::Vec; #[cfg(test)] use crate::string::ToString; - pub fn into_vec(mut b: Box<[T]>) -> Vec { + pub fn into_vec(b: Box<[T]>) -> Vec { unsafe { - let xs = Vec::from_raw_parts(b.as_mut_ptr(), b.len(), b.len()); - mem::forget(b); + let len = b.len(); + let b = Box::into_raw(b); + let xs = Vec::from_raw_parts(b as *mut T, len, len); xs } } -- cgit 1.4.1-3-g733a5 From 0c35c699d43ba24943bb8f38986f84c4be676dc3 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Thu, 30 May 2019 18:00:17 +0000 Subject: Stabilize iter_nth_back feature --- src/liballoc/lib.rs | 1 - src/libcore/iter/traits/double_ended.rs | 5 +---- src/libcore/tests/lib.rs | 1 - 3 files changed, 1 insertion(+), 6 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index d90036eaf49..bfc008e14a4 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -112,7 +112,6 @@ #![feature(maybe_uninit_extra, maybe_uninit_slice, maybe_uninit_array)] #![feature(alloc_layout_extra)] #![feature(try_trait)] -#![feature(iter_nth_back)] // Allow testing this library diff --git a/src/libcore/iter/traits/double_ended.rs b/src/libcore/iter/traits/double_ended.rs index 06de95c0827..2c1aeb5690a 100644 --- a/src/libcore/iter/traits/double_ended.rs +++ b/src/libcore/iter/traits/double_ended.rs @@ -88,7 +88,6 @@ pub trait DoubleEndedIterator: Iterator { /// Basic usage: /// /// ``` - /// #![feature(iter_nth_back)] /// let a = [1, 2, 3]; /// assert_eq!(a.iter().nth_back(2), Some(&1)); /// ``` @@ -96,7 +95,6 @@ pub trait DoubleEndedIterator: Iterator { /// Calling `nth_back()` multiple times doesn't rewind the iterator: /// /// ``` - /// #![feature(iter_nth_back)] /// let a = [1, 2, 3]; /// /// let mut iter = a.iter(); @@ -108,12 +106,11 @@ pub trait DoubleEndedIterator: Iterator { /// Returning `None` if there are less than `n + 1` elements: /// /// ``` - /// #![feature(iter_nth_back)] /// let a = [1, 2, 3]; /// assert_eq!(a.iter().nth_back(10), None); /// ``` #[inline] - #[unstable(feature = "iter_nth_back", issue = "56995")] + #[stable(feature = "iter_nth_back", since = "1.37.0")] fn nth_back(&mut self, mut n: usize) -> Option { for x in self.rev() { if n == 0 { return Some(x) } diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index c617596aba8..0dba2bed62c 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -10,7 +10,6 @@ #![feature(fmt_internals)] #![feature(hashmap_internals)] #![feature(is_sorted)] -#![feature(iter_nth_back)] #![feature(iter_once_with)] #![feature(pattern)] #![feature(range_is_empty)] -- cgit 1.4.1-3-g733a5 From dfd9d0429cbea6133d240a37d6f4edf2a5a90a85 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sat, 1 Jun 2019 00:23:26 -0700 Subject: Add an unusual-conversion example to to_uppercase MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Like how to_lowercase has ὈΔΥΣΣΕΎΣ. --- src/liballoc/str.rs | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/liballoc') diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs index f66ff894ae8..0c7d2b837a3 100644 --- a/src/liballoc/str.rs +++ b/src/liballoc/str.rs @@ -431,6 +431,13 @@ impl str { /// /// assert_eq!(new_year, new_year.to_uppercase()); /// ``` + /// + /// One character can become multiple: + /// ``` + /// let s = "tschüß"; + /// + /// assert_eq!("TSCHÜSS", s.to_uppercase()); + /// ``` #[stable(feature = "unicode_case_mapping", since = "1.2.0")] pub fn to_uppercase(&self) -> String { let mut s = String::with_capacity(self.len()); -- cgit 1.4.1-3-g733a5 From 7bdc38d3a49d57fd56d2e69c8412f688b715f8ab Mon Sep 17 00:00:00 2001 From: Felix Rabe Date: Sat, 1 Jun 2019 11:26:08 +0200 Subject: Succinctify splice docs --- src/liballoc/vec.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 5cb91395b7b..92fe0834dd0 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -2018,16 +2018,14 @@ impl Vec { /// with the given `replace_with` iterator and yields the removed items. /// `replace_with` does not need to be the same length as `range`. /// - /// Note 1: The element range is removed even if the iterator is not - /// consumed until the end. + /// The element range is removed even if the iterator is not consumed until the end. /// - /// Note 2: It is unspecified how many elements are removed from the vector, + /// It is unspecified how many elements are removed from the vector /// if the `Splice` value is leaked. /// - /// Note 3: The input iterator `replace_with` is only consumed - /// when the `Splice` value is dropped. + /// The input iterator `replace_with` is only consumed when the `Splice` value is dropped. /// - /// Note 4: This is optimal if: + /// This is optimal if: /// /// * The tail (elements in the vector after `range`) is empty, /// * or `replace_with` yields fewer elements than `range`’s length -- cgit 1.4.1-3-g733a5 From 74a6d1c821a37a407d2b2bc701d62d0b460b9215 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 8 Jun 2019 11:36:30 +0300 Subject: Turn `#[allocator]` into a built-in attribute and rename it to `#[rustc_allocator]` --- src/liballoc/alloc.rs | 3 +- src/liballoc/lib.rs | 2 +- src/librustc/hir/mod.rs | 2 +- src/librustc_typeck/collect.rs | 2 +- src/libsyntax/feature_gate.rs | 5 +++ src/libsyntax_pos/symbol.rs | 1 + src/test/codegen/function-arguments.rs | 4 +- src/test/run-pass/auxiliary/allocator-dummy.rs | 59 -------------------------- 8 files changed, 13 insertions(+), 65 deletions(-) delete mode 100644 src/test/run-pass/auxiliary/allocator-dummy.rs (limited to 'src/liballoc') diff --git a/src/liballoc/alloc.rs b/src/liballoc/alloc.rs index 41ff06d70ff..755feb84962 100644 --- a/src/liballoc/alloc.rs +++ b/src/liballoc/alloc.rs @@ -15,7 +15,8 @@ extern "Rust" { // them from the `#[global_allocator]` attribute if there is one, or uses the // default implementations in libstd (`__rdl_alloc` etc in `src/libstd/alloc.rs`) // otherwise. - #[allocator] + #[cfg_attr(bootstrap, allocator)] + #[cfg_attr(not(bootstrap), rustc_allocator)] #[rustc_allocator_nounwind] fn __rust_alloc(size: usize, align: usize) -> *mut u8; #[rustc_allocator_nounwind] diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index bfc008e14a4..c530ac24275 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -79,7 +79,7 @@ #![feature(coerce_unsized)] #![feature(dispatch_from_dyn)] #![feature(core_intrinsics)] -#![feature(custom_attribute)] +#![cfg_attr(bootstrap, feature(custom_attribute))] #![feature(dropck_eyepatch)] #![feature(exact_size_is_empty)] #![feature(fmt_internals)] diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 2aaf5ec775d..27ee664aa5f 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -2574,7 +2574,7 @@ bitflags! { /// `#[cold]`: a hint to LLVM that this function, when called, is never on /// the hot path. const COLD = 1 << 0; - /// `#[allocator]`: a hint to LLVM that the pointer returned from this + /// `#[rustc_allocator]`: a hint to LLVM that the pointer returned from this /// function is never null. const ALLOCATOR = 1 << 1; /// `#[unwind]`: an indicator that this function may unwind despite what diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 2751cd0a37e..f738f90b31e 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -2445,7 +2445,7 @@ fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Codegen for attr in attrs.iter() { if attr.check_name(sym::cold) { codegen_fn_attrs.flags |= CodegenFnAttrFlags::COLD; - } else if attr.check_name(sym::allocator) { + } else if attr.check_name(sym::rustc_allocator) { codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR; } else if attr.check_name(sym::unwind) { codegen_fn_attrs.flags |= CodegenFnAttrFlags::UNWIND; diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index b41b91c7631..ac4a7271221 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -1331,6 +1331,11 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ "internal implementation detail", cfg_fn!(rustc_attrs))), + (sym::rustc_allocator, Whitelisted, template!(Word), Gated(Stability::Unstable, + sym::rustc_attrs, + "internal implementation detail", + cfg_fn!(rustc_attrs))), + // FIXME: #14408 whitelist docs since rustdoc looks at them ( sym::doc, diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 49123e4cc30..224b85a11f9 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -513,6 +513,7 @@ symbols! { rust_2018_preview, rust_begin_unwind, rustc, + rustc_allocator, rustc_allocator_nounwind, rustc_allow_const_fn_ptr, rustc_args_required_const, diff --git a/src/test/codegen/function-arguments.rs b/src/test/codegen/function-arguments.rs index c2d697fd046..bd121ef24ad 100644 --- a/src/test/codegen/function-arguments.rs +++ b/src/test/codegen/function-arguments.rs @@ -2,7 +2,7 @@ // ignore-tidy-linelength #![crate_type = "lib"] -#![feature(custom_attribute)] +#![feature(rustc_attrs)] pub struct S { _field: [i32; 8], @@ -146,7 +146,7 @@ pub fn enum_id_2(x: Option) -> Option { // CHECK: noalias i8* @allocator() #[no_mangle] -#[allocator] +#[rustc_allocator] pub fn allocator() -> *const i8 { std::ptr::null() } diff --git a/src/test/run-pass/auxiliary/allocator-dummy.rs b/src/test/run-pass/auxiliary/allocator-dummy.rs deleted file mode 100644 index bedf3020c8b..00000000000 --- a/src/test/run-pass/auxiliary/allocator-dummy.rs +++ /dev/null @@ -1,59 +0,0 @@ -// no-prefer-dynamic - -#![feature(allocator, core_intrinsics, panic_unwind)] -#![allocator] -#![crate_type = "rlib"] -#![no_std] - -extern crate unwind; - -pub static mut HITS: usize = 0; - -type size_t = usize; - -extern { - fn malloc(size: usize) -> *mut u8; - fn free(ptr: *mut u8); - fn calloc(size: usize, amt: usize) -> *mut u8; - fn realloc(ptr: *mut u8, size: usize) -> *mut u8; -} - -#[no_mangle] -pub extern fn __rust_allocate(size: usize, align: usize) -> *mut u8 { - unsafe { - HITS += 1; - malloc(size as size_t) as *mut u8 - } -} - -#[no_mangle] -pub extern fn __rust_allocate_zeroed(size: usize, _align: usize) -> *mut u8 { - unsafe { calloc(size as size_t, 1) as *mut u8 } -} - -#[no_mangle] -pub extern fn __rust_deallocate(ptr: *mut u8, old_size: usize, align: usize) { - unsafe { - HITS += 1; - free(ptr as *mut _) - } -} - -#[no_mangle] -pub extern fn __rust_reallocate(ptr: *mut u8, old_size: usize, size: usize, - align: usize) -> *mut u8 { - unsafe { - realloc(ptr as *mut _, size as size_t) as *mut u8 - } -} - -#[no_mangle] -pub extern fn __rust_reallocate_inplace(ptr: *mut u8, old_size: usize, - size: usize, align: usize) -> usize { - unsafe { core::intrinsics::abort() } -} - -#[no_mangle] -pub extern fn __rust_usable_size(size: usize, align: usize) -> usize { - unsafe { core::intrinsics::abort() } -} -- cgit 1.4.1-3-g733a5 From cc2a2808d078b0a7d49f7a89fa7d14ead1ebc0df Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sat, 1 Jun 2019 17:29:05 -0700 Subject: Add some Vec <-> VecDeque documentation These are more than just `.into_iter().collect()`, so talk about some of their nuances. --- src/liballoc/collections/vec_deque.rs | 53 +++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) (limited to 'src/liballoc') diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index 31e49d06a7b..8cda28a5e40 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -2707,6 +2707,33 @@ impl fmt::Debug for VecDeque { } } +/// Turn a `Vec` into a `VecDeque`. +/// +/// This avoids reallocating where possible, but the conditions for that are +/// strict, and subject to change, so shouldn't be relied upon unless the +/// `Vec` came from `From` has hasn't been reallocated. +/// +/// # Examples +/// +/// ``` +/// use std::collections::VecDeque; +/// +/// // Start with a VecDeque +/// let deque: VecDeque<_> = (1..5).collect(); +/// +/// // Turn it into a Vec (no allocation needed) +/// let mut vec = Vec::from(deque); +/// +/// // modify it, being careful to not trigger reallocation +/// vec.pop(); +/// vec.push(100); +/// +/// // Turn it back into a VecDeque (no allocation needed) +/// let ptr = vec.as_ptr(); +/// let deque = VecDeque::from(vec); +/// assert_eq!(deque, [1, 2, 3, 100]); +/// assert_eq!(deque.as_slices().0.as_ptr(), ptr); +/// ``` #[stable(feature = "vecdeque_vec_conversions", since = "1.10.0")] impl From> for VecDeque { fn from(mut other: Vec) -> Self { @@ -2733,6 +2760,32 @@ impl From> for VecDeque { } } +/// Turn a `VecDeque` into a `Vec`. +/// +/// This never needs to re-allocate, but does need to do O(n) data movement if +/// the circular buffer doesn't happen to be at the beginning of the allocation. +/// +/// # Examples +/// +/// ``` +/// use std::collections::VecDeque; +/// +/// // This one is O(1) +/// let deque: VecDeque<_> = (1..5).collect(); +/// let ptr = deque.as_slices().0.as_ptr(); +/// let vec = Vec::from(deque); +/// assert_eq!(vec, [1, 2, 3, 4]); +/// assert_eq!(vec.as_ptr(), ptr); +/// +/// // This one need data rearranging +/// let mut deque: VecDeque<_> = (1..5).collect(); +/// deque.push_front(9); +/// deque.push_front(8); +/// let ptr = deque.as_slices().1.as_ptr(); +/// let vec = Vec::from(deque); +/// assert_eq!(vec, [8, 9, 1, 2, 3, 4]); +/// assert_eq!(vec.as_ptr(), ptr); +/// ``` #[stable(feature = "vecdeque_vec_conversions", since = "1.10.0")] impl From> for Vec { fn from(other: VecDeque) -> Self { -- cgit 1.4.1-3-g733a5 From 2da4f9ad5ed80bb1488377711699c5f320ae89db Mon Sep 17 00:00:00 2001 From: scottmcm Date: Sat, 1 Jun 2019 19:47:50 -0700 Subject: Apply suggestions from code review Co-Authored-By: Mazdak Farrokhzad --- src/liballoc/collections/vec_deque.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index 8cda28a5e40..d1c9de7c83c 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -2707,28 +2707,28 @@ impl fmt::Debug for VecDeque { } } -/// Turn a `Vec` into a `VecDeque`. +/// Turn a `Vec` into a `VecDeque`. /// /// This avoids reallocating where possible, but the conditions for that are -/// strict, and subject to change, so shouldn't be relied upon unless the -/// `Vec` came from `From` has hasn't been reallocated. +/// strict, and subject to change, and so shouldn't be relied upon unless the +/// `Vec` came from `From>` has hasn't been reallocated. /// /// # Examples /// /// ``` /// use std::collections::VecDeque; /// -/// // Start with a VecDeque +/// // Start with a `VecDeque`. /// let deque: VecDeque<_> = (1..5).collect(); /// -/// // Turn it into a Vec (no allocation needed) +/// // Turn it into a `Vec` with no allocation needed. /// let mut vec = Vec::from(deque); /// -/// // modify it, being careful to not trigger reallocation +/// // Modify it, being careful not to trigger reallocation. /// vec.pop(); /// vec.push(100); /// -/// // Turn it back into a VecDeque (no allocation needed) +/// // Turn it back into a `VecDeque` with no allocation needed. /// let ptr = vec.as_ptr(); /// let deque = VecDeque::from(vec); /// assert_eq!(deque, [1, 2, 3, 100]); @@ -2760,7 +2760,7 @@ impl From> for VecDeque { } } -/// Turn a `VecDeque` into a `Vec`. +/// Turn a `VecDeque` into a `Vec`. /// /// This never needs to re-allocate, but does need to do O(n) data movement if /// the circular buffer doesn't happen to be at the beginning of the allocation. @@ -2770,14 +2770,14 @@ impl From> for VecDeque { /// ``` /// use std::collections::VecDeque; /// -/// // This one is O(1) +/// // This one is O(1). /// let deque: VecDeque<_> = (1..5).collect(); /// let ptr = deque.as_slices().0.as_ptr(); /// let vec = Vec::from(deque); /// assert_eq!(vec, [1, 2, 3, 4]); /// assert_eq!(vec.as_ptr(), ptr); /// -/// // This one need data rearranging +/// // This one needs data rearranging. /// let mut deque: VecDeque<_> = (1..5).collect(); /// deque.push_front(9); /// deque.push_front(8); -- cgit 1.4.1-3-g733a5 From 1f4a262d85e4a87ebbdded023b2422cd41ce3fef Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sat, 1 Jun 2019 19:52:18 -0700 Subject: Put the docs on the methods instead of the impls Since simulacrum suggested (on Discord) they're better there. --- src/liballoc/collections/vec_deque.rs | 106 +++++++++++++++++----------------- 1 file changed, 53 insertions(+), 53 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index d1c9de7c83c..79a36d7248d 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -2707,35 +2707,35 @@ impl fmt::Debug for VecDeque { } } -/// Turn a `Vec` into a `VecDeque`. -/// -/// This avoids reallocating where possible, but the conditions for that are -/// strict, and subject to change, and so shouldn't be relied upon unless the -/// `Vec` came from `From>` has hasn't been reallocated. -/// -/// # Examples -/// -/// ``` -/// use std::collections::VecDeque; -/// -/// // Start with a `VecDeque`. -/// let deque: VecDeque<_> = (1..5).collect(); -/// -/// // Turn it into a `Vec` with no allocation needed. -/// let mut vec = Vec::from(deque); -/// -/// // Modify it, being careful not to trigger reallocation. -/// vec.pop(); -/// vec.push(100); -/// -/// // Turn it back into a `VecDeque` with no allocation needed. -/// let ptr = vec.as_ptr(); -/// let deque = VecDeque::from(vec); -/// assert_eq!(deque, [1, 2, 3, 100]); -/// assert_eq!(deque.as_slices().0.as_ptr(), ptr); -/// ``` #[stable(feature = "vecdeque_vec_conversions", since = "1.10.0")] impl From> for VecDeque { + /// Turn a `Vec` into a `VecDeque`. + /// + /// This avoids reallocating where possible, but the conditions for that are + /// strict, and subject to change, and so shouldn't be relied upon unless the + /// `Vec` came from `From>` has hasn't been reallocated. + /// + /// # Examples + /// + /// ``` + /// use std::collections::VecDeque; + /// + /// // Start with a `VecDeque`. + /// let deque: VecDeque<_> = (1..5).collect(); + /// + /// // Turn it into a `Vec` with no allocation needed. + /// let mut vec = Vec::from(deque); + /// + /// // Modify it, being careful not to trigger reallocation. + /// vec.pop(); + /// vec.push(100); + /// + /// // Turn it back into a `VecDeque` with no allocation needed. + /// let ptr = vec.as_ptr(); + /// let deque = VecDeque::from(vec); + /// assert_eq!(deque, [1, 2, 3, 100]); + /// assert_eq!(deque.as_slices().0.as_ptr(), ptr); + /// ``` fn from(mut other: Vec) -> Self { unsafe { let other_buf = other.as_mut_ptr(); @@ -2760,34 +2760,34 @@ impl From> for VecDeque { } } -/// Turn a `VecDeque` into a `Vec`. -/// -/// This never needs to re-allocate, but does need to do O(n) data movement if -/// the circular buffer doesn't happen to be at the beginning of the allocation. -/// -/// # Examples -/// -/// ``` -/// use std::collections::VecDeque; -/// -/// // This one is O(1). -/// let deque: VecDeque<_> = (1..5).collect(); -/// let ptr = deque.as_slices().0.as_ptr(); -/// let vec = Vec::from(deque); -/// assert_eq!(vec, [1, 2, 3, 4]); -/// assert_eq!(vec.as_ptr(), ptr); -/// -/// // This one needs data rearranging. -/// let mut deque: VecDeque<_> = (1..5).collect(); -/// deque.push_front(9); -/// deque.push_front(8); -/// let ptr = deque.as_slices().1.as_ptr(); -/// let vec = Vec::from(deque); -/// assert_eq!(vec, [8, 9, 1, 2, 3, 4]); -/// assert_eq!(vec.as_ptr(), ptr); -/// ``` #[stable(feature = "vecdeque_vec_conversions", since = "1.10.0")] impl From> for Vec { + /// Turn a `VecDeque` into a `Vec`. + /// + /// This never needs to re-allocate, but does need to do O(n) data movement if + /// the circular buffer doesn't happen to be at the beginning of the allocation. + /// + /// # Examples + /// + /// ``` + /// use std::collections::VecDeque; + /// + /// // This one is O(1). + /// let deque: VecDeque<_> = (1..5).collect(); + /// let ptr = deque.as_slices().0.as_ptr(); + /// let vec = Vec::from(deque); + /// assert_eq!(vec, [1, 2, 3, 4]); + /// assert_eq!(vec.as_ptr(), ptr); + /// + /// // This one needs data rearranging. + /// let mut deque: VecDeque<_> = (1..5).collect(); + /// deque.push_front(9); + /// deque.push_front(8); + /// let ptr = deque.as_slices().1.as_ptr(); + /// let vec = Vec::from(deque); + /// assert_eq!(vec, [8, 9, 1, 2, 3, 4]); + /// assert_eq!(vec.as_ptr(), ptr); + /// ``` fn from(other: VecDeque) -> Self { unsafe { let buf = other.buf.ptr(); -- cgit 1.4.1-3-g733a5 From 8da94ef84921213aa42d9da8b48251503e5ad7be Mon Sep 17 00:00:00 2001 From: scottmcm Date: Sun, 2 Jun 2019 12:14:56 -0700 Subject: Apply suggestions from code review Co-Authored-By: Joe ST --- src/liballoc/collections/vec_deque.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/liballoc') diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index 79a36d7248d..329c1437f29 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -2713,7 +2713,7 @@ impl From> for VecDeque { /// /// This avoids reallocating where possible, but the conditions for that are /// strict, and subject to change, and so shouldn't be relied upon unless the - /// `Vec` came from `From>` has hasn't been reallocated. + /// `Vec` came from `From>` and hasn't been reallocated. /// /// # Examples /// -- cgit 1.4.1-3-g733a5 From 5168f5d220d0b30d322f254f51142931a9054056 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Fri, 7 Jun 2019 21:37:52 -0700 Subject: Add hyperlinks to Vec and VecDeque Let's try the auto-linking instead, since the relative ones don't work. --- src/liballoc/collections/vec_deque.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index 329c1437f29..f01b3155525 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -2709,7 +2709,7 @@ impl fmt::Debug for VecDeque { #[stable(feature = "vecdeque_vec_conversions", since = "1.10.0")] impl From> for VecDeque { - /// Turn a `Vec` into a `VecDeque`. + /// Turn a [`Vec`] into a [`VecDeque`]. /// /// This avoids reallocating where possible, but the conditions for that are /// strict, and subject to change, and so shouldn't be relied upon unless the @@ -2762,7 +2762,7 @@ impl From> for VecDeque { #[stable(feature = "vecdeque_vec_conversions", since = "1.10.0")] impl From> for Vec { - /// Turn a `VecDeque` into a `Vec`. + /// Turn a [`VecDeque`] into a [`Vec`]. /// /// This never needs to re-allocate, but does need to do O(n) data movement if /// the circular buffer doesn't happen to be at the beginning of the allocation. -- cgit 1.4.1-3-g733a5 From 0150448f1b5474bb0c5fe3297eed0c51dae44dc8 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Tue, 11 Jun 2019 21:13:48 -0700 Subject: Remove the questionably-useful example --- src/liballoc/collections/vec_deque.rs | 22 ---------------------- 1 file changed, 22 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index f01b3155525..71faf672962 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -2714,28 +2714,6 @@ impl From> for VecDeque { /// This avoids reallocating where possible, but the conditions for that are /// strict, and subject to change, and so shouldn't be relied upon unless the /// `Vec` came from `From>` and hasn't been reallocated. - /// - /// # Examples - /// - /// ``` - /// use std::collections::VecDeque; - /// - /// // Start with a `VecDeque`. - /// let deque: VecDeque<_> = (1..5).collect(); - /// - /// // Turn it into a `Vec` with no allocation needed. - /// let mut vec = Vec::from(deque); - /// - /// // Modify it, being careful not to trigger reallocation. - /// vec.pop(); - /// vec.push(100); - /// - /// // Turn it back into a `VecDeque` with no allocation needed. - /// let ptr = vec.as_ptr(); - /// let deque = VecDeque::from(vec); - /// assert_eq!(deque, [1, 2, 3, 100]); - /// assert_eq!(deque.as_slices().0.as_ptr(), ptr); - /// ``` fn from(mut other: Vec) -> Self { unsafe { let other_buf = other.as_mut_ptr(); -- cgit 1.4.1-3-g733a5 From eb09daa762c37c743584ec3b5c05a2d181960ced Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 7 Jun 2019 18:29:48 +0300 Subject: Hygienize macros in the standard library --- src/liballoc/macros.rs | 2 +- src/libcore/macros.rs | 22 ++++++++++---------- src/libstd/macros.rs | 16 +++++++-------- src/test/ui/hygiene/no_implicit_prelude.rs | 2 +- src/test/ui/hygiene/no_implicit_prelude.stderr | 6 +++--- .../ui/imports/local-modularized-tricky-fail-1.rs | 1 - .../imports/local-modularized-tricky-fail-1.stderr | 24 ++-------------------- 7 files changed, 26 insertions(+), 47 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/macros.rs b/src/liballoc/macros.rs index dd128e096f9..250c419c531 100644 --- a/src/liballoc/macros.rs +++ b/src/liballoc/macros.rs @@ -42,7 +42,7 @@ macro_rules! vec { ($($x:expr),*) => ( <[_]>::into_vec(box [$($x),*]) ); - ($($x:expr,)*) => (vec![$($x),*]) + ($($x:expr,)*) => ($crate::vec![$($x),*]) } // HACK(japaric): with cfg(test) the inherent `[T]::into_vec` method, which is diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index 9dfa09cf8a5..8b44025f91f 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -6,13 +6,13 @@ #[stable(feature = "core", since = "1.6.0")] macro_rules! panic { () => ( - panic!("explicit panic") + $crate::panic!("explicit panic") ); ($msg:expr) => ({ $crate::panicking::panic(&($msg, file!(), line!(), __rust_unstable_column!())) }); ($msg:expr,) => ( - panic!($msg) + $crate::panic!($msg) ); ($fmt:expr, $($arg:tt)+) => ({ $crate::panicking::panic_fmt(format_args!($fmt, $($arg)*), @@ -58,7 +58,7 @@ macro_rules! assert_eq { } }); ($left:expr, $right:expr,) => ({ - assert_eq!($left, $right) + $crate::assert_eq!($left, $right) }); ($left:expr, $right:expr, $($arg:tt)+) => ({ match (&($left), &($right)) { @@ -115,7 +115,7 @@ macro_rules! assert_ne { } }); ($left:expr, $right:expr,) => { - assert_ne!($left, $right) + $crate::assert_ne!($left, $right) }; ($left:expr, $right:expr, $($arg:tt)+) => ({ match (&($left), &($right)) { @@ -208,7 +208,7 @@ macro_rules! debug_assert { #[macro_export] #[stable(feature = "rust1", since = "1.0.0")] macro_rules! debug_assert_eq { - ($($arg:tt)*) => (if cfg!(debug_assertions) { assert_eq!($($arg)*); }) + ($($arg:tt)*) => (if cfg!(debug_assertions) { $crate::assert_eq!($($arg)*); }) } /// Asserts that two expressions are not equal to each other. @@ -235,7 +235,7 @@ macro_rules! debug_assert_eq { #[macro_export] #[stable(feature = "assert_ne", since = "1.13.0")] macro_rules! debug_assert_ne { - ($($arg:tt)*) => (if cfg!(debug_assertions) { assert_ne!($($arg)*); }) + ($($arg:tt)*) => (if cfg!(debug_assertions) { $crate::assert_ne!($($arg)*); }) } /// Unwraps a result or propagates its error. @@ -310,7 +310,7 @@ macro_rules! r#try { return $crate::result::Result::Err($crate::convert::From::from(err)) } }); - ($expr:expr,) => (r#try!($expr)); + ($expr:expr,) => ($crate::r#try!($expr)); } /// Writes formatted data into a buffer. @@ -425,10 +425,10 @@ macro_rules! write { #[allow_internal_unstable(format_args_nl)] macro_rules! writeln { ($dst:expr) => ( - write!($dst, "\n") + $crate::write!($dst, "\n") ); ($dst:expr,) => ( - writeln!($dst) + $crate::writeln!($dst) ); ($dst:expr, $($arg:tt)*) => ( $dst.write_fmt(format_args_nl!($($arg)*)) @@ -494,10 +494,10 @@ macro_rules! unreachable { panic!("internal error: entered unreachable code") }); ($msg:expr) => ({ - unreachable!("{}", $msg) + $crate::unreachable!("{}", $msg) }); ($msg:expr,) => ({ - unreachable!($msg) + $crate::unreachable!($msg) }); ($fmt:expr, $($arg:tt)*) => ({ panic!(concat!("internal error: entered unreachable code: ", $fmt), $($arg)*) diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index ef7179f0b6f..ef1b549d1dc 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -56,13 +56,13 @@ #[allow_internal_unstable(__rust_unstable_column, libstd_sys_internals)] macro_rules! panic { () => ({ - panic!("explicit panic") + $crate::panic!("explicit panic") }); ($msg:expr) => ({ $crate::rt::begin_panic($msg, &(file!(), line!(), __rust_unstable_column!())) }); ($msg:expr,) => ({ - panic!($msg) + $crate::panic!($msg) }); ($fmt:expr, $($arg:tt)+) => ({ $crate::rt::begin_panic_fmt(&format_args!($fmt, $($arg)+), @@ -145,7 +145,7 @@ macro_rules! print { #[stable(feature = "rust1", since = "1.0.0")] #[allow_internal_unstable(print_internals, format_args_nl)] macro_rules! println { - () => (print!("\n")); + () => ($crate::print!("\n")); ($($arg:tt)*) => ({ $crate::io::_print(format_args_nl!($($arg)*)); }) @@ -204,7 +204,7 @@ macro_rules! eprint { #[stable(feature = "eprint", since = "1.19.0")] #[allow_internal_unstable(print_internals, format_args_nl)] macro_rules! eprintln { - () => (eprint!("\n")); + () => ($crate::eprint!("\n")); ($($arg:tt)*) => ({ $crate::io::_eprint(format_args_nl!($($arg)*)); }) @@ -337,23 +337,23 @@ macro_rules! eprintln { #[stable(feature = "dbg_macro", since = "1.32.0")] macro_rules! dbg { () => { - eprintln!("[{}:{}]", file!(), line!()); + $crate::eprintln!("[{}:{}]", file!(), line!()); }; ($val:expr) => { // Use of `match` here is intentional because it affects the lifetimes // of temporaries - https://stackoverflow.com/a/48732525/1063961 match $val { tmp => { - eprintln!("[{}:{}] {} = {:#?}", + $crate::eprintln!("[{}:{}] {} = {:#?}", file!(), line!(), stringify!($val), &tmp); tmp } } }; // Trailing comma with single argument is ignored - ($val:expr,) => { dbg!($val) }; + ($val:expr,) => { $crate::dbg!($val) }; ($($val:expr),+ $(,)?) => { - ($(dbg!($val)),+,) + ($($crate::dbg!($val)),+,) }; } diff --git a/src/test/ui/hygiene/no_implicit_prelude.rs b/src/test/ui/hygiene/no_implicit_prelude.rs index 1cd05f4d44c..890c8307543 100644 --- a/src/test/ui/hygiene/no_implicit_prelude.rs +++ b/src/test/ui/hygiene/no_implicit_prelude.rs @@ -13,7 +13,7 @@ mod bar { } fn f() { ::foo::m!(); - println!(); //~ ERROR cannot find macro `print!` in this scope + assert_eq!(0, 0); //~ ERROR cannot find macro `panic!` in this scope } } diff --git a/src/test/ui/hygiene/no_implicit_prelude.stderr b/src/test/ui/hygiene/no_implicit_prelude.stderr index dcb213f809a..737b375ed89 100644 --- a/src/test/ui/hygiene/no_implicit_prelude.stderr +++ b/src/test/ui/hygiene/no_implicit_prelude.stderr @@ -7,11 +7,11 @@ LL | fn f() { ::bar::m!(); } LL | Vec::new(); | ^^^ use of undeclared type or module `Vec` -error: cannot find macro `print!` in this scope +error: cannot find macro `panic!` in this scope --> $DIR/no_implicit_prelude.rs:16:9 | -LL | println!(); - | ^^^^^^^^^^^ +LL | assert_eq!(0, 0); + | ^^^^^^^^^^^^^^^^^ | = help: have you added the `#[macro_use]` on the module/import? = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) diff --git a/src/test/ui/imports/local-modularized-tricky-fail-1.rs b/src/test/ui/imports/local-modularized-tricky-fail-1.rs index d1cb6b07d75..29e9b8ec841 100644 --- a/src/test/ui/imports/local-modularized-tricky-fail-1.rs +++ b/src/test/ui/imports/local-modularized-tricky-fail-1.rs @@ -33,7 +33,6 @@ mod inner2 { fn main() { panic!(); //~ ERROR `panic` is ambiguous - //~| ERROR `panic` is ambiguous } mod inner3 { diff --git a/src/test/ui/imports/local-modularized-tricky-fail-1.stderr b/src/test/ui/imports/local-modularized-tricky-fail-1.stderr index d7ae8e6d505..13d3227d8b3 100644 --- a/src/test/ui/imports/local-modularized-tricky-fail-1.stderr +++ b/src/test/ui/imports/local-modularized-tricky-fail-1.stderr @@ -22,7 +22,7 @@ LL | use inner1::*; = help: consider adding an explicit import of `exported` to disambiguate error[E0659]: `include` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution) - --> $DIR/local-modularized-tricky-fail-1.rs:47:1 + --> $DIR/local-modularized-tricky-fail-1.rs:46:1 | LL | include!(); | ^^^^^^^ ambiguous name @@ -59,26 +59,6 @@ LL | define_panic!(); | ---------------- in this macro invocation = help: use `crate::panic` to refer to this macro unambiguously -error[E0659]: `panic` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution) - --> $DIR/local-modularized-tricky-fail-1.rs:35:5 - | -LL | panic!(); - | ^^^^^^^^^ ambiguous name - | - = note: `panic` could refer to a macro from prelude -note: `panic` could also refer to the macro defined here - --> $DIR/local-modularized-tricky-fail-1.rs:11:5 - | -LL | / macro_rules! panic { -LL | | () => () -LL | | } - | |_____^ -... -LL | define_panic!(); - | ---------------- in this macro invocation - = help: use `crate::panic` to refer to this macro unambiguously - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0659`. -- cgit 1.4.1-3-g733a5 From 79e58399920d6a0a7c4050bfb26c64fbc10562ec Mon Sep 17 00:00:00 2001 From: Michal 'vorner' Vaner Date: Sat, 1 Jun 2019 11:55:25 +0200 Subject: docs: Use String in Rc::into_raw examples It is unclear if accessing an integer after `drop_in_place` has been called on it is undefined behaviour or not, as demonstrated by the discussion in https://github.com/rust-lang/rust/pull/60766#pullrequestreview-243414222. Avoid these uncertainties by using String which frees memory in its `drop_in_place` to make sure this is undefined behaviour. The message in the docs should be to watch out and not access the data after that, not discussing when one maybe could get away with it O:-). --- src/liballoc/rc.rs | 28 ++++++++++++++-------------- src/liballoc/sync.rs | 28 ++++++++++++++-------------- 2 files changed, 28 insertions(+), 28 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 1f357a719bb..df2bd2bc939 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -375,9 +375,9 @@ impl Rc { /// ``` /// use std::rc::Rc; /// - /// let x = Rc::new(10); + /// let x = Rc::new("hello".to_owned()); /// let x_ptr = Rc::into_raw(x); - /// assert_eq!(unsafe { *x_ptr }, 10); + /// assert_eq!(unsafe { &*x_ptr }, "hello"); /// ``` #[stable(feature = "rc_raw", since = "1.17.0")] pub fn into_raw(this: Self) -> *const T { @@ -401,13 +401,13 @@ impl Rc { /// ``` /// use std::rc::Rc; /// - /// let x = Rc::new(10); + /// let x = Rc::new("hello".to_owned()); /// let x_ptr = Rc::into_raw(x); /// /// unsafe { /// // Convert back to an `Rc` to prevent leak. /// let x = Rc::from_raw(x_ptr); - /// assert_eq!(*x, 10); + /// assert_eq!(&*x, "hello"); /// /// // Further calls to `Rc::from_raw(x_ptr)` would be memory unsafe. /// } @@ -437,10 +437,10 @@ impl Rc { /// /// use std::rc::Rc; /// - /// let x = Rc::new(10); + /// let x = Rc::new("hello".to_owned()); /// let ptr = Rc::into_raw_non_null(x); - /// let deref = unsafe { *ptr.as_ref() }; - /// assert_eq!(deref, 10); + /// let deref = unsafe { ptr.as_ref() }; + /// assert_eq!(deref, "hello"); /// ``` #[unstable(feature = "rc_into_raw_non_null", issue = "47336")] #[inline] @@ -1274,17 +1274,17 @@ impl Weak { /// use std::rc::{Rc, Weak}; /// use std::ptr; /// - /// let strong = Rc::new(42); + /// let strong = Rc::new("hello".to_owned()); /// let weak = Rc::downgrade(&strong); /// // Both point to the same object /// assert!(ptr::eq(&*strong, Weak::as_raw(&weak))); /// // The strong here keeps it alive, so we can still access the object. - /// assert_eq!(42, unsafe { *Weak::as_raw(&weak) }); + /// assert_eq!("hello", unsafe { &*Weak::as_raw(&weak) }); /// /// drop(strong); /// // But not any more. We can do Weak::as_raw(&weak), but accessing the pointer would lead to /// // undefined behaviour. - /// // assert_eq!(42, unsafe { *Weak::as_raw(&weak) }); + /// // assert_eq!("hello", unsafe { &*Weak::as_raw(&weak) }); /// ``` /// /// [`null`]: ../../std/ptr/fn.null.html @@ -1319,12 +1319,12 @@ impl Weak { /// /// use std::rc::{Rc, Weak}; /// - /// let strong = Rc::new(42); + /// let strong = Rc::new("hello".to_owned()); /// let weak = Rc::downgrade(&strong); /// let raw = Weak::into_raw(weak); /// /// assert_eq!(1, Rc::weak_count(&strong)); - /// assert_eq!(42, unsafe { *raw }); + /// assert_eq!("hello", unsafe { &*raw }); /// /// drop(unsafe { Weak::from_raw(raw) }); /// assert_eq!(0, Rc::weak_count(&strong)); @@ -1360,14 +1360,14 @@ impl Weak { /// /// use std::rc::{Rc, Weak}; /// - /// let strong = Rc::new(42); + /// let strong = Rc::new("hello".to_owned()); /// /// let raw_1 = Weak::into_raw(Rc::downgrade(&strong)); /// let raw_2 = Weak::into_raw(Rc::downgrade(&strong)); /// /// assert_eq!(2, Rc::weak_count(&strong)); /// - /// assert_eq!(42, *Weak::upgrade(&unsafe { Weak::from_raw(raw_1) }).unwrap()); + /// assert_eq!("hello", &*Weak::upgrade(&unsafe { Weak::from_raw(raw_1) }).unwrap()); /// assert_eq!(1, Rc::weak_count(&strong)); /// /// drop(strong); diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index 70865656c51..2503f696bf3 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -356,9 +356,9 @@ impl Arc { /// ``` /// use std::sync::Arc; /// - /// let x = Arc::new(10); + /// let x = Arc::new("hello".to_owned()); /// let x_ptr = Arc::into_raw(x); - /// assert_eq!(unsafe { *x_ptr }, 10); + /// assert_eq!(unsafe { &*x_ptr }, "hello"); /// ``` #[stable(feature = "rc_raw", since = "1.17.0")] pub fn into_raw(this: Self) -> *const T { @@ -382,13 +382,13 @@ impl Arc { /// ``` /// use std::sync::Arc; /// - /// let x = Arc::new(10); + /// let x = Arc::new("hello".to_owned()); /// let x_ptr = Arc::into_raw(x); /// /// unsafe { /// // Convert back to an `Arc` to prevent leak. /// let x = Arc::from_raw(x_ptr); - /// assert_eq!(*x, 10); + /// assert_eq!(&*x, "hello"); /// /// // Further calls to `Arc::from_raw(x_ptr)` would be memory unsafe. /// } @@ -418,10 +418,10 @@ impl Arc { /// /// use std::sync::Arc; /// - /// let x = Arc::new(10); + /// let x = Arc::new("hello".to_owned()); /// let ptr = Arc::into_raw_non_null(x); - /// let deref = unsafe { *ptr.as_ref() }; - /// assert_eq!(deref, 10); + /// let deref = unsafe { ptr.as_ref() }; + /// assert_eq!(deref, "hello"); /// ``` #[unstable(feature = "rc_into_raw_non_null", issue = "47336")] #[inline] @@ -1083,17 +1083,17 @@ impl Weak { /// use std::sync::{Arc, Weak}; /// use std::ptr; /// - /// let strong = Arc::new(42); + /// let strong = Arc::new("hello".to_owned()); /// let weak = Arc::downgrade(&strong); /// // Both point to the same object /// assert!(ptr::eq(&*strong, Weak::as_raw(&weak))); /// // The strong here keeps it alive, so we can still access the object. - /// assert_eq!(42, unsafe { *Weak::as_raw(&weak) }); + /// assert_eq!("hello", unsafe { &*Weak::as_raw(&weak) }); /// /// drop(strong); /// // But not any more. We can do Weak::as_raw(&weak), but accessing the pointer would lead to /// // undefined behaviour. - /// // assert_eq!(42, unsafe { *Weak::as_raw(&weak) }); + /// // assert_eq!("hello", unsafe { &*Weak::as_raw(&weak) }); /// ``` /// /// [`null`]: ../../std/ptr/fn.null.html @@ -1128,12 +1128,12 @@ impl Weak { /// /// use std::sync::{Arc, Weak}; /// - /// let strong = Arc::new(42); + /// let strong = Arc::new("hello".to_owned()); /// let weak = Arc::downgrade(&strong); /// let raw = Weak::into_raw(weak); /// /// assert_eq!(1, Arc::weak_count(&strong)); - /// assert_eq!(42, unsafe { *raw }); + /// assert_eq!("hello", unsafe { &*raw }); /// /// drop(unsafe { Weak::from_raw(raw) }); /// assert_eq!(0, Arc::weak_count(&strong)); @@ -1170,14 +1170,14 @@ impl Weak { /// /// use std::sync::{Arc, Weak}; /// - /// let strong = Arc::new(42); + /// let strong = Arc::new("hello".to_owned()); /// /// let raw_1 = Weak::into_raw(Arc::downgrade(&strong)); /// let raw_2 = Weak::into_raw(Arc::downgrade(&strong)); /// /// assert_eq!(2, Arc::weak_count(&strong)); /// - /// assert_eq!(42, *Weak::upgrade(&unsafe { Weak::from_raw(raw_1) }).unwrap()); + /// assert_eq!("hello", &*Weak::upgrade(&unsafe { Weak::from_raw(raw_1) }).unwrap()); /// assert_eq!(1, Arc::weak_count(&strong)); /// /// drop(strong); -- cgit 1.4.1-3-g733a5 From 49fbd76a7667fba9dfbf283ca792a0dc66c9fb5b Mon Sep 17 00:00:00 2001 From: Michal 'vorner' Vaner Date: Sat, 15 Jun 2019 08:47:19 +0200 Subject: Make the Weak::{into,as}_raw methods Because Weak doesn't Deref, so there's no reason for them to be only associated methods. --- src/liballoc/rc.rs | 30 +++++++++++++++--------------- src/liballoc/sync.rs | 30 +++++++++++++++--------------- 2 files changed, 30 insertions(+), 30 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 7cbb4963301..912f600e377 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -1291,26 +1291,26 @@ impl Weak { /// ``` /// #![feature(weak_into_raw)] /// - /// use std::rc::{Rc, Weak}; + /// use std::rc::Rc; /// use std::ptr; /// /// let strong = Rc::new("hello".to_owned()); /// let weak = Rc::downgrade(&strong); /// // Both point to the same object - /// assert!(ptr::eq(&*strong, Weak::as_raw(&weak))); + /// assert!(ptr::eq(&*strong, weak.as_raw())); /// // The strong here keeps it alive, so we can still access the object. - /// assert_eq!("hello", unsafe { &*Weak::as_raw(&weak) }); + /// assert_eq!("hello", unsafe { &*weak.as_raw() }); /// /// drop(strong); - /// // But not any more. We can do Weak::as_raw(&weak), but accessing the pointer would lead to + /// // But not any more. We can do weak.as_raw(), but accessing the pointer would lead to /// // undefined behaviour. - /// // assert_eq!("hello", unsafe { &*Weak::as_raw(&weak) }); + /// // assert_eq!("hello", unsafe { &*weak.as_raw() }); /// ``` /// /// [`null`]: ../../std/ptr/fn.null.html #[unstable(feature = "weak_into_raw", issue = "60728")] - pub fn as_raw(this: &Self) -> *const T { - match this.inner() { + pub fn as_raw(&self) -> *const T { + match self.inner() { None => ptr::null(), Some(inner) => { let offset = data_offset_sized::(); @@ -1341,7 +1341,7 @@ impl Weak { /// /// let strong = Rc::new("hello".to_owned()); /// let weak = Rc::downgrade(&strong); - /// let raw = Weak::into_raw(weak); + /// let raw = weak.into_raw(); /// /// assert_eq!(1, Rc::weak_count(&strong)); /// assert_eq!("hello", unsafe { &*raw }); @@ -1353,9 +1353,9 @@ impl Weak { /// [`from_raw`]: struct.Weak.html#method.from_raw /// [`as_raw`]: struct.Weak.html#method.as_raw #[unstable(feature = "weak_into_raw", issue = "60728")] - pub fn into_raw(this: Self) -> *const T { - let result = Self::as_raw(&this); - mem::forget(this); + pub fn into_raw(self) -> *const T { + let result = self.as_raw(); + mem::forget(self); result } @@ -1382,18 +1382,18 @@ impl Weak { /// /// let strong = Rc::new("hello".to_owned()); /// - /// let raw_1 = Weak::into_raw(Rc::downgrade(&strong)); - /// let raw_2 = Weak::into_raw(Rc::downgrade(&strong)); + /// let raw_1 = Rc::downgrade(&strong).into_raw(); + /// let raw_2 = Rc::downgrade(&strong).into_raw(); /// /// assert_eq!(2, Rc::weak_count(&strong)); /// - /// assert_eq!("hello", &*Weak::upgrade(&unsafe { Weak::from_raw(raw_1) }).unwrap()); + /// assert_eq!("hello", &*unsafe { Weak::from_raw(raw_1) }.upgrade().unwrap()); /// assert_eq!(1, Rc::weak_count(&strong)); /// /// drop(strong); /// /// // Decrement the last weak count. - /// assert!(Weak::upgrade(&unsafe { Weak::from_raw(raw_2) }).is_none()); + /// assert!(unsafe { Weak::from_raw(raw_2) }.upgrade().is_none()); /// ``` /// /// [`null`]: ../../std/ptr/fn.null.html diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index 2503f696bf3..f0fbcc55981 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -1080,26 +1080,26 @@ impl Weak { /// ``` /// #![feature(weak_into_raw)] /// - /// use std::sync::{Arc, Weak}; + /// use std::sync::Arc; /// use std::ptr; /// /// let strong = Arc::new("hello".to_owned()); /// let weak = Arc::downgrade(&strong); /// // Both point to the same object - /// assert!(ptr::eq(&*strong, Weak::as_raw(&weak))); + /// assert!(ptr::eq(&*strong, weak.as_raw())); /// // The strong here keeps it alive, so we can still access the object. - /// assert_eq!("hello", unsafe { &*Weak::as_raw(&weak) }); + /// assert_eq!("hello", unsafe { &*weak.as_raw() }); /// /// drop(strong); - /// // But not any more. We can do Weak::as_raw(&weak), but accessing the pointer would lead to + /// // But not any more. We can do weak.as_raw(), but accessing the pointer would lead to /// // undefined behaviour. - /// // assert_eq!("hello", unsafe { &*Weak::as_raw(&weak) }); + /// // assert_eq!("hello", unsafe { &*weak.as_raw() }); /// ``` /// /// [`null`]: ../../std/ptr/fn.null.html #[unstable(feature = "weak_into_raw", issue = "60728")] - pub fn as_raw(this: &Self) -> *const T { - match this.inner() { + pub fn as_raw(&self) -> *const T { + match self.inner() { None => ptr::null(), Some(inner) => { let offset = data_offset_sized::(); @@ -1130,7 +1130,7 @@ impl Weak { /// /// let strong = Arc::new("hello".to_owned()); /// let weak = Arc::downgrade(&strong); - /// let raw = Weak::into_raw(weak); + /// let raw = weak.into_raw(); /// /// assert_eq!(1, Arc::weak_count(&strong)); /// assert_eq!("hello", unsafe { &*raw }); @@ -1142,9 +1142,9 @@ impl Weak { /// [`from_raw`]: struct.Weak.html#method.from_raw /// [`as_raw`]: struct.Weak.html#method.as_raw #[unstable(feature = "weak_into_raw", issue = "60728")] - pub fn into_raw(this: Self) -> *const T { - let result = Self::as_raw(&this); - mem::forget(this); + pub fn into_raw(self) -> *const T { + let result = self.as_raw(); + mem::forget(self); result } @@ -1172,18 +1172,18 @@ impl Weak { /// /// let strong = Arc::new("hello".to_owned()); /// - /// let raw_1 = Weak::into_raw(Arc::downgrade(&strong)); - /// let raw_2 = Weak::into_raw(Arc::downgrade(&strong)); + /// let raw_1 = Arc::downgrade(&strong).into_raw(); + /// let raw_2 = Arc::downgrade(&strong).into_raw(); /// /// assert_eq!(2, Arc::weak_count(&strong)); /// - /// assert_eq!("hello", &*Weak::upgrade(&unsafe { Weak::from_raw(raw_1) }).unwrap()); + /// assert_eq!("hello", &*unsafe { Weak::from_raw(raw_1) }.upgrade().unwrap()); /// assert_eq!(1, Arc::weak_count(&strong)); /// /// drop(strong); /// /// // Decrement the last weak count. - /// assert!(Weak::upgrade(&unsafe { Weak::from_raw(raw_2) }).is_none()); + /// assert!(unsafe { Weak::from_raw(raw_2) }.upgrade().is_none()); /// ``` /// /// [`null`]: ../../std/ptr/fn.null.html -- cgit 1.4.1-3-g733a5 From 89292beedb84977970a6ab0e3a0ad695e2fcf7db Mon Sep 17 00:00:00 2001 From: chansuke Date: Sun, 2 Jun 2019 01:50:10 +0900 Subject: Separate liballoc module --- src/liballoc/boxed_test.rs | 140 --------------------------------------------- src/liballoc/lib.rs | 2 +- src/liballoc/tests.rs | 140 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 141 insertions(+), 141 deletions(-) delete mode 100644 src/liballoc/boxed_test.rs create mode 100644 src/liballoc/tests.rs (limited to 'src/liballoc') diff --git a/src/liballoc/boxed_test.rs b/src/liballoc/boxed_test.rs deleted file mode 100644 index 654eabd0703..00000000000 --- a/src/liballoc/boxed_test.rs +++ /dev/null @@ -1,140 +0,0 @@ -//! Test for `boxed` mod. - -use core::any::Any; -use core::ops::Deref; -use core::result::Result::{Err, Ok}; -use core::clone::Clone; -use core::f64; -use core::i64; - -use std::boxed::Box; - -#[test] -fn test_owned_clone() { - let a = Box::new(5); - let b: Box = a.clone(); - assert!(a == b); -} - -#[derive(PartialEq, Eq)] -struct Test; - -#[test] -fn any_move() { - let a = Box::new(8) as Box; - let b = Box::new(Test) as Box; - - match a.downcast::() { - Ok(a) => { - assert!(a == Box::new(8)); - } - Err(..) => panic!(), - } - match b.downcast::() { - Ok(a) => { - assert!(a == Box::new(Test)); - } - Err(..) => panic!(), - } - - let a = Box::new(8) as Box; - let b = Box::new(Test) as Box; - - assert!(a.downcast::>().is_err()); - assert!(b.downcast::>().is_err()); -} - -#[test] -fn test_show() { - let a = Box::new(8) as Box; - let b = Box::new(Test) as Box; - let a_str = format!("{:?}", a); - let b_str = format!("{:?}", b); - assert_eq!(a_str, "Any"); - assert_eq!(b_str, "Any"); - - static EIGHT: usize = 8; - static TEST: Test = Test; - let a = &EIGHT as &dyn Any; - let b = &TEST as &dyn Any; - let s = format!("{:?}", a); - assert_eq!(s, "Any"); - let s = format!("{:?}", b); - assert_eq!(s, "Any"); -} - -#[test] -fn deref() { - fn homura>(_: T) {} - homura(Box::new(765)); -} - -#[test] -fn raw_sized() { - let x = Box::new(17); - let p = Box::into_raw(x); - unsafe { - assert_eq!(17, *p); - *p = 19; - let y = Box::from_raw(p); - assert_eq!(19, *y); - } -} - -#[test] -fn raw_trait() { - trait Foo { - fn get(&self) -> u32; - fn set(&mut self, value: u32); - } - - struct Bar(u32); - - impl Foo for Bar { - fn get(&self) -> u32 { - self.0 - } - - fn set(&mut self, value: u32) { - self.0 = value; - } - } - - let x: Box = Box::new(Bar(17)); - let p = Box::into_raw(x); - unsafe { - assert_eq!(17, (*p).get()); - (*p).set(19); - let y: Box = Box::from_raw(p); - assert_eq!(19, y.get()); - } -} - -#[test] -fn f64_slice() { - let slice: &[f64] = &[-1.0, 0.0, 1.0, f64::INFINITY]; - let boxed: Box<[f64]> = Box::from(slice); - assert_eq!(&*boxed, slice) -} - -#[test] -fn i64_slice() { - let slice: &[i64] = &[i64::MIN, -2, -1, 0, 1, 2, i64::MAX]; - let boxed: Box<[i64]> = Box::from(slice); - assert_eq!(&*boxed, slice) -} - -#[test] -fn str_slice() { - let s = "Hello, world!"; - let boxed: Box = Box::from(s); - assert_eq!(&*boxed, s) -} - -#[test] -fn boxed_slice_from_iter() { - let iter = 0..100; - let boxed: Box<[u32]> = iter.collect(); - assert_eq!(boxed.len(), 100); - assert_eq!(boxed[7], 7); -} diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index c530ac24275..5fc58c8ab5a 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -141,7 +141,7 @@ mod boxed { pub use std::boxed::Box; } #[cfg(test)] -mod boxed_test; +mod tests; pub mod collections; #[cfg(all(target_has_atomic = "ptr", target_has_atomic = "cas"))] pub mod sync; diff --git a/src/liballoc/tests.rs b/src/liballoc/tests.rs new file mode 100644 index 00000000000..654eabd0703 --- /dev/null +++ b/src/liballoc/tests.rs @@ -0,0 +1,140 @@ +//! Test for `boxed` mod. + +use core::any::Any; +use core::ops::Deref; +use core::result::Result::{Err, Ok}; +use core::clone::Clone; +use core::f64; +use core::i64; + +use std::boxed::Box; + +#[test] +fn test_owned_clone() { + let a = Box::new(5); + let b: Box = a.clone(); + assert!(a == b); +} + +#[derive(PartialEq, Eq)] +struct Test; + +#[test] +fn any_move() { + let a = Box::new(8) as Box; + let b = Box::new(Test) as Box; + + match a.downcast::() { + Ok(a) => { + assert!(a == Box::new(8)); + } + Err(..) => panic!(), + } + match b.downcast::() { + Ok(a) => { + assert!(a == Box::new(Test)); + } + Err(..) => panic!(), + } + + let a = Box::new(8) as Box; + let b = Box::new(Test) as Box; + + assert!(a.downcast::>().is_err()); + assert!(b.downcast::>().is_err()); +} + +#[test] +fn test_show() { + let a = Box::new(8) as Box; + let b = Box::new(Test) as Box; + let a_str = format!("{:?}", a); + let b_str = format!("{:?}", b); + assert_eq!(a_str, "Any"); + assert_eq!(b_str, "Any"); + + static EIGHT: usize = 8; + static TEST: Test = Test; + let a = &EIGHT as &dyn Any; + let b = &TEST as &dyn Any; + let s = format!("{:?}", a); + assert_eq!(s, "Any"); + let s = format!("{:?}", b); + assert_eq!(s, "Any"); +} + +#[test] +fn deref() { + fn homura>(_: T) {} + homura(Box::new(765)); +} + +#[test] +fn raw_sized() { + let x = Box::new(17); + let p = Box::into_raw(x); + unsafe { + assert_eq!(17, *p); + *p = 19; + let y = Box::from_raw(p); + assert_eq!(19, *y); + } +} + +#[test] +fn raw_trait() { + trait Foo { + fn get(&self) -> u32; + fn set(&mut self, value: u32); + } + + struct Bar(u32); + + impl Foo for Bar { + fn get(&self) -> u32 { + self.0 + } + + fn set(&mut self, value: u32) { + self.0 = value; + } + } + + let x: Box = Box::new(Bar(17)); + let p = Box::into_raw(x); + unsafe { + assert_eq!(17, (*p).get()); + (*p).set(19); + let y: Box = Box::from_raw(p); + assert_eq!(19, y.get()); + } +} + +#[test] +fn f64_slice() { + let slice: &[f64] = &[-1.0, 0.0, 1.0, f64::INFINITY]; + let boxed: Box<[f64]> = Box::from(slice); + assert_eq!(&*boxed, slice) +} + +#[test] +fn i64_slice() { + let slice: &[i64] = &[i64::MIN, -2, -1, 0, 1, 2, i64::MAX]; + let boxed: Box<[i64]> = Box::from(slice); + assert_eq!(&*boxed, slice) +} + +#[test] +fn str_slice() { + let s = "Hello, world!"; + let boxed: Box = Box::from(s); + assert_eq!(&*boxed, s) +} + +#[test] +fn boxed_slice_from_iter() { + let iter = 0..100; + let boxed: Box<[u32]> = iter.collect(); + assert_eq!(boxed.len(), 100); + assert_eq!(boxed[7], 7); +} -- cgit 1.4.1-3-g733a5 From 387ac060d2044be63786571fcf7831879d2a2bfb Mon Sep 17 00:00:00 2001 From: Thomas Heck Date: Sun, 16 Jun 2019 13:57:07 +0200 Subject: make `Weak::ptr_eq`s into methods --- src/liballoc/rc.rs | 14 +++++++------- src/liballoc/sync.rs | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 7cbb4963301..ee78839f7f0 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -1515,18 +1515,18 @@ impl Weak { /// /// ``` /// #![feature(weak_ptr_eq)] - /// use std::rc::{Rc, Weak}; + /// use std::rc::Rc; /// /// let first_rc = Rc::new(5); /// let first = Rc::downgrade(&first_rc); /// let second = Rc::downgrade(&first_rc); /// - /// assert!(Weak::ptr_eq(&first, &second)); + /// assert!(first.ptr_eq(&second)); /// /// let third_rc = Rc::new(5); /// let third = Rc::downgrade(&third_rc); /// - /// assert!(!Weak::ptr_eq(&first, &third)); + /// assert!(!first.ptr_eq(&third)); /// ``` /// /// Comparing `Weak::new`. @@ -1537,16 +1537,16 @@ impl Weak { /// /// let first = Weak::new(); /// let second = Weak::new(); - /// assert!(Weak::ptr_eq(&first, &second)); + /// assert!(first.ptr_eq(&second)); /// /// let third_rc = Rc::new(()); /// let third = Rc::downgrade(&third_rc); - /// assert!(!Weak::ptr_eq(&first, &third)); + /// assert!(!first.ptr_eq(&third)); /// ``` #[inline] #[unstable(feature = "weak_ptr_eq", issue = "55981")] - pub fn ptr_eq(this: &Self, other: &Self) -> bool { - this.ptr.as_ptr() == other.ptr.as_ptr() + pub fn ptr_eq(&self, other: &Self) -> bool { + self.ptr.as_ptr() == other.ptr.as_ptr() } } diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index 2503f696bf3..6c23b3179ed 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -1349,18 +1349,18 @@ impl Weak { /// /// ``` /// #![feature(weak_ptr_eq)] - /// use std::sync::{Arc, Weak}; + /// use std::sync::Arc; /// /// let first_rc = Arc::new(5); /// let first = Arc::downgrade(&first_rc); /// let second = Arc::downgrade(&first_rc); /// - /// assert!(Weak::ptr_eq(&first, &second)); + /// assert!(first.ptr_eq(&second)); /// /// let third_rc = Arc::new(5); /// let third = Arc::downgrade(&third_rc); /// - /// assert!(!Weak::ptr_eq(&first, &third)); + /// assert!(!first.ptr_eq(&third)); /// ``` /// /// Comparing `Weak::new`. @@ -1371,16 +1371,16 @@ impl Weak { /// /// let first = Weak::new(); /// let second = Weak::new(); - /// assert!(Weak::ptr_eq(&first, &second)); + /// assert!(first.ptr_eq(&second)); /// /// let third_rc = Arc::new(()); /// let third = Arc::downgrade(&third_rc); - /// assert!(!Weak::ptr_eq(&first, &third)); + /// assert!(!first.ptr_eq(&third)); /// ``` #[inline] #[unstable(feature = "weak_ptr_eq", issue = "55981")] - pub fn ptr_eq(this: &Self, other: &Self) -> bool { - this.ptr.as_ptr() == other.ptr.as_ptr() + pub fn ptr_eq(&self, other: &Self) -> bool { + self.ptr.as_ptr() == other.ptr.as_ptr() } } -- cgit 1.4.1-3-g733a5 From 689c64c469152ab6de15c3950d5fe92ba95257f2 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 19 Jun 2019 01:39:51 +0200 Subject: Add basic 'shared_from_iter' impls. --- src/liballoc/rc.rs | 7 +++++++ src/liballoc/sync.rs | 7 +++++++ 2 files changed, 14 insertions(+) (limited to 'src/liballoc') diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index ee78839f7f0..df97b0efc6c 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -1213,6 +1213,13 @@ impl From> for Rc<[T]> { } } +#[stable(feature = "shared_from_iter", since = "1.37.0")] +impl core::iter::FromIterator for Rc<[T]> { + fn from_iter>(iter: I) -> Self { + iter.into_iter().collect::>().into() + } +} + /// `Weak` is a version of [`Rc`] that holds a non-owning reference to the /// managed value. The value is accessed by calling [`upgrade`] on the `Weak` /// pointer, which returns an [`Option`]`<`[`Rc`]`>`. diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index 6c23b3179ed..a0b06fabe32 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -1785,6 +1785,13 @@ impl From> for Arc<[T]> { } } +#[stable(feature = "shared_from_iter", since = "1.37.0")] +impl core::iter::FromIterator for Arc<[T]> { + fn from_iter>(iter: I) -> Self { + iter.into_iter().collect::>().into() + } +} + #[cfg(test)] mod tests { use std::boxed::Box; -- cgit 1.4.1-3-g733a5 From 19982f5653946b9d770f35560115ccc7a25356d4 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 19 Jun 2019 04:46:19 +0200 Subject: Rc: refactor away PhantomData noise. --- src/liballoc/rc.rs | 53 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 23 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index df97b0efc6c..f9af752cae6 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -286,6 +286,19 @@ impl, U: ?Sized> CoerceUnsized> for Rc {} #[unstable(feature = "dispatch_from_dyn", issue = "0")] impl, U: ?Sized> DispatchFromDyn> for Rc {} +impl Rc { + fn from_inner(ptr: NonNull>) -> Self { + Self { + ptr, + phantom: PhantomData, + } + } + + unsafe fn from_ptr(ptr: *mut RcBox) -> Self { + Self::from_inner(NonNull::new_unchecked(ptr)) + } +} + impl Rc { /// Constructs a new `Rc`. /// @@ -298,18 +311,15 @@ impl Rc { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn new(value: T) -> Rc { - Rc { - // there is an implicit weak pointer owned by all the strong - // pointers, which ensures that the weak destructor never frees - // the allocation while the strong destructor is running, even - // if the weak pointer is stored inside the strong one. - ptr: Box::into_raw_non_null(box RcBox { - strong: Cell::new(1), - weak: Cell::new(1), - value, - }), - phantom: PhantomData, - } + // There is an implicit weak pointer owned by all the strong + // pointers, which ensures that the weak destructor never frees + // the allocation while the strong destructor is running, even + // if the weak pointer is stored inside the strong one. + Self::from_inner(Box::into_raw_non_null(box RcBox { + strong: Cell::new(1), + weak: Cell::new(1), + value, + })) } /// Constructs a new `Pin>`. If `T` does not implement `Unpin`, then @@ -422,10 +432,7 @@ impl Rc { let fake_ptr = ptr as *mut RcBox; let rc_ptr = set_data_ptr(fake_ptr, (ptr as *mut u8).offset(-offset)); - Rc { - ptr: NonNull::new_unchecked(rc_ptr), - phantom: PhantomData, - } + Self::from_ptr(rc_ptr) } /// Consumes the `Rc`, returning the wrapped pointer as `NonNull`. @@ -683,7 +690,7 @@ impl Rc { if (*self).is::() { let ptr = self.ptr.cast::>(); forget(self); - Ok(Rc { ptr, phantom: PhantomData }) + Ok(Rc::from_inner(ptr)) } else { Err(self) } @@ -731,7 +738,7 @@ impl Rc { // Free the allocation without dropping its contents box_free(box_unique); - Rc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData } + Self::from_ptr(ptr) } } } @@ -758,7 +765,7 @@ impl Rc<[T]> { &mut (*ptr).value as *mut [T] as *mut T, v.len()); - Rc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData } + Self::from_ptr(ptr) } } @@ -800,7 +807,7 @@ impl RcFromSlice for Rc<[T]> { // Pointer to first element let elems = &mut (*ptr).value as *mut [T] as *mut T; - let mut guard = Guard{ + let mut guard = Guard { mem: NonNull::new_unchecked(mem), elems: elems, layout: layout, @@ -815,7 +822,7 @@ impl RcFromSlice for Rc<[T]> { // All clear. Forget the guard so it doesn't free the new RcBox. forget(guard); - Rc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData } + Self::from_ptr(ptr) } } } @@ -907,7 +914,7 @@ impl Clone for Rc { #[inline] fn clone(&self) -> Rc { self.inc_strong(); - Rc { ptr: self.ptr, phantom: PhantomData } + Self::from_inner(self.ptr) } } @@ -1463,7 +1470,7 @@ impl Weak { None } else { inner.inc_strong(); - Some(Rc { ptr: self.ptr, phantom: PhantomData }) + Some(Rc::from_inner(self.ptr)) } } -- cgit 1.4.1-3-g733a5 From 2efbc9e5a2c5ae36ed2de0b23f315a5d6853b747 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 19 Jun 2019 04:48:46 +0200 Subject: Rc: refactor data_offset{_sized}. --- src/liballoc/rc.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index f9af752cae6..252b1c5a6dc 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -2176,18 +2176,19 @@ impl AsRef for Rc { impl Unpin for Rc { } unsafe fn data_offset(ptr: *const T) -> isize { - // Align the unsized value to the end of the RcBox. + // Align the unsized value to the end of the `RcBox`. // Because it is ?Sized, it will always be the last field in memory. - let align = align_of_val(&*ptr); - let layout = Layout::new::>(); - (layout.size() + layout.padding_needed_for(align)) as isize + data_offset_align(align_of_val(&*ptr)) } -/// Computes the offset of the data field within ArcInner. +/// Computes the offset of the data field within `RcBox`. /// /// Unlike [`data_offset`], this doesn't need the pointer, but it works only on `T: Sized`. fn data_offset_sized() -> isize { - let align = align_of::(); + data_offset_align(align_of::()) +} + +fn data_offset_align(align: usize) -> isize { let layout = Layout::new::>(); (layout.size() + layout.padding_needed_for(align)) as isize } -- cgit 1.4.1-3-g733a5 From bf8f6c399b886480a2f2710531cf76de46b1c0cd Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 19 Jun 2019 04:56:58 +0200 Subject: Rc: reduce duplicate calls. --- src/liballoc/rc.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 252b1c5a6dc..970b4745c31 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -1674,14 +1674,16 @@ trait RcBoxPtr { #[inline] fn inc_strong(&self) { + let strong = self.strong(); + // We want to abort on overflow instead of dropping the value. // The reference count will never be zero when this is called; // nevertheless, we insert an abort here to hint LLVM at // an otherwise missed optimization. - if self.strong() == 0 || self.strong() == usize::max_value() { + if strong == 0 || strong == usize::max_value() { unsafe { abort(); } } - self.inner().strong.set(self.strong() + 1); + self.inner().strong.set(strong + 1); } #[inline] @@ -1696,14 +1698,16 @@ trait RcBoxPtr { #[inline] fn inc_weak(&self) { + let weak = self.weak(); + // We want to abort on overflow instead of dropping the value. // The reference count will never be zero when this is called; // nevertheless, we insert an abort here to hint LLVM at // an otherwise missed optimization. - if self.weak() == 0 || self.weak() == usize::max_value() { + if weak == 0 || weak == usize::max_value() { unsafe { abort(); } } - self.inner().weak.set(self.weak() + 1); + self.inner().weak.set(weak + 1); } #[inline] -- cgit 1.4.1-3-g733a5 From 353c8eb828ec7a68621334b91bf0f01eaf3ed769 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 19 Jun 2019 09:36:20 +0200 Subject: shared_from_iter/Rc: Use specialization to elide allocation. --- src/liballoc/lib.rs | 1 + src/liballoc/rc.rs | 206 ++++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 168 insertions(+), 39 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 5fc58c8ab5a..b679abacdc8 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -102,6 +102,7 @@ #![feature(try_reserve)] #![feature(unboxed_closures)] #![feature(unicode_internals)] +#![feature(untagged_unions)] #![feature(unsize)] #![feature(unsized_locals)] #![feature(allocator_internals)] diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 970b4745c31..43b6b3cea15 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -238,12 +238,13 @@ use core::cmp::Ordering; use core::fmt; use core::hash::{Hash, Hasher}; use core::intrinsics::abort; +use core::iter; use core::marker::{self, Unpin, Unsize, PhantomData}; use core::mem::{self, align_of, align_of_val, forget, size_of_val}; use core::ops::{Deref, Receiver, CoerceUnsized, DispatchFromDyn}; use core::pin::Pin; use core::ptr::{self, NonNull}; -use core::slice::from_raw_parts_mut; +use core::slice::{self, from_raw_parts_mut}; use core::convert::From; use core::usize; @@ -698,21 +699,29 @@ impl Rc { } impl Rc { - // Allocates an `RcBox` with sufficient space for an unsized value - unsafe fn allocate_for_ptr(ptr: *const T) -> *mut RcBox { - // Calculate layout using the given value. + // Allocates an `RcBox` with sufficient space for + // an unsized value where the value has the layout provided. + // + // The function `mem_to_rcbox` is called with the data pointer + // and must return back a (potentially fat)-pointer for the `RcBox`. + unsafe fn allocate_for_unsized( + value_layout: Layout, + mem_to_rcbox: impl FnOnce(*mut u8) -> *mut RcBox + ) -> *mut RcBox { + // Calculate layout using the given value layout. // Previously, layout was calculated on the expression // `&*(ptr as *const RcBox)`, but this created a misaligned // reference (see #54908). let layout = Layout::new::>() - .extend(Layout::for_value(&*ptr)).unwrap().0 + .extend(value_layout).unwrap().0 .pad_to_align().unwrap(); + // Allocate for the layout. let mem = Global.alloc(layout) .unwrap_or_else(|_| handle_alloc_error(layout)); // Initialize the RcBox - let inner = set_data_ptr(ptr as *mut T, mem.as_ptr() as *mut u8) as *mut RcBox; + let inner = mem_to_rcbox(mem.as_ptr()); debug_assert_eq!(Layout::for_value(&*inner), layout); ptr::write(&mut (*inner).strong, Cell::new(1)); @@ -721,6 +730,15 @@ impl Rc { inner } + // Allocates an `RcBox` with sufficient space for an unsized value + unsafe fn allocate_for_ptr(ptr: *const T) -> *mut RcBox { + // Allocate for the `RcBox` using the given value. + Self::allocate_for_unsized( + Layout::for_value(&*ptr), + |mem| set_data_ptr(ptr as *mut T, mem) as *mut RcBox, + ) + } + fn from_box(v: Box) -> Rc { unsafe { let box_unique = Box::into_unique(v); @@ -743,6 +761,32 @@ impl Rc { } } +impl Rc<[T]> { + // Allocates an `RcBox<[T]>` with the given length. + unsafe fn allocate_for_slice(len: usize) -> *mut RcBox<[T]> { + // FIXME(#60667): Deduplicate. + fn slice_from_raw_parts_mut(data: *mut T, len: usize) -> *mut [T] { + #[repr(C)] + union Repr { + rust_mut: *mut [T], + raw: FatPtr, + } + + #[repr(C)] + struct FatPtr { + data: *const T, + len: usize, + } + unsafe { Repr { raw: FatPtr { data, len } }.rust_mut } + } + + Self::allocate_for_unsized( + Layout::array::(len).unwrap(), + |mem| slice_from_raw_parts_mut(mem as *mut T, len) as *mut RcBox<[T]>, + ) + } +} + // Sets the data pointer of a `?Sized` raw pointer. // // For a slice/trait object, this sets the `data` field and leaves the rest @@ -757,8 +801,7 @@ impl Rc<[T]> { // // Unsafe because the caller must either take ownership or bind `T: Copy` unsafe fn copy_from_slice(v: &[T]) -> Rc<[T]> { - let v_ptr = v as *const [T]; - let ptr = Self::allocate_for_ptr(v_ptr); + let ptr = Self::allocate_for_slice(v.len()); ptr::copy_nonoverlapping( v.as_ptr(), @@ -767,15 +810,11 @@ impl Rc<[T]> { Self::from_ptr(ptr) } -} -trait RcFromSlice { - fn from_slice(slice: &[T]) -> Self; -} - -impl RcFromSlice for Rc<[T]> { - #[inline] - default fn from_slice(v: &[T]) -> Self { + /// Constructs an `Rc<[T]>` from an iterator known to be of a certain size. + /// + /// Behavior is undefined should the size be wrong. + unsafe fn from_iter_exact(iter: impl iter::Iterator, len: usize) -> Rc<[T]> { // Panic guard while cloning T elements. // In the event of a panic, elements that have been written // into the new RcBox will be dropped, then the memory freed. @@ -797,32 +836,42 @@ impl RcFromSlice for Rc<[T]> { } } - unsafe { - let v_ptr = v as *const [T]; - let ptr = Self::allocate_for_ptr(v_ptr); + let ptr = Self::allocate_for_slice(len); - let mem = ptr as *mut _ as *mut u8; - let layout = Layout::for_value(&*ptr); + let mem = ptr as *mut _ as *mut u8; + let layout = Layout::for_value(&*ptr); - // Pointer to first element - let elems = &mut (*ptr).value as *mut [T] as *mut T; + // Pointer to first element + let elems = &mut (*ptr).value as *mut [T] as *mut T; - let mut guard = Guard { - mem: NonNull::new_unchecked(mem), - elems: elems, - layout: layout, - n_elems: 0, - }; + let mut guard = Guard { + mem: NonNull::new_unchecked(mem), + elems, + layout, + n_elems: 0, + }; - for (i, item) in v.iter().enumerate() { - ptr::write(elems.add(i), item.clone()); - guard.n_elems += 1; - } + for (i, item) in iter.enumerate() { + ptr::write(elems.add(i), item); + guard.n_elems += 1; + } - // All clear. Forget the guard so it doesn't free the new RcBox. - forget(guard); + // All clear. Forget the guard so it doesn't free the new RcBox. + forget(guard); - Self::from_ptr(ptr) + Self::from_ptr(ptr) + } +} + +trait RcFromSlice { + fn from_slice(slice: &[T]) -> Self; +} + +impl RcFromSlice for Rc<[T]> { + #[inline] + default fn from_slice(v: &[T]) -> Self { + unsafe { + Self::from_iter_exact(v.iter().cloned(), v.len()) } } } @@ -1221,9 +1270,88 @@ impl From> for Rc<[T]> { } #[stable(feature = "shared_from_iter", since = "1.37.0")] -impl core::iter::FromIterator for Rc<[T]> { - fn from_iter>(iter: I) -> Self { - iter.into_iter().collect::>().into() +impl iter::FromIterator for Rc<[T]> { + /// Takes each element in the `Iterator` and collects it into an `Rc<[T]>`. + /// + /// # Performance characteristics + /// + /// ## The general case + /// + /// In the general case, collecting into `Rc<[T]>` is done by first + /// collecting into a `Vec`. That is, when writing the following: + /// + /// ```rust + /// # use std::rc::Rc; + /// let evens: Rc<[u8]> = (0..10).filter(|&x| x % 2 == 0).collect(); + /// # assert_eq!(&*evens, &[0, 2, 4, 6, 8]); + /// ``` + /// + /// this behaves as if we wrote: + /// + /// ```rust + /// # use std::rc::Rc; + /// let evens: Rc<[u8]> = (0..10).filter(|&x| x % 2 == 0) + /// .collect::>() // The first set of allocations happens here. + /// .into(); // A second allocation for `Rc<[T]>` happens here. + /// # assert_eq!(&*evens, &[0, 2, 4, 6, 8]); + /// ``` + /// + /// This will allocate as many times as needed for constructing the `Vec` + /// and then it will allocate once for turning the `Vec` into the `Rc<[T]>`. + /// + /// ## Iterators of known length + /// + /// When your `Iterator` implements `TrustedLen` and is of an exact size, + /// a single allocation will be made for the `Rc<[T]>`. For example: + /// + /// ```rust + /// # use std::rc::Rc; + /// let evens: Rc<[u8]> = (0..10).collect(); // Just a single allocation happens here. + /// # assert_eq!(&*evens, &*(0..10).collect::>()); + /// ``` + fn from_iter>(iter: I) -> Self { + RcFromIter::from_iter(iter.into_iter()) + } +} + +/// Specialization trait used for collecting into `Rc<[T]>`. +trait RcFromIter { + fn from_iter(iter: I) -> Self; +} + +impl> RcFromIter for Rc<[T]> { + default fn from_iter(iter: I) -> Self { + iter.collect::>().into() + } +} + +impl> RcFromIter for Rc<[T]> { + default fn from_iter(iter: I) -> Self { + // This is the case for a `TrustedLen` iterator. + let (low, high) = iter.size_hint(); + if let Some(high) = high { + debug_assert_eq!( + low, high, + "TrustedLen iterator's size hint is not exact: {:?}", + (low, high) + ); + + unsafe { + // SAFETY: We need to ensure that the iterator has an exact length and we have. + Rc::from_iter_exact(iter, low) + } + } else { + // Fall back to normal implementation. + iter.collect::>().into() + } + } +} + +impl<'a, T: 'a + Clone> RcFromIter<&'a T, slice::Iter<'a, T>> for Rc<[T]> { + fn from_iter(iter: slice::Iter<'a, T>) -> Self { + // Delegate to `impl From<&[T]> for Rc<[T]>` + // which will use `ptr::copy_nonoverlapping`. + iter.as_slice().into() } } -- cgit 1.4.1-3-g733a5 From 27f5d0f208e12176c614d6ffbd410f7b53ed9eed Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 19 Jun 2019 09:56:34 +0200 Subject: Arc: refactor away PhantomData noise. --- src/liballoc/sync.rs | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index a0b06fabe32..de47e164c92 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -206,6 +206,19 @@ impl, U: ?Sized> CoerceUnsized> for Arc {} #[unstable(feature = "dispatch_from_dyn", issue = "0")] impl, U: ?Sized> DispatchFromDyn> for Arc {} +impl Arc { + fn from_inner(ptr: NonNull>) -> Self { + Self { + ptr, + phantom: PhantomData, + } + } + + unsafe fn from_ptr(ptr: *mut ArcInner) -> Self { + Self::from_inner(NonNull::new_unchecked(ptr)) + } +} + /// `Weak` is a version of [`Arc`] that holds a non-owning reference to the /// managed value. The value is accessed by calling [`upgrade`] on the `Weak` /// pointer, which returns an [`Option`]`<`[`Arc`]`>`. @@ -290,7 +303,7 @@ impl Arc { weak: atomic::AtomicUsize::new(1), data, }; - Arc { ptr: Box::into_raw_non_null(x), phantom: PhantomData } + Self::from_inner(Box::into_raw_non_null(x)) } /// Constructs a new `Pin>`. If `T` does not implement `Unpin`, then @@ -403,10 +416,7 @@ impl Arc { let fake_ptr = ptr as *mut ArcInner; let arc_ptr = set_data_ptr(fake_ptr, (ptr as *mut u8).offset(-offset)); - Arc { - ptr: NonNull::new_unchecked(arc_ptr), - phantom: PhantomData, - } + Self::from_ptr(arc_ptr) } /// Consumes the `Arc`, returning the wrapped pointer as `NonNull`. @@ -617,7 +627,7 @@ impl Arc { // Free the allocation without dropping its contents box_free(box_unique); - Arc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData } + Self::from_ptr(ptr) } } } @@ -644,7 +654,7 @@ impl Arc<[T]> { &mut (*ptr).data as *mut [T] as *mut T, v.len()); - Arc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData } + Self::from_ptr(ptr) } } @@ -702,7 +712,7 @@ impl ArcFromSlice for Arc<[T]> { // All clear. Forget the guard so it doesn't free the new ArcInner. mem::forget(guard); - Arc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData } + Self::from_ptr(ptr) } } } @@ -760,7 +770,7 @@ impl Clone for Arc { } } - Arc { ptr: self.ptr, phantom: PhantomData } + Self::from_inner(self.ptr) } } @@ -1039,7 +1049,7 @@ impl Arc { if (*self).is::() { let ptr = self.ptr.cast::>(); mem::forget(self); - Ok(Arc { ptr, phantom: PhantomData }) + Ok(Arc::from_inner(ptr)) } else { Err(self) } @@ -1260,11 +1270,7 @@ impl Weak { // Relaxed is valid for the same reason it is on Arc's Clone impl match inner.strong.compare_exchange_weak(n, n + 1, Relaxed, Relaxed) { - Ok(_) => return Some(Arc { - // null checked above - ptr: self.ptr, - phantom: PhantomData, - }), + Ok(_) => return Some(Arc::from_inner(self.ptr)), // null checked above Err(old) => n = old, } } -- cgit 1.4.1-3-g733a5 From 59ecff915ce3fbef44ca5591d69c2c908a88ca0b Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 19 Jun 2019 10:00:24 +0200 Subject: Arc: refactor data_offset{_sized}. --- src/liballoc/sync.rs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index de47e164c92..127068284d3 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -2298,20 +2298,21 @@ impl AsRef for Arc { #[stable(feature = "pin", since = "1.33.0")] impl Unpin for Arc { } -/// Computes the offset of the data field within ArcInner. +/// Computes the offset of the data field within `ArcInner`. unsafe fn data_offset(ptr: *const T) -> isize { - // Align the unsized value to the end of the ArcInner. - // Because it is ?Sized, it will always be the last field in memory. - let align = align_of_val(&*ptr); - let layout = Layout::new::>(); - (layout.size() + layout.padding_needed_for(align)) as isize + // Align the unsized value to the end of the `ArcInner`. + // Because it is `?Sized`, it will always be the last field in memory. + data_offset_align(align_of_val(&*ptr)) } -/// Computes the offset of the data field within ArcInner. +/// Computes the offset of the data field within `ArcInner`. /// /// Unlike [`data_offset`], this doesn't need the pointer, but it works only on `T: Sized`. fn data_offset_sized() -> isize { - let align = align_of::(); + data_offset_align(align_of::()) +} + +fn data_offset_align(align: usize) -> isize { let layout = Layout::new::>(); (layout.size() + layout.padding_needed_for(align)) as isize } -- cgit 1.4.1-3-g733a5 From b1dbf15bb5d06b8213b8ed3c61b0f92faf1c001c Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 19 Jun 2019 10:23:28 +0200 Subject: shared_from_iter/Arc: Use specialization to elide allocation. --- src/liballoc/sync.rs | 207 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 167 insertions(+), 40 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index 127068284d3..caf727081b1 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -12,6 +12,7 @@ use core::sync::atomic::Ordering::{Acquire, Relaxed, Release, SeqCst}; use core::borrow; use core::fmt; use core::cmp::{self, Ordering}; +use core::iter; use core::intrinsics::abort; use core::mem::{self, align_of, align_of_val, size_of_val}; use core::ops::{Deref, Receiver, CoerceUnsized, DispatchFromDyn}; @@ -21,7 +22,7 @@ use core::marker::{Unpin, Unsize, PhantomData}; use core::hash::{Hash, Hasher}; use core::{isize, usize}; use core::convert::From; -use core::slice::from_raw_parts_mut; +use core::slice::{self, from_raw_parts_mut}; use crate::alloc::{Global, Alloc, Layout, box_free, handle_alloc_error}; use crate::boxed::Box; @@ -587,21 +588,28 @@ impl Arc { } impl Arc { - // Allocates an `ArcInner` with sufficient space for an unsized value - unsafe fn allocate_for_ptr(ptr: *const T) -> *mut ArcInner { - // Calculate layout using the given value. + // Allocates an `ArcInner` with sufficient space for + // an unsized value where the value has the layout provided. + // + // The function `mem_to_arcinner` is called with the data pointer + // and must return back a (potentially fat)-pointer for the `ArcInner`. + unsafe fn allocate_for_unsized( + value_layout: Layout, + mem_to_arcinner: impl FnOnce(*mut u8) -> *mut ArcInner + ) -> *mut ArcInner { + // Calculate layout using the given value layout. // Previously, layout was calculated on the expression // `&*(ptr as *const ArcInner)`, but this created a misaligned // reference (see #54908). let layout = Layout::new::>() - .extend(Layout::for_value(&*ptr)).unwrap().0 + .extend(value_layout).unwrap().0 .pad_to_align().unwrap(); let mem = Global.alloc(layout) .unwrap_or_else(|_| handle_alloc_error(layout)); // Initialize the ArcInner - let inner = set_data_ptr(ptr as *mut T, mem.as_ptr() as *mut u8) as *mut ArcInner; + let inner = mem_to_arcinner(mem.as_ptr()); debug_assert_eq!(Layout::for_value(&*inner), layout); ptr::write(&mut (*inner).strong, atomic::AtomicUsize::new(1)); @@ -610,6 +618,15 @@ impl Arc { inner } + // Allocates an `ArcInner` with sufficient space for an unsized value + unsafe fn allocate_for_ptr(ptr: *const T) -> *mut ArcInner { + // Allocate for the `ArcInner` using the given value. + Self::allocate_for_unsized( + Layout::for_value(&*ptr), + |mem| set_data_ptr(ptr as *mut T, mem) as *mut ArcInner, + ) + } + fn from_box(v: Box) -> Arc { unsafe { let box_unique = Box::into_unique(v); @@ -632,6 +649,32 @@ impl Arc { } } +impl Arc<[T]> { + // Allocates an `ArcInner<[T]>` with the given length. + unsafe fn allocate_for_slice(len: usize) -> *mut ArcInner<[T]> { + // FIXME(#60667): Deduplicate. + fn slice_from_raw_parts_mut(data: *mut T, len: usize) -> *mut [T] { + #[repr(C)] + union Repr { + rust_mut: *mut [T], + raw: FatPtr, + } + + #[repr(C)] + struct FatPtr { + data: *const T, + len: usize, + } + unsafe { Repr { raw: FatPtr { data, len } }.rust_mut } + } + + Self::allocate_for_unsized( + Layout::array::(len).unwrap(), + |mem| slice_from_raw_parts_mut(mem as *mut T, len) as *mut ArcInner<[T]>, + ) + } +} + // Sets the data pointer of a `?Sized` raw pointer. // // For a slice/trait object, this sets the `data` field and leaves the rest @@ -646,8 +689,7 @@ impl Arc<[T]> { // // Unsafe because the caller must either take ownership or bind `T: Copy` unsafe fn copy_from_slice(v: &[T]) -> Arc<[T]> { - let v_ptr = v as *const [T]; - let ptr = Self::allocate_for_ptr(v_ptr); + let ptr = Self::allocate_for_slice(v.len()); ptr::copy_nonoverlapping( v.as_ptr(), @@ -656,16 +698,11 @@ impl Arc<[T]> { Self::from_ptr(ptr) } -} -// Specialization trait used for From<&[T]> -trait ArcFromSlice { - fn from_slice(slice: &[T]) -> Self; -} - -impl ArcFromSlice for Arc<[T]> { - #[inline] - default fn from_slice(v: &[T]) -> Self { + /// Constructs an `Arc<[T]>` from an iterator known to be of a certain size. + /// + /// Behavior is undefined should the size be wrong. + unsafe fn from_iter_exact(iter: impl iter::Iterator, len: usize) -> Arc<[T]> { // Panic guard while cloning T elements. // In the event of a panic, elements that have been written // into the new ArcInner will be dropped, then the memory freed. @@ -687,32 +724,43 @@ impl ArcFromSlice for Arc<[T]> { } } - unsafe { - let v_ptr = v as *const [T]; - let ptr = Self::allocate_for_ptr(v_ptr); + let ptr = Self::allocate_for_slice(len); + + let mem = ptr as *mut _ as *mut u8; + let layout = Layout::for_value(&*ptr); - let mem = ptr as *mut _ as *mut u8; - let layout = Layout::for_value(&*ptr); + // Pointer to first element + let elems = &mut (*ptr).data as *mut [T] as *mut T; - // Pointer to first element - let elems = &mut (*ptr).data as *mut [T] as *mut T; + let mut guard = Guard { + mem: NonNull::new_unchecked(mem), + elems, + layout, + n_elems: 0, + }; - let mut guard = Guard{ - mem: NonNull::new_unchecked(mem), - elems: elems, - layout: layout, - n_elems: 0, - }; + for (i, item) in iter.enumerate() { + ptr::write(elems.add(i), item); + guard.n_elems += 1; + } - for (i, item) in v.iter().enumerate() { - ptr::write(elems.add(i), item.clone()); - guard.n_elems += 1; - } + // All clear. Forget the guard so it doesn't free the new ArcInner. + mem::forget(guard); - // All clear. Forget the guard so it doesn't free the new ArcInner. - mem::forget(guard); + Self::from_ptr(ptr) + } +} - Self::from_ptr(ptr) +// Specialization trait used for From<&[T]> +trait ArcFromSlice { + fn from_slice(slice: &[T]) -> Self; +} + +impl ArcFromSlice for Arc<[T]> { + #[inline] + default fn from_slice(v: &[T]) -> Self { + unsafe { + Self::from_iter_exact(v.iter().cloned(), v.len()) } } } @@ -1792,9 +1840,88 @@ impl From> for Arc<[T]> { } #[stable(feature = "shared_from_iter", since = "1.37.0")] -impl core::iter::FromIterator for Arc<[T]> { - fn from_iter>(iter: I) -> Self { - iter.into_iter().collect::>().into() +impl iter::FromIterator for Arc<[T]> { + /// Takes each element in the `Iterator` and collects it into an `Arc<[T]>`. + /// + /// # Performance characteristics + /// + /// ## The general case + /// + /// In the general case, collecting into `Arc<[T]>` is done by first + /// collecting into a `Vec`. That is, when writing the following: + /// + /// ```rust + /// # use std::sync::Arc; + /// let evens: Arc<[u8]> = (0..10).filter(|&x| x % 2 == 0).collect(); + /// # assert_eq!(&*evens, &[0, 2, 4, 6, 8]); + /// ``` + /// + /// this behaves as if we wrote: + /// + /// ```rust + /// # use std::sync::Arc; + /// let evens: Arc<[u8]> = (0..10).filter(|&x| x % 2 == 0) + /// .collect::>() // The first set of allocations happens here. + /// .into(); // A second allocation for `Arc<[T]>` happens here. + /// # assert_eq!(&*evens, &[0, 2, 4, 6, 8]); + /// ``` + /// + /// This will allocate as many times as needed for constructing the `Vec` + /// and then it will allocate once for turning the `Vec` into the `Arc<[T]>`. + /// + /// ## Iterators of known length + /// + /// When your `Iterator` implements `TrustedLen` and is of an exact size, + /// a single allocation will be made for the `Arc<[T]>`. For example: + /// + /// ```rust + /// # use std::sync::Arc; + /// let evens: Arc<[u8]> = (0..10).collect(); // Just a single allocation happens here. + /// # assert_eq!(&*evens, &*(0..10).collect::>()); + /// ``` + fn from_iter>(iter: I) -> Self { + ArcFromIter::from_iter(iter.into_iter()) + } +} + +/// Specialization trait used for collecting into `Arc<[T]>`. +trait ArcFromIter { + fn from_iter(iter: I) -> Self; +} + +impl> ArcFromIter for Arc<[T]> { + default fn from_iter(iter: I) -> Self { + iter.collect::>().into() + } +} + +impl> ArcFromIter for Arc<[T]> { + default fn from_iter(iter: I) -> Self { + // This is the case for a `TrustedLen` iterator. + let (low, high) = iter.size_hint(); + if let Some(high) = high { + debug_assert_eq!( + low, high, + "TrustedLen iterator's size hint is not exact: {:?}", + (low, high) + ); + + unsafe { + // SAFETY: We need to ensure that the iterator has an exact length and we have. + Arc::from_iter_exact(iter, low) + } + } else { + // Fall back to normal implementation. + iter.collect::>().into() + } + } +} + +impl<'a, T: 'a + Clone> ArcFromIter<&'a T, slice::Iter<'a, T>> for Arc<[T]> { + fn from_iter(iter: slice::Iter<'a, T>) -> Self { + // Delegate to `impl From<&[T]> for Arc<[T]>` + // which will use `ptr::copy_nonoverlapping`. + iter.as_slice().into() } } -- cgit 1.4.1-3-g733a5 From 4b44ad9038ec421b21a971429e55475f1c1bd81e Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 20 Jun 2019 09:28:01 +0200 Subject: deduplicate slice_from_raw_parts_mut. --- src/liballoc/lib.rs | 2 +- src/liballoc/rc.rs | 18 +----------------- src/liballoc/sync.rs | 18 +----------------- 3 files changed, 3 insertions(+), 35 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index b679abacdc8..cef41f974e4 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -94,6 +94,7 @@ #![feature(ptr_offset_from)] #![feature(rustc_attrs)] #![feature(receiver_trait)] +#![feature(slice_from_raw_parts)] #![feature(specialization)] #![feature(staged_api)] #![feature(std_internals)] @@ -102,7 +103,6 @@ #![feature(try_reserve)] #![feature(unboxed_closures)] #![feature(unicode_internals)] -#![feature(untagged_unions)] #![feature(unsize)] #![feature(unsized_locals)] #![feature(allocator_internals)] diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 43b6b3cea15..1e9cd3ff396 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -764,25 +764,9 @@ impl Rc { impl Rc<[T]> { // Allocates an `RcBox<[T]>` with the given length. unsafe fn allocate_for_slice(len: usize) -> *mut RcBox<[T]> { - // FIXME(#60667): Deduplicate. - fn slice_from_raw_parts_mut(data: *mut T, len: usize) -> *mut [T] { - #[repr(C)] - union Repr { - rust_mut: *mut [T], - raw: FatPtr, - } - - #[repr(C)] - struct FatPtr { - data: *const T, - len: usize, - } - unsafe { Repr { raw: FatPtr { data, len } }.rust_mut } - } - Self::allocate_for_unsized( Layout::array::(len).unwrap(), - |mem| slice_from_raw_parts_mut(mem as *mut T, len) as *mut RcBox<[T]>, + |mem| ptr::slice_from_raw_parts_mut(mem as *mut T, len) as *mut RcBox<[T]>, ) } } diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index caf727081b1..07eae916894 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -652,25 +652,9 @@ impl Arc { impl Arc<[T]> { // Allocates an `ArcInner<[T]>` with the given length. unsafe fn allocate_for_slice(len: usize) -> *mut ArcInner<[T]> { - // FIXME(#60667): Deduplicate. - fn slice_from_raw_parts_mut(data: *mut T, len: usize) -> *mut [T] { - #[repr(C)] - union Repr { - rust_mut: *mut [T], - raw: FatPtr, - } - - #[repr(C)] - struct FatPtr { - data: *const T, - len: usize, - } - unsafe { Repr { raw: FatPtr { data, len } }.rust_mut } - } - Self::allocate_for_unsized( Layout::array::(len).unwrap(), - |mem| slice_from_raw_parts_mut(mem as *mut T, len) as *mut ArcInner<[T]>, + |mem| ptr::slice_from_raw_parts_mut(mem as *mut T, len) as *mut ArcInner<[T]>, ) } } -- cgit 1.4.1-3-g733a5 From 85978d028ad6edb1530c494682c05b46f26900f6 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 20 Jun 2019 23:13:06 +0200 Subject: data_offset_align: add inline attribute. --- src/liballoc/rc.rs | 1 + src/liballoc/sync.rs | 1 + 2 files changed, 2 insertions(+) (limited to 'src/liballoc') diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 1e9cd3ff396..a222dbc93a8 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -2304,6 +2304,7 @@ fn data_offset_sized() -> isize { data_offset_align(align_of::()) } +#[inline] fn data_offset_align(align: usize) -> isize { let layout = Layout::new::>(); (layout.size() + layout.padding_needed_for(align)) as isize diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index 07eae916894..f5110905a11 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -2423,6 +2423,7 @@ fn data_offset_sized() -> isize { data_offset_align(align_of::()) } +#[inline] fn data_offset_align(align: usize) -> isize { let layout = Layout::new::>(); (layout.size() + layout.padding_needed_for(align)) as isize -- cgit 1.4.1-3-g733a5 From 6b8417b55c59f3412e97131fd1f99e34bdd8f5d2 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 20 Jun 2019 23:20:21 +0200 Subject: shared_from_iter: Clarify slice::Iter specialization impl. --- src/liballoc/rc.rs | 10 ++++++++-- src/liballoc/sync.rs | 10 ++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index a222dbc93a8..9b653fe2d75 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -1333,8 +1333,14 @@ impl> RcFromIter for Rc<[T]> { impl<'a, T: 'a + Clone> RcFromIter<&'a T, slice::Iter<'a, T>> for Rc<[T]> { fn from_iter(iter: slice::Iter<'a, T>) -> Self { - // Delegate to `impl From<&[T]> for Rc<[T]>` - // which will use `ptr::copy_nonoverlapping`. + // Delegate to `impl From<&[T]> for Rc<[T]>`. + // + // In the case that `T: Copy`, we get to use `ptr::copy_nonoverlapping` + // which is even more performant. + // + // In the fall-back case we have `T: Clone`. This is still better + // than the `TrustedLen` implementation as slices have a known length + // and so we get to avoid calling `size_hint` and avoid the branching. iter.as_slice().into() } } diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index f5110905a11..672481ca0de 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -1903,8 +1903,14 @@ impl> ArcFromIter for Arc<[T]> { impl<'a, T: 'a + Clone> ArcFromIter<&'a T, slice::Iter<'a, T>> for Arc<[T]> { fn from_iter(iter: slice::Iter<'a, T>) -> Self { - // Delegate to `impl From<&[T]> for Arc<[T]>` - // which will use `ptr::copy_nonoverlapping`. + // Delegate to `impl From<&[T]> for Rc<[T]>`. + // + // In the case that `T: Copy`, we get to use `ptr::copy_nonoverlapping` + // which is even more performant. + // + // In the fall-back case we have `T: Clone`. This is still better + // than the `TrustedLen` implementation as slices have a known length + // and so we get to avoid calling `size_hint` and avoid the branching. iter.as_slice().into() } } -- cgit 1.4.1-3-g733a5 From 8bbf1abd0ec903ff4408238e86d712aeba1cbd7f Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Fri, 21 Jun 2019 03:52:38 +0200 Subject: shared_from_iter: Add more tests. --- src/liballoc/tests/arc.rs | 119 ++++++++++++++++++++++++++++++++++++++++++++++ src/liballoc/tests/lib.rs | 2 + src/liballoc/tests/rc.rs | 117 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 238 insertions(+) (limited to 'src/liballoc') diff --git a/src/liballoc/tests/arc.rs b/src/liballoc/tests/arc.rs index 2759b1b1cac..ce64e2de013 100644 --- a/src/liballoc/tests/arc.rs +++ b/src/liballoc/tests/arc.rs @@ -2,6 +2,8 @@ use std::any::Any; use std::sync::{Arc, Weak}; use std::cell::RefCell; use std::cmp::PartialEq; +use std::iter::TrustedLen; +use std::mem; #[test] fn uninhabited() { @@ -85,3 +87,120 @@ fn eq() { assert!(!(x != x)); assert_eq!(*x.0.borrow(), 0); } + +type Rc = Arc; + +const SHARED_ITER_MAX: u16 = 100; + +fn assert_trusted_len(_: &I) {} + +#[test] +fn shared_from_iter_normal() { + // Exercise the base implementation for non-`TrustedLen` iterators. + { + // `Filter` is never `TrustedLen` since we don't + // know statically how many elements will be kept: + let iter = (0..SHARED_ITER_MAX).filter(|x| x % 2 == 0).map(Box::new); + + // Collecting into a `Vec` or `Rc<[T]>` should make no difference: + let vec = iter.clone().collect::>(); + let rc = iter.collect::>(); + assert_eq!(&*vec, &*rc); + + // Clone a bit and let these get dropped. + { + let _rc_2 = rc.clone(); + let _rc_3 = rc.clone(); + let _rc_4 = Rc::downgrade(&_rc_3); + } + } // Drop what hasn't been here. +} + +#[test] +fn shared_from_iter_trustedlen_normal() { + // Exercise the `TrustedLen` implementation under normal circumstances + // where `size_hint()` matches `(_, Some(exact_len))`. + { + let iter = (0..SHARED_ITER_MAX).map(Box::new); + assert_trusted_len(&iter); + + // Collecting into a `Vec` or `Rc<[T]>` should make no difference: + let vec = iter.clone().collect::>(); + let rc = iter.collect::>(); + assert_eq!(&*vec, &*rc); + assert_eq!(mem::size_of::>() * SHARED_ITER_MAX as usize, mem::size_of_val(&*rc)); + + // Clone a bit and let these get dropped. + { + let _rc_2 = rc.clone(); + let _rc_3 = rc.clone(); + let _rc_4 = Rc::downgrade(&_rc_3); + } + } // Drop what hasn't been here. + + // Try a ZST to make sure it is handled well. + { + let iter = (0..SHARED_ITER_MAX).map(|_| ()); + let vec = iter.clone().collect::>(); + let rc = iter.collect::>(); + assert_eq!(&*vec, &*rc); + assert_eq!(0, mem::size_of_val(&*rc)); + { + let _rc_2 = rc.clone(); + let _rc_3 = rc.clone(); + let _rc_4 = Rc::downgrade(&_rc_3); + } + } +} + +#[test] +#[should_panic = "I've almost got 99 problems."] +fn shared_from_iter_trustedlen_panic() { + // Exercise the `TrustedLen` implementation when `size_hint()` matches + // `(_, Some(exact_len))` but where `.next()` drops before the last iteration. + let iter = (0..SHARED_ITER_MAX) + .map(|val| { + match val { + 98 => panic!("I've almost got 99 problems."), + _ => Box::new(val), + } + }); + assert_trusted_len(&iter); + let _ = iter.collect::>(); + + panic!("I am unreachable."); +} + +#[test] +fn shared_from_iter_trustedlen_no_fuse() { + // Exercise the `TrustedLen` implementation when `size_hint()` matches + // `(_, Some(exact_len))` but where the iterator does not behave in a fused manner. + struct Iter(std::vec::IntoIter>>); + + unsafe impl TrustedLen for Iter {} + + impl Iterator for Iter { + fn size_hint(&self) -> (usize, Option) { + (2, Some(2)) + } + + type Item = Box; + + fn next(&mut self) -> Option { + self.0.next().flatten() + } + } + + let vec = vec![ + Some(Box::new(42)), + Some(Box::new(24)), + None, + Some(Box::new(12)), + ]; + let iter = Iter(vec.into_iter()); + assert_trusted_len(&iter); + assert_eq!( + &[Box::new(42), Box::new(24)], + &*iter.collect::>() + ); +} diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs index ddb3120e89d..5a43c8e09a2 100644 --- a/src/liballoc/tests/lib.rs +++ b/src/liballoc/tests/lib.rs @@ -2,8 +2,10 @@ #![feature(box_syntax)] #![feature(drain_filter)] #![feature(exact_size_is_empty)] +#![feature(option_flattening)] #![feature(pattern)] #![feature(repeat_generic_slice)] +#![feature(trusted_len)] #![feature(try_reserve)] #![feature(unboxed_closures)] #![deny(rust_2018_idioms)] diff --git a/src/liballoc/tests/rc.rs b/src/liballoc/tests/rc.rs index 18f82e80410..7854ca0fc16 100644 --- a/src/liballoc/tests/rc.rs +++ b/src/liballoc/tests/rc.rs @@ -2,6 +2,8 @@ use std::any::Any; use std::rc::{Rc, Weak}; use std::cell::RefCell; use std::cmp::PartialEq; +use std::mem; +use std::iter::TrustedLen; #[test] fn uninhabited() { @@ -85,3 +87,118 @@ fn eq() { assert!(!(x != x)); assert_eq!(*x.0.borrow(), 0); } + +const SHARED_ITER_MAX: u16 = 100; + +fn assert_trusted_len(_: &I) {} + +#[test] +fn shared_from_iter_normal() { + // Exercise the base implementation for non-`TrustedLen` iterators. + { + // `Filter` is never `TrustedLen` since we don't + // know statically how many elements will be kept: + let iter = (0..SHARED_ITER_MAX).filter(|x| x % 2 == 0).map(Box::new); + + // Collecting into a `Vec` or `Rc<[T]>` should make no difference: + let vec = iter.clone().collect::>(); + let rc = iter.collect::>(); + assert_eq!(&*vec, &*rc); + + // Clone a bit and let these get dropped. + { + let _rc_2 = rc.clone(); + let _rc_3 = rc.clone(); + let _rc_4 = Rc::downgrade(&_rc_3); + } + } // Drop what hasn't been here. +} + +#[test] +fn shared_from_iter_trustedlen_normal() { + // Exercise the `TrustedLen` implementation under normal circumstances + // where `size_hint()` matches `(_, Some(exact_len))`. + { + let iter = (0..SHARED_ITER_MAX).map(Box::new); + assert_trusted_len(&iter); + + // Collecting into a `Vec` or `Rc<[T]>` should make no difference: + let vec = iter.clone().collect::>(); + let rc = iter.collect::>(); + assert_eq!(&*vec, &*rc); + assert_eq!(mem::size_of::>() * SHARED_ITER_MAX as usize, mem::size_of_val(&*rc)); + + // Clone a bit and let these get dropped. + { + let _rc_2 = rc.clone(); + let _rc_3 = rc.clone(); + let _rc_4 = Rc::downgrade(&_rc_3); + } + } // Drop what hasn't been here. + + // Try a ZST to make sure it is handled well. + { + let iter = (0..SHARED_ITER_MAX).map(|_| ()); + let vec = iter.clone().collect::>(); + let rc = iter.collect::>(); + assert_eq!(&*vec, &*rc); + assert_eq!(0, mem::size_of_val(&*rc)); + { + let _rc_2 = rc.clone(); + let _rc_3 = rc.clone(); + let _rc_4 = Rc::downgrade(&_rc_3); + } + } +} + +#[test] +#[should_panic = "I've almost got 99 problems."] +fn shared_from_iter_trustedlen_panic() { + // Exercise the `TrustedLen` implementation when `size_hint()` matches + // `(_, Some(exact_len))` but where `.next()` drops before the last iteration. + let iter = (0..SHARED_ITER_MAX) + .map(|val| { + match val { + 98 => panic!("I've almost got 99 problems."), + _ => Box::new(val), + } + }); + assert_trusted_len(&iter); + let _ = iter.collect::>(); + + panic!("I am unreachable."); +} + +#[test] +fn shared_from_iter_trustedlen_no_fuse() { + // Exercise the `TrustedLen` implementation when `size_hint()` matches + // `(_, Some(exact_len))` but where the iterator does not behave in a fused manner. + struct Iter(std::vec::IntoIter>>); + + unsafe impl TrustedLen for Iter {} + + impl Iterator for Iter { + fn size_hint(&self) -> (usize, Option) { + (2, Some(2)) + } + + type Item = Box; + + fn next(&mut self) -> Option { + self.0.next().flatten() + } + } + + let vec = vec![ + Some(Box::new(42)), + Some(Box::new(24)), + None, + Some(Box::new(12)), + ]; + let iter = Iter(vec.into_iter()); + assert_trusted_len(&iter); + assert_eq!( + &[Box::new(42), Box::new(24)], + &*iter.collect::>() + ); +} -- cgit 1.4.1-3-g733a5 From 85def307fc83f8c0d164b1506bb855dfaed5f8b5 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Fri, 21 Jun 2019 23:01:48 +0200 Subject: shared_from_iter: Polish internal docs. --- src/liballoc/rc.rs | 29 +++++++++++++++-------------- src/liballoc/sync.rs | 32 ++++++++++++++++---------------- src/liballoc/tests/arc.rs | 2 ++ 3 files changed, 33 insertions(+), 30 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 9b653fe2d75..94cc0b18133 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -699,11 +699,11 @@ impl Rc { } impl Rc { - // Allocates an `RcBox` with sufficient space for - // an unsized value where the value has the layout provided. - // - // The function `mem_to_rcbox` is called with the data pointer - // and must return back a (potentially fat)-pointer for the `RcBox`. + /// Allocates an `RcBox` with sufficient space for + /// an unsized value where the value has the layout provided. + /// + /// The function `mem_to_rcbox` is called with the data pointer + /// and must return back a (potentially fat)-pointer for the `RcBox`. unsafe fn allocate_for_unsized( value_layout: Layout, mem_to_rcbox: impl FnOnce(*mut u8) -> *mut RcBox @@ -730,7 +730,7 @@ impl Rc { inner } - // Allocates an `RcBox` with sufficient space for an unsized value + /// Allocates an `RcBox` with sufficient space for an unsized value unsafe fn allocate_for_ptr(ptr: *const T) -> *mut RcBox { // Allocate for the `RcBox` using the given value. Self::allocate_for_unsized( @@ -762,7 +762,7 @@ impl Rc { } impl Rc<[T]> { - // Allocates an `RcBox<[T]>` with the given length. + /// Allocates an `RcBox<[T]>` with the given length. unsafe fn allocate_for_slice(len: usize) -> *mut RcBox<[T]> { Self::allocate_for_unsized( Layout::array::(len).unwrap(), @@ -771,19 +771,19 @@ impl Rc<[T]> { } } -// Sets the data pointer of a `?Sized` raw pointer. -// -// For a slice/trait object, this sets the `data` field and leaves the rest -// unchanged. For a sized raw pointer, this simply sets the pointer. +/// Sets the data pointer of a `?Sized` raw pointer. +/// +/// For a slice/trait object, this sets the `data` field and leaves the rest +/// unchanged. For a sized raw pointer, this simply sets the pointer. unsafe fn set_data_ptr(mut ptr: *mut T, data: *mut U) -> *mut T { ptr::write(&mut ptr as *mut _ as *mut *mut u8, data as *mut u8); ptr } impl Rc<[T]> { - // Copy elements from slice into newly allocated Rc<[T]> - // - // Unsafe because the caller must either take ownership or bind `T: Copy` + /// Copy elements from slice into newly allocated Rc<[T]> + /// + /// Unsafe because the caller must either take ownership or bind `T: Copy` unsafe fn copy_from_slice(v: &[T]) -> Rc<[T]> { let ptr = Self::allocate_for_slice(v.len()); @@ -847,6 +847,7 @@ impl Rc<[T]> { } } +/// Specialization trait used for `From<&[T]>`. trait RcFromSlice { fn from_slice(slice: &[T]) -> Self; } diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index 672481ca0de..0a9ce437978 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -588,11 +588,11 @@ impl Arc { } impl Arc { - // Allocates an `ArcInner` with sufficient space for - // an unsized value where the value has the layout provided. - // - // The function `mem_to_arcinner` is called with the data pointer - // and must return back a (potentially fat)-pointer for the `ArcInner`. + /// Allocates an `ArcInner` with sufficient space for + /// an unsized value where the value has the layout provided. + /// + /// The function `mem_to_arcinner` is called with the data pointer + /// and must return back a (potentially fat)-pointer for the `ArcInner`. unsafe fn allocate_for_unsized( value_layout: Layout, mem_to_arcinner: impl FnOnce(*mut u8) -> *mut ArcInner @@ -618,7 +618,7 @@ impl Arc { inner } - // Allocates an `ArcInner` with sufficient space for an unsized value + /// Allocates an `ArcInner` with sufficient space for an unsized value. unsafe fn allocate_for_ptr(ptr: *const T) -> *mut ArcInner { // Allocate for the `ArcInner` using the given value. Self::allocate_for_unsized( @@ -650,7 +650,7 @@ impl Arc { } impl Arc<[T]> { - // Allocates an `ArcInner<[T]>` with the given length. + /// Allocates an `ArcInner<[T]>` with the given length. unsafe fn allocate_for_slice(len: usize) -> *mut ArcInner<[T]> { Self::allocate_for_unsized( Layout::array::(len).unwrap(), @@ -659,19 +659,19 @@ impl Arc<[T]> { } } -// Sets the data pointer of a `?Sized` raw pointer. -// -// For a slice/trait object, this sets the `data` field and leaves the rest -// unchanged. For a sized raw pointer, this simply sets the pointer. +/// Sets the data pointer of a `?Sized` raw pointer. +/// +/// For a slice/trait object, this sets the `data` field and leaves the rest +/// unchanged. For a sized raw pointer, this simply sets the pointer. unsafe fn set_data_ptr(mut ptr: *mut T, data: *mut U) -> *mut T { ptr::write(&mut ptr as *mut _ as *mut *mut u8, data as *mut u8); ptr } impl Arc<[T]> { - // Copy elements from slice into newly allocated Arc<[T]> - // - // Unsafe because the caller must either take ownership or bind `T: Copy` + /// Copy elements from slice into newly allocated Arc<[T]> + /// + /// Unsafe because the caller must either take ownership or bind `T: Copy`. unsafe fn copy_from_slice(v: &[T]) -> Arc<[T]> { let ptr = Self::allocate_for_slice(v.len()); @@ -735,7 +735,7 @@ impl Arc<[T]> { } } -// Specialization trait used for From<&[T]> +/// Specialization trait used for `From<&[T]>`. trait ArcFromSlice { fn from_slice(slice: &[T]) -> Self; } @@ -1903,7 +1903,7 @@ impl> ArcFromIter for Arc<[T]> { impl<'a, T: 'a + Clone> ArcFromIter<&'a T, slice::Iter<'a, T>> for Arc<[T]> { fn from_iter(iter: slice::Iter<'a, T>) -> Self { - // Delegate to `impl From<&[T]> for Rc<[T]>`. + // Delegate to `impl From<&[T]> for Arc<[T]>`. // // In the case that `T: Copy`, we get to use `ptr::copy_nonoverlapping` // which is even more performant. diff --git a/src/liballoc/tests/arc.rs b/src/liballoc/tests/arc.rs index ce64e2de013..cf2ad2a8e60 100644 --- a/src/liballoc/tests/arc.rs +++ b/src/liballoc/tests/arc.rs @@ -88,6 +88,8 @@ fn eq() { assert_eq!(*x.0.borrow(), 0); } +// The test code below is identical to that in `rc.rs`. +// For better maintainability we therefore define this type alias. type Rc = Arc; const SHARED_ITER_MAX: u16 = 100; -- cgit 1.4.1-3-g733a5 From a99a7b7f35e3b30862058cc28ed4b0cf51638cf4 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 22 Jun 2019 06:59:27 +0200 Subject: Remove FnBox. --- .../src/language-features/unsized-locals.md | 4 +- .../unstable-book/src/library-features/fnbox.md | 32 --------- src/liballoc/boxed.rs | 79 ---------------------- src/libstd/lib.rs | 1 - src/test/run-pass/unsized-locals/fnbox-compat.rs | 13 ---- 5 files changed, 1 insertion(+), 128 deletions(-) delete mode 100644 src/doc/unstable-book/src/library-features/fnbox.md delete mode 100644 src/test/run-pass/unsized-locals/fnbox-compat.rs (limited to 'src/liballoc') diff --git a/src/doc/unstable-book/src/language-features/unsized-locals.md b/src/doc/unstable-book/src/language-features/unsized-locals.md index edc039f896b..343084b7db5 100644 --- a/src/doc/unstable-book/src/language-features/unsized-locals.md +++ b/src/doc/unstable-book/src/language-features/unsized-locals.md @@ -117,9 +117,7 @@ fn main () { } ``` -One of the objectives of this feature is to allow `Box`, instead of `Box` in the future. See [#28796] for details. - -[#28796]: https://github.com/rust-lang/rust/issues/28796 +One of the objectives of this feature is to allow `Box`. ## Variable length arrays diff --git a/src/doc/unstable-book/src/library-features/fnbox.md b/src/doc/unstable-book/src/library-features/fnbox.md deleted file mode 100644 index 97e32cc0acb..00000000000 --- a/src/doc/unstable-book/src/library-features/fnbox.md +++ /dev/null @@ -1,32 +0,0 @@ -# `fnbox` - -The tracking issue for this feature is [#28796] - -[#28796]: https://github.com/rust-lang/rust/issues/28796 - ------------------------- - -This had been a temporary alternative to the following impls: - -```rust,ignore -impl FnOnce for Box where F: FnOnce + ?Sized {} -impl FnMut for Box where F: FnMut + ?Sized {} -impl Fn for Box where F: Fn + ?Sized {} -``` - -The impls are parallel to these (relatively old) impls: - -```rust,ignore -impl FnOnce for &mut F where F: FnMut + ?Sized {} -impl FnMut for &mut F where F: FnMut + ?Sized {} -impl Fn for &mut F where F: Fn + ?Sized {} -impl FnOnce for &F where F: Fn + ?Sized {} -impl FnMut for &F where F: Fn + ?Sized {} -impl Fn for &F where F: Fn + ?Sized {} -``` - -Before the introduction of [`unsized_locals`][unsized_locals], we had been unable to provide the former impls. That means, unlike `&dyn Fn()` or `&mut dyn FnMut()` we could not use `Box` at that time. - -[unsized_locals]: ../language-features/unsized-locals.md - -`FnBox()` is an alternative approach to `Box` is delegated to `FnBox::call_box` which doesn't need unsized locals. As we now have `Box` working, the `fnbox` feature is going to be removed. diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 76b660fba68..9109a730cce 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -761,85 +761,6 @@ impl + ?Sized> Fn for Box { } } -/// `FnBox` is deprecated and will be removed. -/// `Box` can be called directly, since Rust 1.35.0. -/// -/// `FnBox` is a version of the `FnOnce` intended for use with boxed -/// closure objects. The idea was that where one would normally store a -/// `Box` in a data structure, you whould use -/// `Box`. The two traits behave essentially the same, except -/// that a `FnBox` closure can only be called if it is boxed. -/// -/// # Examples -/// -/// Here is a snippet of code which creates a hashmap full of boxed -/// once closures and then removes them one by one, calling each -/// closure as it is removed. Note that the type of the closures -/// stored in the map is `Box i32>` and not `Box i32>`. -/// -/// ``` -/// #![feature(fnbox)] -/// #![allow(deprecated)] -/// -/// use std::boxed::FnBox; -/// use std::collections::HashMap; -/// -/// fn make_map() -> HashMap i32>> { -/// let mut map: HashMap i32>> = HashMap::new(); -/// map.insert(1, Box::new(|| 22)); -/// map.insert(2, Box::new(|| 44)); -/// map -/// } -/// -/// fn main() { -/// let mut map = make_map(); -/// for i in &[1, 2] { -/// let f = map.remove(&i).unwrap(); -/// assert_eq!(f(), i * 22); -/// } -/// } -/// ``` -/// -/// In Rust 1.35.0 or later, use `FnOnce`, `FnMut`, or `Fn` instead: -/// -/// ``` -/// use std::collections::HashMap; -/// -/// fn make_map() -> HashMap i32>> { -/// let mut map: HashMap i32>> = HashMap::new(); -/// map.insert(1, Box::new(|| 22)); -/// map.insert(2, Box::new(|| 44)); -/// map -/// } -/// -/// fn main() { -/// let mut map = make_map(); -/// for i in &[1, 2] { -/// let f = map.remove(&i).unwrap(); -/// assert_eq!(f(), i * 22); -/// } -/// } -/// ``` -#[rustc_paren_sugar] -#[unstable(feature = "fnbox", issue = "28796")] -#[rustc_deprecated(reason = "use `FnOnce`, `FnMut`, or `Fn` instead", since = "1.37.0")] -pub trait FnBox: FnOnce { - /// Performs the call operation. - fn call_box(self: Box, args: A) -> Self::Output; -} - -#[unstable(feature = "fnbox", issue = "28796")] -#[rustc_deprecated(reason = "use `FnOnce`, `FnMut`, or `Fn` instead", since = "1.37.0")] -#[allow(deprecated, deprecated_in_future)] -impl FnBox for F - where F: FnOnce -{ - fn call_box(self: Box, args: A) -> F::Output { - self.call_once(args) - } -} - #[unstable(feature = "coerce_unsized", issue = "27732")] impl, U: ?Sized> CoerceUnsized> for Box {} diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index e0ffc9ba92f..60e06139eba 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -262,7 +262,6 @@ #![feature(exhaustive_patterns)] #![feature(external_doc)] #![feature(fn_traits)] -#![feature(fnbox)] #![feature(generator_trait)] #![feature(hash_raw_entry)] #![feature(hashmap_internals)] diff --git a/src/test/run-pass/unsized-locals/fnbox-compat.rs b/src/test/run-pass/unsized-locals/fnbox-compat.rs deleted file mode 100644 index 74a4dd5d851..00000000000 --- a/src/test/run-pass/unsized-locals/fnbox-compat.rs +++ /dev/null @@ -1,13 +0,0 @@ -#![feature(fnbox)] -#![allow(deprecated, deprecated_in_future)] - -use std::boxed::FnBox; - -fn call_it(f: Box T>) -> T { - f() -} - -fn main() { - let s = "hello".to_owned(); - assert_eq!(&call_it(Box::new(|| s)) as &str, "hello"); -} -- cgit 1.4.1-3-g733a5 From abe3bdf257f50b583cd7dea91e33424f700fb0c2 Mon Sep 17 00:00:00 2001 From: Matthias Geier Date: Tue, 25 Jun 2019 15:44:21 +0200 Subject: Remove RawVec::cap() As suggested in https://github.com/rust-lang/rust/pull/60340#issuecomment-493681032 --- src/liballoc/raw_vec.rs | 6 ------ 1 file changed, 6 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs index e5a8a522fbc..7c92ee51337 100644 --- a/src/liballoc/raw_vec.rs +++ b/src/liballoc/raw_vec.rs @@ -209,12 +209,6 @@ impl RawVec { } } - // For backwards compatibility - #[inline(always)] - pub fn cap(&self) -> usize { - self.capacity() - } - /// Returns a shared reference to the allocator backing this RawVec. pub fn alloc(&self) -> &A { &self.a -- cgit 1.4.1-3-g733a5 From 95275658f26e0e83fb26f946e716fa5de28fe43a Mon Sep 17 00:00:00 2001 From: Taylor Cramer Date: Thu, 27 Jun 2019 16:11:46 -0700 Subject: Add Vec::leak --- src/liballoc/vec.rs | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'src/liballoc') diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 92fe0834dd0..c0544d7469c 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -1367,6 +1367,40 @@ impl Vec { self.truncate(new_len); } } + + /// Consumes and leaks the `Vec`, returning a mutable reference to the contents, + /// `&'a mut [T]`. Note that the type `T` must outlive the chosen lifetime + /// `'a`. If the type has only static references, or none at all, then this + /// may be chosen to be `'static`. + /// + /// This function is similar to the `leak` function on `Box`. + /// + /// This function is mainly useful for data that lives for the remainder of + /// the program's life. Dropping the returned reference will cause a memory + /// leak. + /// + /// # Examples + /// + /// Simple usage: + /// + /// ``` + /// #![feature(vec_leak)] + /// + /// fn main() { + /// let x = vec![1, 2, 3]; + /// let static_ref: &'static mut [usize] = Vec::leak(x); + /// static_ref[0] += 1; + /// assert_eq!(static_ref, &[2, 2, 3]); + /// } + /// ``` + #[unstable(feature = "vec_leak", issue = "62195")] + #[inline] + pub fn leak<'a>(vec: Vec) -> &'a mut [T] + where + T: 'a // Technically not needed, but kept to be explicit. + { + Box::leak(vec.into_boxed_slice()) + } } impl Vec { -- cgit 1.4.1-3-g733a5 From fc70c37d167237023df1e75d154d1e6bebd44aee Mon Sep 17 00:00:00 2001 From: Chris Gregory Date: Sun, 30 Jun 2019 11:56:21 -0700 Subject: Improve box clone doctests to ensure the documentation is valid --- src/liballoc/boxed.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'src/liballoc') diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 9109a730cce..19b0f82db43 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -367,12 +367,19 @@ impl Clone for Box { /// ``` /// let x = Box::new(5); /// let y = x.clone(); + /// + /// // The value is the same + /// assert_eq!(x, y); + /// + /// // But they are unique objects + /// assert_ne!(&*x as *const i32, &*y as *const i32); /// ``` #[rustfmt::skip] #[inline] fn clone(&self) -> Box { box { (**self).clone() } } + /// Copies `source`'s contents into `self` without creating a new allocation. /// /// # Examples @@ -380,10 +387,15 @@ impl Clone for Box { /// ``` /// let x = Box::new(5); /// let mut y = Box::new(10); + /// let yp: *const i32 = &*y; /// /// y.clone_from(&x); /// - /// assert_eq!(*y, 5); + /// // The value is the same + /// assert_eq!(x, y); + /// + /// // And no allocation occurred + /// assert_eq!(yp, &*y); /// ``` #[inline] fn clone_from(&mut self, source: &Box) { -- cgit 1.4.1-3-g733a5 From 47ea8ae0223434e917ce840a963b495019bbe4d1 Mon Sep 17 00:00:00 2001 From: Jeremy Stucki Date: Tue, 25 Jun 2019 19:43:18 +0200 Subject: Remove needless lifetimes --- src/liballoc/collections/btree/map.rs | 8 ++++---- src/liballoc/collections/btree/node.rs | 2 +- src/liballoc/string.rs | 2 +- src/libcore/marker.rs | 2 +- src/libcore/ops/index.rs | 4 ++-- src/librustdoc/clean/mod.rs | 10 +++++----- src/librustdoc/html/render.rs | 2 +- src/librustdoc/html/toc.rs | 2 +- src/librustdoc/markdown.rs | 2 +- src/libserialize/json.rs | 4 ++-- src/libstd/sync/mpsc/sync.rs | 2 +- src/libstd/sys/redox/ext/net.rs | 2 +- src/libstd/sys/unix/ext/net.rs | 4 ++-- src/libstd/sys/windows/mod.rs | 2 +- src/libstd/sys/windows/path.rs | 2 +- src/libstd/sys_common/io.rs | 2 +- 16 files changed, 26 insertions(+), 26 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs index 6b079fc87cc..c610de3febf 100644 --- a/src/liballoc/collections/btree/map.rs +++ b/src/liballoc/collections/btree/map.rs @@ -2004,7 +2004,7 @@ impl BTreeMap { /// assert_eq!(keys, [1, 2]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn keys<'a>(&'a self) -> Keys<'a, K, V> { + pub fn keys(&self) -> Keys<'_, K, V> { Keys { inner: self.iter() } } @@ -2025,7 +2025,7 @@ impl BTreeMap { /// assert_eq!(values, ["hello", "goodbye"]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn values<'a>(&'a self) -> Values<'a, K, V> { + pub fn values(&self) -> Values<'_, K, V> { Values { inner: self.iter() } } @@ -2529,8 +2529,8 @@ enum UnderflowResult<'a, K, V> { Stole(NodeRef, K, V, marker::Internal>), } -fn handle_underfull_node<'a, K, V>(node: NodeRef, K, V, marker::LeafOrInternal>) - -> UnderflowResult<'a, K, V> { +fn handle_underfull_node(node: NodeRef, K, V, marker::LeafOrInternal>) + -> UnderflowResult<'_, K, V> { let parent = if let Ok(parent) = node.ascend() { parent } else { diff --git a/src/liballoc/collections/btree/node.rs b/src/liballoc/collections/btree/node.rs index 581c66c7086..7cf077d61d6 100644 --- a/src/liballoc/collections/btree/node.rs +++ b/src/liballoc/collections/btree/node.rs @@ -394,7 +394,7 @@ impl NodeRef { } /// Temporarily takes out another, immutable reference to the same node. - fn reborrow<'a>(&'a self) -> NodeRef, K, V, Type> { + fn reborrow(&self) -> NodeRef, K, V, Type> { NodeRef { height: self.height, node: self.node, diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index 7f7722548f5..89d24a234e9 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -552,7 +552,7 @@ impl String { /// assert_eq!("Hello �World", output); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn from_utf8_lossy<'a>(v: &'a [u8]) -> Cow<'a, str> { + pub fn from_utf8_lossy(v: &[u8]) -> Cow<'_, str> { let mut iter = lossy::Utf8Lossy::from_bytes(v).chunks(); let (first_valid, first_broken) = if let Some(chunk) = iter.next() { diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index d9757d78dce..39c390b4df6 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -498,7 +498,7 @@ macro_rules! impls{ /// # end: *const T, /// # phantom: PhantomData<&'a T>, /// # } -/// fn borrow_vec<'a, T>(vec: &'a Vec) -> Slice<'a, T> { +/// fn borrow_vec(vec: &Vec) -> Slice<'_, T> { /// let ptr = vec.as_ptr(); /// Slice { /// start: ptr, diff --git a/src/libcore/ops/index.rs b/src/libcore/ops/index.rs index 3158f58e958..9cff474a760 100644 --- a/src/libcore/ops/index.rs +++ b/src/libcore/ops/index.rs @@ -105,7 +105,7 @@ pub trait Index { /// impl Index for Balance { /// type Output = Weight; /// -/// fn index<'a>(&'a self, index: Side) -> &'a Self::Output { +/// fn index(&self, index: Side) -> &Self::Output { /// println!("Accessing {:?}-side of balance immutably", index); /// match index { /// Side::Left => &self.left, @@ -115,7 +115,7 @@ pub trait Index { /// } /// /// impl IndexMut for Balance { -/// fn index_mut<'a>(&'a mut self, index: Side) -> &'a mut Self::Output { +/// fn index_mut(&mut self, index: Side) -> &mut Self::Output { /// println!("Accessing {:?}-side of balance mutably", index); /// match index { /// Side::Left => &mut self.left, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 41a56756a14..6ba7daa35de 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -392,7 +392,7 @@ impl fmt::Debug for Item { impl Item { /// Finds the `doc` attribute as a NameValue and returns the corresponding /// value found. - pub fn doc_value<'a>(&'a self) -> Option<&'a str> { + pub fn doc_value(&self) -> Option<&str> { self.attrs.doc_value() } /// Finds all `doc` attributes as NameValues and returns their corresponding values, joined @@ -699,11 +699,11 @@ impl<'a> Iterator for ListAttributesIter<'a> { pub trait AttributesExt { /// Finds an attribute as List and returns the list of attributes nested inside. - fn lists<'a>(&'a self, name: Symbol) -> ListAttributesIter<'a>; + fn lists(&self, name: Symbol) -> ListAttributesIter<'_>; } impl AttributesExt for [ast::Attribute] { - fn lists<'a>(&'a self, name: Symbol) -> ListAttributesIter<'a> { + fn lists(&self, name: Symbol) -> ListAttributesIter<'_> { ListAttributesIter { attrs: self.iter(), current_list: Vec::new().into_iter(), @@ -952,7 +952,7 @@ impl Attributes { /// Finds the `doc` attribute as a NameValue and returns the corresponding /// value found. - pub fn doc_value<'a>(&'a self) -> Option<&'a str> { + pub fn doc_value(&self) -> Option<&str> { self.doc_strings.first().map(|s| s.as_str()) } @@ -1037,7 +1037,7 @@ impl Hash for Attributes { } impl AttributesExt for Attributes { - fn lists<'a>(&'a self, name: Symbol) -> ListAttributesIter<'a> { + fn lists(&self, name: Symbol) -> ListAttributesIter<'_> { self.other_attrs.lists(name) } } diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index f0aff961c67..e2c23ff89c6 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -2541,7 +2541,7 @@ fn full_path(cx: &Context, item: &clean::Item) -> String { s } -fn shorter<'a>(s: Option<&'a str>) -> String { +fn shorter(s: Option<&str>) -> String { match s { Some(s) => s.lines() .skip_while(|s| s.chars().all(|c| c.is_whitespace())) diff --git a/src/librustdoc/html/toc.rs b/src/librustdoc/html/toc.rs index 2564c611e54..2da7aceae8b 100644 --- a/src/librustdoc/html/toc.rs +++ b/src/librustdoc/html/toc.rs @@ -119,7 +119,7 @@ impl TocBuilder { /// Push a level `level` heading into the appropriate place in the /// hierarchy, returning a string containing the section number in /// `..` format. - pub fn push<'a>(&'a mut self, level: u32, name: String, id: String) -> &'a str { + pub fn push(&mut self, level: u32, name: String, id: String) -> &str { assert!(level >= 1); // collapse all previous sections into their parents until we diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs index b0a37ea9c80..50a647f244d 100644 --- a/src/librustdoc/markdown.rs +++ b/src/librustdoc/markdown.rs @@ -17,7 +17,7 @@ use crate::html::markdown::{ErrorCodes, IdMap, Markdown, MarkdownWithToc, find_t use crate::test::{TestOptions, Collector}; /// Separate any lines at the start of the file that begin with `# ` or `%`. -fn extract_leading_metadata<'a>(s: &'a str) -> (Vec<&'a str>, &'a str) { +fn extract_leading_metadata(s: &str) -> (Vec<&str>, &str) { let mut metadata = Vec::new(); let mut count = 0; diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index a7e7c09f9ae..726306d60ce 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -1031,7 +1031,7 @@ impl Json { /// If the Json value is an Object, returns the value associated with the provided key. /// Otherwise, returns None. - pub fn find<'a>(&'a self, key: &str) -> Option<&'a Json>{ + pub fn find(&self, key: &str) -> Option<&Json> { match *self { Json::Object(ref map) => map.get(key), _ => None @@ -1052,7 +1052,7 @@ impl Json { /// If the Json value is an Object, performs a depth-first search until /// a value associated with the provided key is found. If no value is found /// or the Json value is not an Object, returns `None`. - pub fn search<'a>(&'a self, key: &str) -> Option<&'a Json> { + pub fn search(&self, key: &str) -> Option<&Json> { match self { &Json::Object(ref map) => { match map.get(key) { diff --git a/src/libstd/sync/mpsc/sync.rs b/src/libstd/sync/mpsc/sync.rs index 3c4f8e077c9..a9c4c7345c2 100644 --- a/src/libstd/sync/mpsc/sync.rs +++ b/src/libstd/sync/mpsc/sync.rs @@ -140,7 +140,7 @@ fn wait_timeout_receiver<'a, 'b, T>(lock: &'a Mutex>, new_guard } -fn abort_selection<'a, T>(guard: &mut MutexGuard<'a , State>) -> bool { +fn abort_selection(guard: &mut MutexGuard<'_, State>) -> bool { match mem::replace(&mut guard.blocker, NoneBlocked) { NoneBlocked => true, BlockedSender(token) => { diff --git a/src/libstd/sys/redox/ext/net.rs b/src/libstd/sys/redox/ext/net.rs index b3ef5f3064c..e25bab4ff61 100644 --- a/src/libstd/sys/redox/ext/net.rs +++ b/src/libstd/sys/redox/ext/net.rs @@ -673,7 +673,7 @@ impl UnixListener { /// } /// ``` #[stable(feature = "unix_socket_redox", since = "1.29.0")] - pub fn incoming<'a>(&'a self) -> Incoming<'a> { + pub fn incoming(&self) -> Incoming { Incoming { listener: self } } } diff --git a/src/libstd/sys/unix/ext/net.rs b/src/libstd/sys/unix/ext/net.rs index 41090caee84..42edd5dbbea 100644 --- a/src/libstd/sys/unix/ext/net.rs +++ b/src/libstd/sys/unix/ext/net.rs @@ -198,7 +198,7 @@ impl SocketAddr { } } - fn address<'a>(&'a self) -> AddressKind<'a> { + fn address(&self) -> AddressKind<'_> { let len = self.len as usize - sun_path_offset(&self.addr); let path = unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.addr.sun_path) }; @@ -894,7 +894,7 @@ impl UnixListener { /// } /// ``` #[stable(feature = "unix_socket", since = "1.10.0")] - pub fn incoming<'a>(&'a self) -> Incoming<'a> { + pub fn incoming(&self) -> Incoming<'_> { Incoming { listener: self } } } diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs index 1cb55539129..36fb1fb5ff6 100644 --- a/src/libstd/sys/windows/mod.rs +++ b/src/libstd/sys/windows/mod.rs @@ -195,7 +195,7 @@ fn wide_char_to_multi_byte(code_page: u32, } } -pub fn truncate_utf16_at_nul<'a>(v: &'a [u16]) -> &'a [u16] { +pub fn truncate_utf16_at_nul(v: &[u16]) -> &[u16] { match v.iter().position(|c| *c == 0) { // don't include the 0 Some(i) => &v[..i], diff --git a/src/libstd/sys/windows/path.rs b/src/libstd/sys/windows/path.rs index f3178a5e9e6..7eae28cb14f 100644 --- a/src/libstd/sys/windows/path.rs +++ b/src/libstd/sys/windows/path.rs @@ -19,7 +19,7 @@ pub fn is_verbatim_sep(b: u8) -> bool { b == b'\\' } -pub fn parse_prefix<'a>(path: &'a OsStr) -> Option> { +pub fn parse_prefix(path: &OsStr) -> Option> { use crate::path::Prefix::*; unsafe { // The unsafety here stems from converting between &OsStr and &[u8] diff --git a/src/libstd/sys_common/io.rs b/src/libstd/sys_common/io.rs index 44b0963302d..8789abe55c3 100644 --- a/src/libstd/sys_common/io.rs +++ b/src/libstd/sys_common/io.rs @@ -16,7 +16,7 @@ pub mod test { p.join(path) } - pub fn path<'a>(&'a self) -> &'a Path { + pub fn path(&self) -> &Path { let TempDir(ref p) = *self; p } -- cgit 1.4.1-3-g733a5 From 636f5e6d1120c2bfc264687fbe1e77312c8d2979 Mon Sep 17 00:00:00 2001 From: Chris Gregory Date: Sun, 30 Jun 2019 11:30:01 -0700 Subject: Convert more usages over --- src/liballoc/collections/btree/map.rs | 4 ++-- src/liballoc/collections/linked_list.rs | 2 +- src/liballoc/str.rs | 2 +- src/librustc/hir/lowering.rs | 4 ++-- src/librustc/infer/nll_relate/mod.rs | 2 +- src/librustc/infer/outlives/obligations.rs | 2 +- src/librustc/infer/region_constraints/mod.rs | 2 +- src/librustc/middle/region.rs | 2 +- src/librustc/middle/resolve_lifetime.rs | 9 ++++----- src/librustc_codegen_llvm/back/archive.rs | 4 ++-- src/librustc_codegen_ssa/back/command.rs | 2 +- src/librustc_codegen_ssa/back/write.rs | 9 +++------ src/librustc_mir/borrow_check/mod.rs | 2 +- src/librustc_mir/build/matches/simplify.rs | 2 +- src/librustc_mir/util/def_use.rs | 2 +- src/librustc_resolve/macros.rs | 6 +++--- src/librustc_resolve/resolve_imports.rs | 2 +- src/librustc_typeck/check/method/probe.rs | 4 ++-- src/librustdoc/clean/mod.rs | 2 +- src/librustdoc/clean/simplify.rs | 2 +- src/librustdoc/html/render.rs | 2 +- src/librustdoc/passes/collapse_docs.rs | 2 +- src/libstd/panicking.rs | 2 +- src/libstd/sync/mpsc/sync.rs | 2 +- src/libstd/sys/windows/pipe.rs | 2 +- src/libsyntax/ext/expand.rs | 2 +- src/libsyntax/ext/tt/transcribe.rs | 2 +- src/libsyntax/parse/parser.rs | 4 ++-- src/libsyntax/test.rs | 4 ++-- src/tools/compiletest/src/runtest.rs | 4 ++-- 30 files changed, 44 insertions(+), 48 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs index 6b079fc87cc..d9ebc40aa2c 100644 --- a/src/liballoc/collections/btree/map.rs +++ b/src/liballoc/collections/btree/map.rs @@ -770,8 +770,8 @@ impl BTreeMap { } // First, we merge `self` and `other` into a sorted sequence in linear time. - let self_iter = mem::replace(self, BTreeMap::new()).into_iter(); - let other_iter = mem::replace(other, BTreeMap::new()).into_iter(); + let self_iter = mem::take(self).into_iter(); + let other_iter = mem::take(other).into_iter(); let iter = MergeIter { left: self_iter.peekable(), right: other_iter.peekable(), diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs index 40a82d6feaa..ca9e78bb459 100644 --- a/src/liballoc/collections/linked_list.rs +++ b/src/liballoc/collections/linked_list.rs @@ -708,7 +708,7 @@ impl LinkedList { let len = self.len(); assert!(at <= len, "Cannot split off at a nonexistent index"); if at == 0 { - return mem::replace(self, Self::new()); + return mem::take(self); } else if at == len { return Self::new(); } diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs index 40104554fe5..70a93157c9e 100644 --- a/src/liballoc/str.rs +++ b/src/liballoc/str.rs @@ -203,7 +203,7 @@ impl ToOwned for str { } fn clone_into(&self, target: &mut String) { - let mut b = mem::replace(target, String::new()).into_bytes(); + let mut b = mem::take(target).into_bytes(); self.as_bytes().clone_into(&mut b); *target = unsafe { String::from_utf8_unchecked(b) } } diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 9c4a208f0f9..2e7a934a769 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1278,8 +1278,8 @@ impl<'a> LoweringContext<'a> { let was_in_loop_condition = self.is_in_loop_condition; self.is_in_loop_condition = false; - let catch_scopes = mem::replace(&mut self.catch_scopes, Vec::new()); - let loop_scopes = mem::replace(&mut self.loop_scopes, Vec::new()); + let catch_scopes = mem::take(&mut self.catch_scopes); + let loop_scopes = mem::take(&mut self.loop_scopes); let ret = f(self); self.catch_scopes = catch_scopes; self.loop_scopes = loop_scopes; diff --git a/src/librustc/infer/nll_relate/mod.rs b/src/librustc/infer/nll_relate/mod.rs index a1a93eb5521..a0621af0537 100644 --- a/src/librustc/infer/nll_relate/mod.rs +++ b/src/librustc/infer/nll_relate/mod.rs @@ -364,7 +364,7 @@ where // been fully instantiated and hence the set of scopes we have // doesn't matter -- just to be sure, put an empty vector // in there. - let old_a_scopes = ::std::mem::replace(pair.vid_scopes(self), vec![]); + let old_a_scopes = ::std::mem::take(pair.vid_scopes(self)); // Relate the generalized kind to the original one. let result = pair.relate_generalized_ty(self, generalized_ty); diff --git a/src/librustc/infer/outlives/obligations.rs b/src/librustc/infer/outlives/obligations.rs index 0ae4446ee63..e1470e4ef02 100644 --- a/src/librustc/infer/outlives/obligations.rs +++ b/src/librustc/infer/outlives/obligations.rs @@ -112,7 +112,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { /// Trait queries just want to pass back type obligations "as is" pub fn take_registered_region_obligations(&self) -> Vec<(hir::HirId, RegionObligation<'tcx>)> { - ::std::mem::replace(&mut *self.region_obligations.borrow_mut(), vec![]) + ::std::mem::take(&mut *self.region_obligations.borrow_mut()) } /// Process the region obligations that must be proven (during diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs index f2235fe8d6d..b27c39c4f71 100644 --- a/src/librustc/infer/region_constraints/mod.rs +++ b/src/librustc/infer/region_constraints/mod.rs @@ -410,7 +410,7 @@ impl<'tcx> RegionConstraintCollector<'tcx> { *any_unifications = false; } - mem::replace(data, RegionConstraintData::default()) + mem::take(data) } pub fn data(&self) -> &RegionConstraintData<'tcx> { diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 114684b1524..1a188bad11b 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -1375,7 +1375,7 @@ impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> { let outer_ec = mem::replace(&mut self.expr_and_pat_count, 0); let outer_cx = self.cx; - let outer_ts = mem::replace(&mut self.terminating_scopes, FxHashSet::default()); + let outer_ts = mem::take(&mut self.terminating_scopes); self.terminating_scopes.insert(body.value.hir_id.local_id); if let Some(root_id) = self.cx.root_id { diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 412346bab25..dada3a87be5 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -18,7 +18,7 @@ use errors::{Applicability, DiagnosticBuilder}; use rustc_macros::HashStable; use std::borrow::Cow; use std::cell::Cell; -use std::mem::replace; +use std::mem::{replace, take}; use syntax::ast; use syntax::attr; use syntax::ptr::P; @@ -441,7 +441,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { fn visit_nested_body(&mut self, body: hir::BodyId) { // Each body has their own set of labels, save labels. - let saved = replace(&mut self.labels_in_fn, vec![]); + let saved = take(&mut self.labels_in_fn); let body = self.tcx.hir().body(body); extract_labels(self, body); self.with( @@ -1405,9 +1405,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { lifetime_uses, .. } = self; - let labels_in_fn = replace(&mut self.labels_in_fn, vec![]); - let xcrate_object_lifetime_defaults = - replace(&mut self.xcrate_object_lifetime_defaults, DefIdMap::default()); + let labels_in_fn = take(&mut self.labels_in_fn); + let xcrate_object_lifetime_defaults = take(&mut self.xcrate_object_lifetime_defaults); let mut this = LifetimeContext { tcx: *tcx, map: map, diff --git a/src/librustc_codegen_llvm/back/archive.rs b/src/librustc_codegen_llvm/back/archive.rs index e0e26e9af25..ca3b2b84655 100644 --- a/src/librustc_codegen_llvm/back/archive.rs +++ b/src/librustc_codegen_llvm/back/archive.rs @@ -205,8 +205,8 @@ impl<'a> LlvmArchiveBuilder<'a> { } fn build_with_llvm(&mut self, kind: ArchiveKind) -> io::Result<()> { - let removals = mem::replace(&mut self.removals, Vec::new()); - let mut additions = mem::replace(&mut self.additions, Vec::new()); + let removals = mem::take(&mut self.removals); + let mut additions = mem::take(&mut self.additions); let mut strings = Vec::new(); let mut members = Vec::new(); diff --git a/src/librustc_codegen_ssa/back/command.rs b/src/librustc_codegen_ssa/back/command.rs index 78570cce57d..d610805b5bb 100644 --- a/src/librustc_codegen_ssa/back/command.rs +++ b/src/librustc_codegen_ssa/back/command.rs @@ -110,7 +110,7 @@ impl Command { } pub fn take_args(&mut self) -> Vec { - mem::replace(&mut self.args, Vec::new()) + mem::take(&mut self.args) } /// Returns a `true` if we're pretty sure that this'll blow OS spawn limits, diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs index 309187ca2ea..5ca38273269 100644 --- a/src/librustc_codegen_ssa/back/write.rs +++ b/src/librustc_codegen_ssa/back/write.rs @@ -1345,12 +1345,9 @@ fn start_executing_work( assert!(!started_lto); started_lto = true; - let needs_fat_lto = - mem::replace(&mut needs_fat_lto, Vec::new()); - let needs_thin_lto = - mem::replace(&mut needs_thin_lto, Vec::new()); - let import_only_modules = - mem::replace(&mut lto_import_only_modules, Vec::new()); + let needs_fat_lto = mem::take(&mut needs_fat_lto); + let needs_thin_lto = mem::take(&mut needs_thin_lto); + let import_only_modules = mem::take(&mut lto_import_only_modules); for (work, cost) in generate_lto_work(&cgcx, needs_fat_lto, needs_thin_lto, import_only_modules) { diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 4872440f5bd..58009167e3c 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -275,7 +275,7 @@ fn do_mir_borrowck<'a, 'tcx>( mbcx.analyze_results(&mut state); // entry point for DataflowResultsConsumer // Convert any reservation warnings into lints. - let reservation_warnings = mem::replace(&mut mbcx.reservation_warnings, Default::default()); + let reservation_warnings = mem::take(&mut mbcx.reservation_warnings); for (_, (place, span, location, bk, borrow)) in reservation_warnings { let mut initial_diag = mbcx.report_conflicting_borrow(location, (&place, span), bk, &borrow); diff --git a/src/librustc_mir/build/matches/simplify.rs b/src/librustc_mir/build/matches/simplify.rs index b1b5233fbc8..7125eb6850b 100644 --- a/src/librustc_mir/build/matches/simplify.rs +++ b/src/librustc_mir/build/matches/simplify.rs @@ -28,7 +28,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { candidate: &mut Candidate<'pat, 'tcx>) { // repeatedly simplify match pairs until fixed point is reached loop { - let match_pairs = mem::replace(&mut candidate.match_pairs, vec![]); + let match_pairs = mem::take(&mut candidate.match_pairs); let mut changed = false; for match_pair in match_pairs { match self.simplify_match_pair(match_pair, candidate) { diff --git a/src/librustc_mir/util/def_use.rs b/src/librustc_mir/util/def_use.rs index fac752dbf02..59821440c66 100644 --- a/src/librustc_mir/util/def_use.rs +++ b/src/librustc_mir/util/def_use.rs @@ -31,7 +31,7 @@ impl DefUseAnalysis { self.clear(); let mut finder = DefUseFinder { - info: mem::replace(&mut self.info, IndexVec::new()), + info: mem::take(&mut self.info), }; finder.visit_body(body); self.info = finder.info diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 392a46a262f..c544b3f4603 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -946,7 +946,7 @@ impl<'a> Resolver<'a> { }; let macro_resolutions = - mem::replace(&mut *module.multi_segment_macro_resolutions.borrow_mut(), Vec::new()); + mem::take(&mut *module.multi_segment_macro_resolutions.borrow_mut()); for (mut path, path_span, kind, parent_scope, initial_res) in macro_resolutions { // FIXME: Path resolution will ICE if segment IDs present. for seg in &mut path { seg.id = None; } @@ -973,7 +973,7 @@ impl<'a> Resolver<'a> { } let macro_resolutions = - mem::replace(&mut *module.single_segment_macro_resolutions.borrow_mut(), Vec::new()); + mem::take(&mut *module.single_segment_macro_resolutions.borrow_mut()); for (ident, kind, parent_scope, initial_binding) in macro_resolutions { match self.early_resolve_ident_in_lexical_scope(ident, ScopeSet::Macro(kind), &parent_scope, true, true, ident.span) { @@ -998,7 +998,7 @@ impl<'a> Resolver<'a> { } } - let builtin_attrs = mem::replace(&mut *module.builtin_attrs.borrow_mut(), Vec::new()); + let builtin_attrs = mem::take(&mut *module.builtin_attrs.borrow_mut()); for (ident, parent_scope) in builtin_attrs { let _ = self.early_resolve_ident_in_lexical_scope( ident, ScopeSet::Macro(MacroKind::Attr), &parent_scope, true, true, ident.span diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index f69849bb4a9..404d728d880 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -682,7 +682,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { let mut prev_num_indeterminates = self.indeterminate_imports.len() + 1; while self.indeterminate_imports.len() < prev_num_indeterminates { prev_num_indeterminates = self.indeterminate_imports.len(); - for import in mem::replace(&mut self.indeterminate_imports, Vec::new()) { + for import in mem::take(&mut self.indeterminate_imports) { match self.resolve_import(&import) { true => self.determined_imports.push(import), false => self.indeterminate_imports.push(import), diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 661883f2ac1..bd4cf9d2086 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -970,9 +970,9 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { debug!("pick: actual search failed, assemble diagnotics"); - let static_candidates = mem::replace(&mut self.static_candidates, vec![]); + let static_candidates = mem::take(&mut self.static_candidates); let private_candidate = self.private_candidate.take(); - let unsatisfied_predicates = mem::replace(&mut self.unsatisfied_predicates, vec![]); + let unsatisfied_predicates = mem::take(&mut self.unsatisfied_predicates); // things failed, so lets look at all traits, for diagnostic purposes now: self.reset(); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 3fe048a6986..8fec433e56d 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -4408,7 +4408,7 @@ pub fn enter_impl_trait(cx: &DocContext<'_>, f: F) -> R where F: FnOnce() -> R, { - let old_bounds = mem::replace(&mut *cx.impl_trait_bounds.borrow_mut(), Default::default()); + let old_bounds = mem::take(&mut *cx.impl_trait_bounds.borrow_mut()); let r = f(); assert!(cx.impl_trait_bounds.borrow().is_empty()); *cx.impl_trait_bounds.borrow_mut() = old_bounds; diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs index 36e6a6003df..e4fba73b820 100644 --- a/src/librustdoc/clean/simplify.rs +++ b/src/librustdoc/clean/simplify.rs @@ -131,7 +131,7 @@ pub fn ty_params(mut params: Vec) -> Vec { - *bounds = ty_bounds(mem::replace(bounds, Vec::new())); + *bounds = ty_bounds(mem::take(bounds)); } _ => panic!("expected only type parameters"), } diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 2080637ecb4..2d6503c9445 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -660,7 +660,7 @@ pub fn run(mut krate: clean::Crate, deref_trait_did, deref_mut_trait_did, owned_box_did, - masked_crates: mem::replace(&mut krate.masked_crates, Default::default()), + masked_crates: mem::take(&mut krate.masked_crates), param_names: external_param_names, aliases: Default::default(), }; diff --git a/src/librustdoc/passes/collapse_docs.rs b/src/librustdoc/passes/collapse_docs.rs index 8666ba357b8..e15a95e2e1a 100644 --- a/src/librustdoc/passes/collapse_docs.rs +++ b/src/librustdoc/passes/collapse_docs.rs @@ -46,7 +46,7 @@ fn collapse(doc_strings: &mut Vec) { let mut docs = vec![]; let mut last_frag: Option = None; - for frag in replace(doc_strings, vec![]) { + for frag in take(doc_strings) { if let Some(mut curr_frag) = last_frag.take() { let curr_kind = curr_frag.kind(); let new_kind = frag.kind(); diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs index 797d85e941d..952fd9ebfdf 100644 --- a/src/libstd/panicking.rs +++ b/src/libstd/panicking.rs @@ -364,7 +364,7 @@ fn continue_panic_fmt(info: &PanicInfo<'_>) -> ! { unsafe impl<'a> BoxMeUp for PanicPayload<'a> { fn box_me_up(&mut self) -> *mut (dyn Any + Send) { - let contents = mem::replace(self.fill(), String::new()); + let contents = mem::take(self.fill()); Box::into_raw(Box::new(contents)) } diff --git a/src/libstd/sync/mpsc/sync.rs b/src/libstd/sync/mpsc/sync.rs index 3c4f8e077c9..f8fcd3ff5a5 100644 --- a/src/libstd/sync/mpsc/sync.rs +++ b/src/libstd/sync/mpsc/sync.rs @@ -383,7 +383,7 @@ impl Packet { // needs to be careful to destroy the data *outside* of the lock to // prevent deadlock. let _data = if guard.cap != 0 { - mem::replace(&mut guard.buf.buf, Vec::new()) + mem::take(&mut guard.buf.buf) } else { Vec::new() }; diff --git a/src/libstd/sys/windows/pipe.rs b/src/libstd/sys/windows/pipe.rs index 493ee8a9a2d..c77f30dfc71 100644 --- a/src/libstd/sys/windows/pipe.rs +++ b/src/libstd/sys/windows/pipe.rs @@ -342,7 +342,7 @@ impl<'a> Drop for AsyncPipe<'a> { // If anything here fails, there's not really much we can do, so we leak // the buffer/OVERLAPPED pointers to ensure we're at least memory safe. if self.pipe.cancel_io().is_err() || self.result().is_err() { - let buf = mem::replace(self.dst, Vec::new()); + let buf = mem::take(self.dst); let overlapped = Box::new(unsafe { mem::zeroed() }); let overlapped = mem::replace(&mut self.overlapped, overlapped); mem::forget((buf, overlapped)); diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 5473f55aa33..c0f721b466e 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -307,7 +307,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } else { self.resolve_imports(); if undetermined_invocations.is_empty() { break } - invocations = mem::replace(&mut undetermined_invocations, Vec::new()); + invocations = mem::take(&mut undetermined_invocations); force = !mem::replace(&mut progress, false); continue }; diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs index ea7f8e356aa..e04fd2ddc05 100644 --- a/src/libsyntax/ext/tt/transcribe.rs +++ b/src/libsyntax/ext/tt/transcribe.rs @@ -249,7 +249,7 @@ pub fn transcribe( quoted::TokenTree::Delimited(mut span, delimited) => { span = span.apply_mark(cx.current_expansion.mark); stack.push(Frame::Delimited { forest: delimited, idx: 0, span }); - result_stack.push(mem::replace(&mut result, Vec::new())); + result_stack.push(mem::take(&mut result)); } // Nothing much to do here. Just push the token to the result, being careful to diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 696b5f48385..8ac20f33908 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -7699,7 +7699,7 @@ impl<'a> Parser<'a> { let mut tokens = Vec::new(); let prev_collecting = match self.token_cursor.frame.last_token { LastToken::Collecting(ref mut list) => { - Some(mem::replace(list, Vec::new())) + Some(mem::take(list)) } LastToken::Was(ref mut last) => { tokens.extend(last.take()); @@ -7717,7 +7717,7 @@ impl<'a> Parser<'a> { // Pull out the tokens that we've collected from the call to `f` above. let mut collected_tokens = match *last_token { - LastToken::Collecting(ref mut v) => mem::replace(v, Vec::new()), + LastToken::Collecting(ref mut v) => mem::take(v), LastToken::Was(_) => panic!("our vector went away?"), }; diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index f90b76721ee..156fab8834c 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -120,8 +120,8 @@ impl<'a> MutVisitor for TestHarnessGenerator<'a> { // We don't want to recurse into anything other than mods, since // mods or tests inside of functions will break things if let ast::ItemKind::Mod(mut module) = item.node { - let tests = mem::replace(&mut self.tests, Vec::new()); - let tested_submods = mem::replace(&mut self.tested_submods, Vec::new()); + let tests = mem::take(&mut self.tests); + let tested_submods = mem::take(&mut self.tested_submods); noop_visit_mod(&mut module, self); let tests = mem::replace(&mut self.tests, tests); let tested_submods = mem::replace(&mut self.tested_submods, tested_submods); diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 35caf82dd71..6053b538ff3 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -3608,7 +3608,7 @@ fn nocomment_mir_line(line: &str) -> &str { fn read2_abbreviated(mut child: Child) -> io::Result { use crate::read2::read2; - use std::mem::replace; + use std::mem::take; const HEAD_LEN: usize = 160 * 1024; const TAIL_LEN: usize = 256 * 1024; @@ -3632,7 +3632,7 @@ fn read2_abbreviated(mut child: Child) -> io::Result { return; } let tail = bytes.split_off(new_len - TAIL_LEN).into_boxed_slice(); - let head = replace(bytes, Vec::new()); + let head = take(bytes); let skipped = new_len - HEAD_LEN - TAIL_LEN; ProcOutput::Abbreviated { head, -- cgit 1.4.1-3-g733a5 From b0c199a9697e79c70976cf4fe4fe9e0e6cc81a5c Mon Sep 17 00:00:00 2001 From: Chris Gregory Date: Sun, 30 Jun 2019 11:38:06 -0700 Subject: Enable mem_take feature in relevant crates --- src/liballoc/lib.rs | 1 + src/libcore/lib.rs | 1 + src/libproc_macro/lib.rs | 1 + src/librustc/lib.rs | 1 + src/librustc_codegen_llvm/lib.rs | 1 + src/librustc_codegen_ssa/lib.rs | 1 + src/librustc_mir/lib.rs | 1 + src/librustc_resolve/lib.rs | 1 + src/librustc_typeck/lib.rs | 1 + src/librustdoc/lib.rs | 1 + src/libstd/lib.rs | 1 + src/libsyntax/lib.rs | 1 + src/tools/compiletest/src/main.rs | 1 + 13 files changed, 13 insertions(+) (limited to 'src/liballoc') diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 5fc58c8ab5a..bfe7d12d9d0 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -112,6 +112,7 @@ #![feature(maybe_uninit_extra, maybe_uninit_slice, maybe_uninit_array)] #![feature(alloc_layout_extra)] #![feature(try_trait)] +#![feature(mem_take)] // Allow testing this library diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 04c50329de3..d2d08a075b9 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -126,6 +126,7 @@ #![feature(adx_target_feature)] #![feature(maybe_uninit_slice, maybe_uninit_array)] #![feature(external_doc)] +#![feature(mem_take)] #[prelude_import] #[allow(unused)] diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index 1e0f1ed578a..2c097238b95 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -25,6 +25,7 @@ #![feature(extern_types)] #![feature(in_band_lifetimes)] #![feature(optin_builtin_traits)] +#![feature(mem_take)] #![feature(non_exhaustive)] #![feature(specialization)] diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 257d5159f11..390ad09a404 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -65,6 +65,7 @@ #![feature(crate_visibility_modifier)] #![feature(proc_macro_hygiene)] #![feature(log_syntax)] +#![feature(mem_take)] #![recursion_limit="512"] diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index 7283aa95b30..f6d8b41f710 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -21,6 +21,7 @@ #![feature(link_args)] #![feature(static_nobundle)] #![feature(trusted_len)] +#![feature(mem_take)] #![deny(rust_2018_idioms)] #![deny(internal)] #![deny(unused_lifetimes)] diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs index b76f098773f..3c1ab600040 100644 --- a/src/librustc_codegen_ssa/lib.rs +++ b/src/librustc_codegen_ssa/lib.rs @@ -10,6 +10,7 @@ #![feature(in_band_lifetimes)] #![feature(nll)] #![feature(trusted_len)] +#![feature(mem_take)] #![allow(unused_attributes)] #![allow(dead_code)] #![deny(rust_2018_idioms)] diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index cb02e1a778c..b85149cf556 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -24,6 +24,7 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![feature(slice_concat_ext)] #![feature(trusted_len)] #![feature(try_blocks)] +#![feature(mem_take)] #![recursion_limit="256"] diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index f4c23a023b1..3bc4da78e18 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -4,6 +4,7 @@ #![feature(crate_visibility_modifier)] #![feature(label_break_value)] +#![feature(mem_take)] #![feature(nll)] #![feature(rustc_diagnostic_macros)] #![cfg_attr(bootstrap, feature(type_alias_enum_variants))] diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 85ae55b2dd9..2b9ee0a746d 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -69,6 +69,7 @@ This API is completely unstable and subject to change. #![feature(slice_patterns)] #![feature(never_type)] #![feature(inner_deref)] +#![feature(mem_take)] #![recursion_limit="256"] diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index ba423300e02..342264db43c 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -21,6 +21,7 @@ #![feature(drain_filter)] #![feature(inner_deref)] #![feature(never_type)] +#![feature(mem_take)] #![recursion_limit="256"] diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 60e06139eba..fb9a228880e 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -272,6 +272,7 @@ #![feature(libc)] #![feature(link_args)] #![feature(linkage)] +#![feature(mem_take)] #![feature(needs_panic_runtime)] #![feature(never_type)] #![feature(nll)] diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 337b8424736..72b5f8c9f3f 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -16,6 +16,7 @@ #![feature(const_transmute)] #![feature(crate_visibility_modifier)] #![feature(label_break_value)] +#![feature(mem_take)] #![feature(nll)] #![feature(rustc_attrs)] #![feature(rustc_diagnostic_macros)] diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index 597fdf2d95e..517f2a362f5 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -1,4 +1,5 @@ #![crate_name = "compiletest"] +#![feature(mem_take)] #![feature(test)] #![feature(vec_remove_item)] #![deny(warnings, rust_2018_idioms)] -- cgit 1.4.1-3-g733a5 From 45e7ba96cb9e5cc018f213f15a2c71f4e1350424 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 2 Jul 2019 12:56:51 +0200 Subject: test more possible overaligned requests --- src/liballoc/tests/heap.rs | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/tests/heap.rs b/src/liballoc/tests/heap.rs index c225ebfa96b..904b3e7e1b0 100644 --- a/src/liballoc/tests/heap.rs +++ b/src/liballoc/tests/heap.rs @@ -1,6 +1,6 @@ use std::alloc::{Global, Alloc, Layout, System}; -/// Issue #45955. +/// Issue #45955 and #62251. #[test] fn alloc_system_overaligned_request() { check_overalign_requests(System) @@ -12,21 +12,23 @@ fn std_heap_overaligned_request() { } fn check_overalign_requests(mut allocator: T) { - let size = 8; - let align = 16; // greater than size - let iterations = 100; - unsafe { - let pointers: Vec<_> = (0..iterations).map(|_| { - allocator.alloc(Layout::from_size_align(size, align).unwrap()).unwrap() - }).collect(); - for &ptr in &pointers { - assert_eq!((ptr.as_ptr() as usize) % align, 0, - "Got a pointer less aligned than requested") - } + for &align in &[4, 8, 16, 32] { // less than and bigger than `MIN_ALIGN` + for &size in &[align/2, align-1] { // size less than alignment + let iterations = 128; + unsafe { + let pointers: Vec<_> = (0..iterations).map(|_| { + allocator.alloc(Layout::from_size_align(size, align).unwrap()).unwrap() + }).collect(); + for &ptr in &pointers { + assert_eq!((ptr.as_ptr() as usize) % align, 0, + "Got a pointer less aligned than requested") + } - // Clean up - for &ptr in &pointers { - allocator.dealloc(ptr, Layout::from_size_align(size, align).unwrap()) + // Clean up + for &ptr in &pointers { + allocator.dealloc(ptr, Layout::from_size_align(size, align).unwrap()) + } + } } } } -- cgit 1.4.1-3-g733a5 From db16e1721264dc06ac926a642deb4c7633a4b54d Mon Sep 17 00:00:00 2001 From: Kyle Huey Date: Tue, 2 Jul 2019 13:45:29 -0700 Subject: When possible without changing semantics, implement Iterator::last in terms of DoubleEndedIterator::next_back for types in liballoc and libcore. Provided that the iterator has finite length and does not trigger user-provided code, this is safe. What follows is a full list of the DoubleEndedIterators in liballoc/libcore and whether this optimization is safe, and if not, why not. src/liballoc/boxed.rs Box: Pass through to avoid defeating optimization of the underlying DoubleIterator implementation. This has no correctness impact. src/liballoc/collections/binary_heap.rs Iter: Pass through to avoid defeating optimizations on slice::Iter IntoIter: Not safe, changes Drop order Drain: Not safe, changes Drop order src/liballoc/collections/btree/map.rs Iter: Safe to call next_back, invokes no user defined code. IterMut: ditto IntoIter: Not safe, changes Drop order Keys: Safe to call next_back, invokes no user defined code. Values: ditto ValuesMut: ditto Range: ditto RangeMut: ditto src/liballoc/collections/btree/set.rs Iter: Safe to call next_back, invokes no user defined code. IntoIter: Not safe, changes Drop order Range: Safe to call next_back, invokes no user defined code. src/liballoc/collections/linked_list.rs Iter: Safe to call next_back, invokes no user defined code. IterMut: ditto IntoIter: Not safe, changes Drop order src/liballoc/collections/vec_deque.rs Iter: Safe to call next_back, invokes no user defined code. IterMut: ditto IntoIter: Not safe, changes Drop order Drain: ditto src/liballoc/string.rs Drain: Safe because return type is a primitive (char) src/liballoc/vec.rs IntoIter: Not safe, changes Drop order Drain: ditto Splice: ditto src/libcore/ascii.rs EscapeDefault: Safe because return type is a primitive (u8) src/libcore/iter/adapters/chain.rs Chain: Not safe, invokes user defined code (Iterator impl) src/libcore/iter/adapters/flatten.rs FlatMap: Not safe, invokes user defined code (Iterator impl) Flatten: ditto FlattenCompat: ditto src/libcore/iter/adapters/mod.rs Rev: Not safe, invokes user defined code (Iterator impl) Copied: ditto Cloned: Not safe, invokes user defined code (Iterator impl and T::clone) Map: Not safe, invokes user defined code (Iterator impl + closure) Filter: ditto FilterMap: ditto Enumerate: Not safe, invokes user defined code (Iterator impl) Skip: ditto Fuse: ditto Inspect: ditto src/libcore/iter/adapters/zip.rs Zip: Not safe, invokes user defined code (Iterator impl) src/libcore/iter/range.rs ops::Range: Not safe, changes Drop order, but ALREADY HAS SPECIALIZATION ops::RangeInclusive: ditto src/libcore/iter/sources.rs Repeat: Not safe, calling last should iloop. Empty: No point, iterator is at most one item long. Once: ditto OnceWith: ditto src/libcore/option.rs Item: No point, iterator is at most one item long. Iter: ditto IterMut: ditto IntoIter: ditto src/libcore/result.rs Iter: No point, iterator is at most one item long IterMut: ditto IntoIter: ditto src/libcore/slice/mod.rs Split: Not safe, invokes user defined closure SplitMut: ditto RSplit: ditto RSplitMut: ditto Windows: Safe, already has specialization Chunks: ditto ChunksMut: ditto ChunksExact: ditto ChunksExactMut: ditto RChunks: ditto RChunksMut: ditto RChunksExact: ditto RChunksExactMut: ditto src/libcore/str/mod.rs Chars: Safe, already has specialization CharIndices: ditto Bytes: ditto Lines: Safe to call next_back, invokes no user defined code. LinesAny: Deprecated Everything that is generic over P: Pattern: Not safe because Pattern invokes user defined code. SplitWhitespace: Safe to call next_back, invokes no user defined code. SplitAsciiWhitespace: ditto --- src/liballoc/boxed.rs | 8 ++++++++ src/liballoc/collections/binary_heap.rs | 5 +++++ src/liballoc/collections/btree/map.rs | 28 ++++++++++++++++++++++++++++ src/liballoc/collections/btree/set.rs | 7 +++++++ src/liballoc/collections/linked_list.rs | 10 ++++++++++ src/liballoc/collections/vec_deque.rs | 10 ++++++++++ src/liballoc/string.rs | 5 +++++ src/libcore/ascii.rs | 1 + src/libcore/str/mod.rs | 15 +++++++++++++++ 9 files changed, 89 insertions(+) (limited to 'src/liballoc') diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 9109a730cce..570e657b101 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -716,6 +716,14 @@ impl Iterator for Box { (**self).nth(n) } } + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for Box { + fn last(self) -> Option where I: Sized { + (*self).last() + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl DoubleEndedIterator for Box { fn next_back(&mut self) -> Option { diff --git a/src/liballoc/collections/binary_heap.rs b/src/liballoc/collections/binary_heap.rs index c898f064fd0..9f531f5b83c 100644 --- a/src/liballoc/collections/binary_heap.rs +++ b/src/liballoc/collections/binary_heap.rs @@ -1035,6 +1035,11 @@ impl<'a, T> Iterator for Iter<'a, T> { fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } + + #[inline] + fn last(self) -> Option<&'a T> { + self.iter.last() + } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs index 6b079fc87cc..8e1c870cf6b 100644 --- a/src/liballoc/collections/btree/map.rs +++ b/src/liballoc/collections/btree/map.rs @@ -1193,6 +1193,10 @@ impl<'a, K: 'a, V: 'a> Iterator for Iter<'a, K, V> { fn size_hint(&self) -> (usize, Option) { (self.length, Some(self.length)) } + + fn last(mut self) -> Option<(&'a K, &'a V)> { + self.next_back() + } } #[stable(feature = "fused", since = "1.26.0")] @@ -1253,6 +1257,10 @@ impl<'a, K: 'a, V: 'a> Iterator for IterMut<'a, K, V> { fn size_hint(&self) -> (usize, Option) { (self.length, Some(self.length)) } + + fn last(mut self) -> Option<(&'a K, &'a mut V)> { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1421,6 +1429,10 @@ impl<'a, K, V> Iterator for Keys<'a, K, V> { fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } + + fn last(mut self) -> Option<&'a K> { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1458,6 +1470,10 @@ impl<'a, K, V> Iterator for Values<'a, K, V> { fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } + + fn last(mut self) -> Option<&'a V> { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1495,6 +1511,10 @@ impl<'a, K, V> Iterator for Range<'a, K, V> { unsafe { Some(self.next_unchecked()) } } } + + fn last(mut self) -> Option<(&'a K, &'a V)> { + self.next_back() + } } #[stable(feature = "map_values_mut", since = "1.10.0")] @@ -1508,6 +1528,10 @@ impl<'a, K, V> Iterator for ValuesMut<'a, K, V> { fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } + + fn last(mut self) -> Option<&'a mut V> { + self.next_back() + } } #[stable(feature = "map_values_mut", since = "1.10.0")] @@ -1626,6 +1650,10 @@ impl<'a, K, V> Iterator for RangeMut<'a, K, V> { unsafe { Some(self.next_unchecked()) } } } + + fn last(mut self) -> Option<(&'a K, &'a mut V)> { + self.next_back() + } } impl<'a, K, V> RangeMut<'a, K, V> { diff --git a/src/liballoc/collections/btree/set.rs b/src/liballoc/collections/btree/set.rs index 16a96ca19b8..d3af910a82c 100644 --- a/src/liballoc/collections/btree/set.rs +++ b/src/liballoc/collections/btree/set.rs @@ -1019,6 +1019,9 @@ impl<'a, T> Iterator for Iter<'a, T> { fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } + fn last(mut self) -> Option<&'a T> { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> DoubleEndedIterator for Iter<'a, T> { @@ -1073,6 +1076,10 @@ impl<'a, T> Iterator for Range<'a, T> { fn next(&mut self) -> Option<&'a T> { self.iter.next().map(|(k, _)| k) } + + fn last(mut self) -> Option<&'a T> { + self.next_back() + } } #[stable(feature = "btree_range", since = "1.17.0")] diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs index 40a82d6feaa..b5dbbe8fe2d 100644 --- a/src/liballoc/collections/linked_list.rs +++ b/src/liballoc/collections/linked_list.rs @@ -832,6 +832,11 @@ impl<'a, T> Iterator for Iter<'a, T> { fn size_hint(&self) -> (usize, Option) { (self.len, Some(self.len)) } + + #[inline] + fn last(mut self) -> Option<&'a T> { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -881,6 +886,11 @@ impl<'a, T> Iterator for IterMut<'a, T> { fn size_hint(&self) -> (usize, Option) { (self.len, Some(self.len)) } + + #[inline] + fn last(mut self) -> Option<&'a mut T> { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index 71faf672962..573dd86b23a 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -2206,6 +2206,11 @@ impl<'a, T> Iterator for Iter<'a, T> { self.tail = self.head - iter.len(); final_res } + + #[inline] + fn last(mut self) -> Option<&'a T> { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -2319,6 +2324,11 @@ impl<'a, T> Iterator for IterMut<'a, T> { accum = front.iter_mut().fold(accum, &mut f); back.iter_mut().fold(accum, &mut f) } + + #[inline] + fn last(mut self) -> Option<&'a mut T> { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index 7f7722548f5..1b0d3c19692 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -2385,6 +2385,11 @@ impl Iterator for Drain<'_> { fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } + + #[inline] + fn last(mut self) -> Option { + self.next_back() + } } #[stable(feature = "drain", since = "1.6.0")] diff --git a/src/libcore/ascii.rs b/src/libcore/ascii.rs index c0ab364380f..e6a6fdde540 100644 --- a/src/libcore/ascii.rs +++ b/src/libcore/ascii.rs @@ -117,6 +117,7 @@ impl Iterator for EscapeDefault { type Item = u8; fn next(&mut self) -> Option { self.range.next().map(|i| self.data[i]) } fn size_hint(&self) -> (usize, Option) { self.range.size_hint() } + fn last(mut self) -> Option { self.next_back() } } #[stable(feature = "rust1", since = "1.0.0")] impl DoubleEndedIterator for EscapeDefault { diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 34f2d8917ea..f3fbf351817 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -1333,6 +1333,11 @@ impl<'a> Iterator for Lines<'a> { fn size_hint(&self) -> (usize, Option) { self.0.size_hint() } + + #[inline] + fn last(mut self) -> Option<&'a str> { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -4241,6 +4246,11 @@ impl<'a> Iterator for SplitWhitespace<'a> { fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } + + #[inline] + fn last(mut self) -> Option<&'a str> { + self.next_back() + } } #[stable(feature = "split_whitespace", since = "1.1.0")] @@ -4267,6 +4277,11 @@ impl<'a> Iterator for SplitAsciiWhitespace<'a> { fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } + + #[inline] + fn last(mut self) -> Option<&'a str> { + self.next_back() + } } #[stable(feature = "split_ascii_whitespace", since = "1.34.0")] -- cgit 1.4.1-3-g733a5 From 38d4c1b2fc6820a48fd1ad7e8e7b68cb71c0bf79 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Thu, 20 Jun 2019 23:38:58 -0700 Subject: Fix the links in Vec(Deque)-from-Vec(Deque) Ok, I can't use `std` in doc-links, only in doc-tests. Try 7... --- src/liballoc/collections/vec_deque.rs | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/liballoc') diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index 71faf672962..0e98dd53ef7 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -2711,6 +2711,9 @@ impl fmt::Debug for VecDeque { impl From> for VecDeque { /// Turn a [`Vec`] into a [`VecDeque`]. /// + /// [`Vec`]: crate::vec::Vec + /// [`VecDeque`]: crate::collections::VecDeque + /// /// This avoids reallocating where possible, but the conditions for that are /// strict, and subject to change, and so shouldn't be relied upon unless the /// `Vec` came from `From>` and hasn't been reallocated. @@ -2742,6 +2745,9 @@ impl From> for VecDeque { impl From> for Vec { /// Turn a [`VecDeque`] into a [`Vec`]. /// + /// [`Vec`]: crate::vec::Vec + /// [`VecDeque`]: crate::collections::VecDeque + /// /// This never needs to re-allocate, but does need to do O(n) data movement if /// the circular buffer doesn't happen to be at the beginning of the allocation. /// -- cgit 1.4.1-3-g733a5 From 4dd5edc76ddf4ceebc1b2b4815028b04bb9cc21e Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 3 Jul 2019 19:41:16 +0200 Subject: enable a few more tests in Miri and update the comment for others --- src/liballoc/tests/vec.rs | 1 - src/libcore/tests/fmt/mod.rs | 2 -- src/libcore/tests/ptr.rs | 5 ++--- src/libcore/tests/slice.rs | 4 ++-- 4 files changed, 4 insertions(+), 8 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/tests/vec.rs b/src/liballoc/tests/vec.rs index 5ddac673c9f..e0c724f557b 100644 --- a/src/liballoc/tests/vec.rs +++ b/src/liballoc/tests/vec.rs @@ -761,7 +761,6 @@ fn from_into_inner() { it.next().unwrap(); let vec = it.collect::>(); assert_eq!(vec, [2, 3]); - #[cfg(not(miri))] // Miri does not support comparing dangling pointers assert!(ptr != vec.as_ptr()); } diff --git a/src/libcore/tests/fmt/mod.rs b/src/libcore/tests/fmt/mod.rs index df1deeaeb97..d86e21cf40b 100644 --- a/src/libcore/tests/fmt/mod.rs +++ b/src/libcore/tests/fmt/mod.rs @@ -3,7 +3,6 @@ mod float; mod num; #[test] -#[cfg(not(miri))] // Miri cannot print pointers fn test_format_flags() { // No residual flags left by pointer formatting let p = "".as_ptr(); @@ -13,7 +12,6 @@ fn test_format_flags() { } #[test] -#[cfg(not(miri))] // Miri cannot print pointers fn test_pointer_formats_data_pointer() { let b: &[u8] = b""; let s: &str = ""; diff --git a/src/libcore/tests/ptr.rs b/src/libcore/tests/ptr.rs index 03fe1fe5a7c..569b3197d09 100644 --- a/src/libcore/tests/ptr.rs +++ b/src/libcore/tests/ptr.rs @@ -253,7 +253,6 @@ fn test_unsized_nonnull() { #[test] #[allow(warnings)] -#[cfg(not(miri))] // Miri cannot hash pointers // Have a symbol for the test below. It doesn’t need to be an actual variadic function, match the // ABI, or even point to an actual executable code, because the function itself is never invoked. #[no_mangle] @@ -293,7 +292,7 @@ fn write_unaligned_drop() { } #[test] -#[cfg(not(miri))] // Miri cannot compute actual alignment of an allocation +#[cfg(not(miri))] // Miri does not compute a maximal `mid` for `align_offset` fn align_offset_zst() { // For pointers of stride = 0, the pointer is already aligned or it cannot be aligned at // all, because no amount of elements will align the pointer. @@ -308,7 +307,7 @@ fn align_offset_zst() { } #[test] -#[cfg(not(miri))] // Miri cannot compute actual alignment of an allocation +#[cfg(not(miri))] // Miri does not compute a maximal `mid` for `align_offset` fn align_offset_stride1() { // For pointers of stride = 1, the pointer can always be aligned. The offset is equal to // number of bytes. diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs index 03e65d2fe0b..72161b63241 100644 --- a/src/libcore/tests/slice.rs +++ b/src/libcore/tests/slice.rs @@ -1396,7 +1396,7 @@ pub mod memchr { } #[test] -#[cfg(not(miri))] // Miri cannot compute actual alignment of an allocation +#[cfg(not(miri))] // Miri does not compute a maximal `mid` for `align_offset` fn test_align_to_simple() { let bytes = [1u8, 2, 3, 4, 5, 6, 7]; let (prefix, aligned, suffix) = unsafe { bytes.align_to::() }; @@ -1420,7 +1420,7 @@ fn test_align_to_zst() { } #[test] -#[cfg(not(miri))] // Miri cannot compute actual alignment of an allocation +#[cfg(not(miri))] // Miri does not compute a maximal `mid` for `align_offset` fn test_align_to_non_trivial() { #[repr(align(8))] struct U64(u64, u64); #[repr(align(8))] struct U64U64U32(u64, u64, u32); -- cgit 1.4.1-3-g733a5 From 55bd2140a23eb164a6b3bb6b7014e7ad757994f3 Mon Sep 17 00:00:00 2001 From: Wim Looman Date: Thu, 4 Jul 2019 12:55:23 +0200 Subject: Add tracking issue for Box::into_pin --- src/liballoc/boxed.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/liballoc') diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 41966360377..01dee0a3943 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -320,7 +320,7 @@ impl Box { /// This conversion does not allocate on the heap and happens in place. /// /// This is also available via [`From`]. - #[unstable(feature = "box_into_pin", issue = "0")] + #[unstable(feature = "box_into_pin", issue = "62370")] pub fn into_pin(boxed: Box) -> Pin> { // It's not possible to move or replace the insides of a `Pin>` // when `T: !Unpin`, so it's safe to pin it directly without any -- cgit 1.4.1-3-g733a5 From 8a7dded1a249a21540583333204c378bf960a700 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Thu, 4 Jul 2019 10:05:50 -0400 Subject: Switch master to 1.38 --- src/bootstrap/channel.rs | 2 +- src/liballoc/alloc.rs | 3 +- src/liballoc/lib.rs | 1 - src/libcore/ffi.rs | 6 ---- src/libcore/future/future.rs | 2 +- src/libcore/intrinsics.rs | 57 ---------------------------------- src/libcore/lib.rs | 2 +- src/libcore/mem/maybe_uninit.rs | 2 +- src/libcore/num/mod.rs | 2 +- src/libcore/ptr/non_null.rs | 2 +- src/librustc_data_structures/macros.rs | 4 +-- src/librustc_resolve/lib.rs | 1 - src/libsyntax/tokenstream.rs | 11 ------- src/libunwind/build.rs | 8 ++--- src/libunwind/libunwind.rs | 10 +++--- src/stage0.txt | 2 +- 16 files changed, 17 insertions(+), 98 deletions(-) (limited to 'src/liballoc') diff --git a/src/bootstrap/channel.rs b/src/bootstrap/channel.rs index 41235d911c0..8e8d8f5e787 100644 --- a/src/bootstrap/channel.rs +++ b/src/bootstrap/channel.rs @@ -13,7 +13,7 @@ use build_helper::output; use crate::Build; // The version number -pub const CFG_RELEASE_NUM: &str = "1.37.0"; +pub const CFG_RELEASE_NUM: &str = "1.38.0"; pub struct GitInfo { inner: Option, diff --git a/src/liballoc/alloc.rs b/src/liballoc/alloc.rs index 755feb84962..cef2b5eea34 100644 --- a/src/liballoc/alloc.rs +++ b/src/liballoc/alloc.rs @@ -15,8 +15,7 @@ extern "Rust" { // them from the `#[global_allocator]` attribute if there is one, or uses the // default implementations in libstd (`__rdl_alloc` etc in `src/libstd/alloc.rs`) // otherwise. - #[cfg_attr(bootstrap, allocator)] - #[cfg_attr(not(bootstrap), rustc_allocator)] + #[rustc_allocator] #[rustc_allocator_nounwind] fn __rust_alloc(size: usize, align: usize) -> *mut u8; #[rustc_allocator_nounwind] diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index bfe7d12d9d0..0750665c6b4 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -79,7 +79,6 @@ #![feature(coerce_unsized)] #![feature(dispatch_from_dyn)] #![feature(core_intrinsics)] -#![cfg_attr(bootstrap, feature(custom_attribute))] #![feature(dropck_eyepatch)] #![feature(exact_size_is_empty)] #![feature(fmt_internals)] diff --git a/src/libcore/ffi.rs b/src/libcore/ffi.rs index 49090fb8e43..4f87cc506ef 100644 --- a/src/libcore/ffi.rs +++ b/src/libcore/ffi.rs @@ -302,7 +302,6 @@ impl sealed_trait::VaArgSafe for *const T {} reason = "the `c_variadic` feature has not been properly tested on \ all supported platforms", issue = "44930")] -#[cfg(not(bootstrap))] impl<'f> VaListImpl<'f> { /// Advance to the next arg. #[inline] @@ -324,7 +323,6 @@ impl<'f> VaListImpl<'f> { reason = "the `c_variadic` feature has not been properly tested on \ all supported platforms", issue = "44930")] -#[cfg(not(bootstrap))] impl<'f> Clone for VaListImpl<'f> { #[inline] fn clone(&self) -> Self { @@ -340,7 +338,6 @@ impl<'f> Clone for VaListImpl<'f> { reason = "the `c_variadic` feature has not been properly tested on \ all supported platforms", issue = "44930")] -#[cfg(not(bootstrap))] impl<'f> Drop for VaListImpl<'f> { fn drop(&mut self) { // FIXME: this should call `va_end`, but there's no clean way to @@ -359,15 +356,12 @@ impl<'f> Drop for VaListImpl<'f> { extern "rust-intrinsic" { /// Destroy the arglist `ap` after initialization with `va_start` or /// `va_copy`. - #[cfg(not(bootstrap))] fn va_end(ap: &mut VaListImpl<'_>); /// Copies the current location of arglist `src` to the arglist `dst`. - #[cfg(not(bootstrap))] fn va_copy<'f>(dest: *mut VaListImpl<'f>, src: &VaListImpl<'f>); /// Loads an argument of type `T` from the `va_list` `ap` and increment the /// argument `ap` points to. - #[cfg(not(bootstrap))] fn va_arg(ap: &mut VaListImpl<'_>) -> T; } diff --git a/src/libcore/future/future.rs b/src/libcore/future/future.rs index acca8d7ba15..8bd1601a362 100644 --- a/src/libcore/future/future.rs +++ b/src/libcore/future/future.rs @@ -25,7 +25,7 @@ use crate::task::{Context, Poll}; #[doc(spotlight)] #[must_use = "futures do nothing unless you `.await` or poll them"] #[stable(feature = "futures_api", since = "1.36.0")] -#[cfg_attr(not(bootstrap), lang = "future_trait")] +#[lang = "future_trait"] pub trait Future { /// The type of value produced on completion. #[stable(feature = "futures_api", since = "1.36.0")] diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index b30eff8baa9..8e53022c287 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -1052,16 +1052,12 @@ extern "rust-intrinsic" { pub fn fabsf64(x: f64) -> f64; /// Returns the minimum of two `f32` values. - #[cfg(not(bootstrap))] pub fn minnumf32(x: f32, y: f32) -> f32; /// Returns the minimum of two `f64` values. - #[cfg(not(bootstrap))] pub fn minnumf64(x: f64, y: f64) -> f64; /// Returns the maximum of two `f32` values. - #[cfg(not(bootstrap))] pub fn maxnumf32(x: f32, y: f32) -> f32; /// Returns the maximum of two `f64` values. - #[cfg(not(bootstrap))] pub fn maxnumf64(x: f64, y: f64) -> f64; /// Copies the sign from `y` to `x` for `f32` values. @@ -1255,17 +1251,14 @@ extern "rust-intrinsic" { /// Returns the result of an unchecked addition, resulting in /// undefined behavior when `x + y > T::max_value()` or `x + y < T::min_value()`. - #[cfg(not(bootstrap))] pub fn unchecked_add(x: T, y: T) -> T; /// Returns the result of an unchecked substraction, resulting in /// undefined behavior when `x - y > T::max_value()` or `x - y < T::min_value()`. - #[cfg(not(bootstrap))] pub fn unchecked_sub(x: T, y: T) -> T; /// Returns the result of an unchecked multiplication, resulting in /// undefined behavior when `x * y > T::max_value()` or `x * y < T::min_value()`. - #[cfg(not(bootstrap))] pub fn unchecked_mul(x: T, y: T) -> T; /// Performs rotate left. @@ -1563,53 +1556,3 @@ pub unsafe fn write_bytes(dst: *mut T, val: u8, count: usize) { } write_bytes(dst, val, count) } - -// Simple bootstrap implementations of minnum/maxnum for stage0 compilation. - -/// Returns the minimum of two `f32` values. -#[cfg(bootstrap)] -pub fn minnumf32(x: f32, y: f32) -> f32 { - // IEEE754 says: minNum(x, y) is the canonicalized number x if x < y, y if y < x, the - // canonicalized number if one operand is a number and the other a quiet NaN. Otherwise it - // is either x or y, canonicalized (this means results might differ among implementations). - // When either x or y is a signaling NaN, then the result is according to 6.2. - // - // Since we do not support sNaN in Rust yet, we do not need to handle them. - // FIXME(nagisa): due to https://bugs.llvm.org/show_bug.cgi?id=33303 we canonicalize by - // multiplying by 1.0. Should switch to the `canonicalize` when it works. - (if x < y || y != y { x } else { y }) * 1.0 -} - -/// Returns the minimum of two `f64` values. -#[cfg(bootstrap)] -pub fn minnumf64(x: f64, y: f64) -> f64 { - // Identical to the `f32` case. - (if x < y || y != y { x } else { y }) * 1.0 -} - -/// Returns the maximum of two `f32` values. -#[cfg(bootstrap)] -pub fn maxnumf32(x: f32, y: f32) -> f32 { - // IEEE754 says: maxNum(x, y) is the canonicalized number y if x < y, x if y < x, the - // canonicalized number if one operand is a number and the other a quiet NaN. Otherwise it - // is either x or y, canonicalized (this means results might differ among implementations). - // When either x or y is a signaling NaN, then the result is according to 6.2. - // - // Since we do not support sNaN in Rust yet, we do not need to handle them. - // FIXME(nagisa): due to https://bugs.llvm.org/show_bug.cgi?id=33303 we canonicalize by - // multiplying by 1.0. Should switch to the `canonicalize` when it works. - (if x < y || x != x { y } else { x }) * 1.0 -} - -/// Returns the maximum of two `f64` values. -#[cfg(bootstrap)] -pub fn maxnumf64(x: f64, y: f64) -> f64 { - // Identical to the `f32` case. - (if x < y || x != x { y } else { x }) * 1.0 -} - -/// For bootstrapping, implement unchecked_sub as just wrapping_sub. -#[cfg(bootstrap)] -pub unsafe fn unchecked_sub(x: T, y: T) -> T { - sub_with_overflow(x, y).0 -} diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index d2d08a075b9..398b929b206 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -99,7 +99,7 @@ #![feature(staged_api)] #![feature(std_internals)] #![feature(stmt_expr_attributes)] -#![cfg_attr(not(bootstrap), feature(transparent_unions))] +#![feature(transparent_unions)] #![feature(unboxed_closures)] #![feature(unsized_locals)] #![feature(untagged_unions)] diff --git a/src/libcore/mem/maybe_uninit.rs b/src/libcore/mem/maybe_uninit.rs index 28e1e22ba7f..407691662d1 100644 --- a/src/libcore/mem/maybe_uninit.rs +++ b/src/libcore/mem/maybe_uninit.rs @@ -207,7 +207,7 @@ use crate::mem::ManuallyDrop; #[allow(missing_debug_implementations)] #[stable(feature = "maybe_uninit", since = "1.36.0")] #[derive(Copy)] -#[cfg_attr(not(bootstrap), repr(transparent))] +#[repr(transparent)] pub union MaybeUninit { uninit: (), value: ManuallyDrop, diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index d70f5567011..72552c5a0b0 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -50,7 +50,7 @@ assert_eq!(size_of::>(), size_of::<", s #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] #[repr(transparent)] #[rustc_layout_scalar_valid_range_start(1)] - #[cfg_attr(not(bootstrap), rustc_nonnull_optimization_guaranteed)] + #[rustc_nonnull_optimization_guaranteed] pub struct $Ty($Int); } diff --git a/src/libcore/ptr/non_null.rs b/src/libcore/ptr/non_null.rs index 46dde7c1da5..ad3d1ce396a 100644 --- a/src/libcore/ptr/non_null.rs +++ b/src/libcore/ptr/non_null.rs @@ -38,7 +38,7 @@ use crate::cmp::Ordering; #[stable(feature = "nonnull", since = "1.25.0")] #[repr(transparent)] #[rustc_layout_scalar_valid_range_start(1)] -#[cfg_attr(not(bootstrap), rustc_nonnull_optimization_guaranteed)] +#[rustc_nonnull_optimization_guaranteed] pub struct NonNull { pointer: *const T, } diff --git a/src/librustc_data_structures/macros.rs b/src/librustc_data_structures/macros.rs index 6e7a8e98853..3f75523a815 100644 --- a/src/librustc_data_structures/macros.rs +++ b/src/librustc_data_structures/macros.rs @@ -1,7 +1,6 @@ /// A simple static assertion macro. #[macro_export] -#[cfg_attr(bootstrap, allow_internal_unstable(type_ascription, underscore_const_names))] -#[cfg_attr(not(bootstrap), allow_internal_unstable(type_ascription))] +#[allow_internal_unstable(type_ascription)] macro_rules! static_assert { ($test:expr) => { // Use the bool to access an array such that if the bool is false, the access @@ -13,7 +12,6 @@ macro_rules! static_assert { /// Type size assertion. The first argument is a type and the second argument is its expected size. #[macro_export] -#[cfg_attr(bootstrap, allow_internal_unstable(underscore_const_names))] macro_rules! static_assert_size { ($ty:ty, $size:expr) => { const _: [(); $size] = [(); ::std::mem::size_of::<$ty>()]; diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 05247600a4d..ce5a6b854ea 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -7,7 +7,6 @@ #![feature(mem_take)] #![feature(nll)] #![feature(rustc_diagnostic_macros)] -#![cfg_attr(bootstrap, feature(type_alias_enum_variants))] #![recursion_limit="256"] diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs index cd906bb282b..b32049b1da8 100644 --- a/src/libsyntax/tokenstream.rs +++ b/src/libsyntax/tokenstream.rs @@ -59,17 +59,6 @@ where TokenStream: Send + Sync, {} -// These are safe since we ensure that they hold for all fields in the `_dummy` function. -// -// These impls are only here because the compiler takes forever to compute the Send and Sync -// bounds without them. -// FIXME: Remove these impls when the compiler can compute the bounds quickly again. -// See https://github.com/rust-lang/rust/issues/60846 -#[cfg(all(bootstrap, parallel_compiler))] -unsafe impl Send for TokenTree {} -#[cfg(all(bootstrap, parallel_compiler))] -unsafe impl Sync for TokenTree {} - impl TokenTree { /// Use this token tree as a matcher to parse given tts. pub fn parse(cx: &base::ExtCtxt<'_>, mtch: &[quoted::TokenTree], tts: TokenStream) diff --git a/src/libunwind/build.rs b/src/libunwind/build.rs index e92c68f5b0c..20280aa3c41 100644 --- a/src/libunwind/build.rs +++ b/src/libunwind/build.rs @@ -4,13 +4,11 @@ fn main() { println!("cargo:rerun-if-changed=build.rs"); let target = env::var("TARGET").expect("TARGET was not set"); - // FIXME: the not(bootstrap) part is needed because of the issue addressed by #62286, - // and could be removed once that change is in beta. - if cfg!(all(not(bootstrap), feature = "llvm-libunwind")) && + if cfg!(feature = "llvm-libunwind") && (target.contains("linux") || target.contains("fuchsia")) { // Build the unwinding from libunwind C/C++ source code. - #[cfg(all(not(bootstrap), feature = "llvm-libunwind"))] + #[cfg(feature = "llvm-libunwind")] llvm_libunwind::compile(); } else if target.contains("linux") { if target.contains("musl") { @@ -44,7 +42,7 @@ fn main() { } } -#[cfg(all(not(bootstrap), feature = "llvm-libunwind"))] +#[cfg(feature = "llvm-libunwind")] mod llvm_libunwind { use std::env; use std::path::Path; diff --git a/src/libunwind/libunwind.rs b/src/libunwind/libunwind.rs index 7e640897af7..41adc0a4153 100644 --- a/src/libunwind/libunwind.rs +++ b/src/libunwind/libunwind.rs @@ -67,7 +67,7 @@ pub enum _Unwind_Context {} pub type _Unwind_Exception_Cleanup_Fn = extern "C" fn(unwind_code: _Unwind_Reason_Code, exception: *mut _Unwind_Exception); -#[cfg_attr(all(not(bootstrap), feature = "llvm-libunwind"), +#[cfg_attr(feature = "llvm-libunwind", link(name = "unwind", kind = "static"))] extern "C" { #[unwind(allowed)] @@ -93,7 +93,7 @@ if #[cfg(all(any(target_os = "ios", target_os = "netbsd", not(target_arch = "arm } pub use _Unwind_Action::*; - #[cfg_attr(all(not(bootstrap), feature = "llvm-libunwind"), + #[cfg_attr(feature = "llvm-libunwind", link(name = "unwind", kind = "static"))] extern "C" { pub fn _Unwind_GetGR(ctx: *mut _Unwind_Context, reg_index: c_int) -> _Unwind_Word; @@ -148,7 +148,7 @@ if #[cfg(all(any(target_os = "ios", target_os = "netbsd", not(target_arch = "arm pub const UNWIND_POINTER_REG: c_int = 12; pub const UNWIND_IP_REG: c_int = 15; - #[cfg_attr(all(not(bootstrap), feature = "llvm-libunwind"), + #[cfg_attr(feature = "llvm-libunwind", link(name = "unwind", kind = "static"))] extern "C" { fn _Unwind_VRS_Get(ctx: *mut _Unwind_Context, @@ -212,7 +212,7 @@ if #[cfg(all(any(target_os = "ios", target_os = "netbsd", not(target_arch = "arm cfg_if::cfg_if! { if #[cfg(not(all(target_os = "ios", target_arch = "arm")))] { // Not 32-bit iOS - #[cfg_attr(all(not(bootstrap), feature = "llvm-libunwind"), + #[cfg_attr(feature = "llvm-libunwind", link(name = "unwind", kind = "static"))] extern "C" { #[unwind(allowed)] @@ -223,7 +223,7 @@ if #[cfg(not(all(target_os = "ios", target_arch = "arm")))] { } } else { // 32-bit iOS uses SjLj and does not provide _Unwind_Backtrace() - #[cfg_attr(all(not(bootstrap), feature = "llvm-libunwind"), + #[cfg_attr(feature = "llvm-libunwind", link(name = "unwind", kind = "static"))] extern "C" { #[unwind(allowed)] diff --git a/src/stage0.txt b/src/stage0.txt index d928d0888a0..9b70a404582 100644 --- a/src/stage0.txt +++ b/src/stage0.txt @@ -12,7 +12,7 @@ # source tarball for a stable release you'll likely see `1.x.0` for rustc and # `0.x.0` for Cargo where they were released on `date`. -date: 2019-05-23 +date: 2019-07-04 rustc: beta cargo: beta -- cgit 1.4.1-3-g733a5 From 63f2c22675bad6de9545d1b225a562debbaa7b4e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 2 Jul 2019 17:04:25 +0200 Subject: Add missing doc links in boxed module --- src/liballoc/boxed.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 9109a730cce..ce6d5166e87 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -1,6 +1,6 @@ //! A pointer type for heap allocation. //! -//! `Box`, casually referred to as a 'box', provides the simplest form of +//! [`Box`], casually referred to as a 'box', provides the simplest form of //! heap allocation in Rust. Boxes provide ownership for this allocation, and //! drop their contents when they go out of scope. //! @@ -48,7 +48,7 @@ //! //! It wouldn't work. This is because the size of a `List` depends on how many //! elements are in the list, and so we don't know how much memory to allocate -//! for a `Cons`. By introducing a `Box`, which has a defined size, we know how +//! for a `Cons`. By introducing a [`Box`], which has a defined size, we know how //! big `Cons` needs to be. //! //! # Memory layout @@ -59,15 +59,19 @@ //! [`Layout`] used with the allocator is correct for the type. More precisely, //! a `value: *mut T` that has been allocated with the [`Global`] allocator //! with `Layout::for_value(&*value)` may be converted into a box using -//! `Box::::from_raw(value)`. Conversely, the memory backing a `value: *mut -//! T` obtained from `Box::::into_raw` may be deallocated using the -//! [`Global`] allocator with `Layout::for_value(&*value)`. +//! [`Box::::from_raw(value)`]. Conversely, the memory backing a `value: *mut +//! T` obtained from [`Box::::into_raw`] may be deallocated using the +//! [`Global`] allocator with [`Layout::for_value(&*value)`]. //! //! //! [dereferencing]: ../../std/ops/trait.Deref.html //! [`Box`]: struct.Box.html +//! [`Box`]: struct.Box.html +//! [`Box::::from_raw(value)`]: struct.Box.html#method.from_raw +//! [`Box::::into_raw`]: struct.Box.html#method.into_raw //! [`Global`]: ../alloc/struct.Global.html //! [`Layout`]: ../alloc/struct.Layout.html +//! [`Layout::for_value(&*value)`]: ../alloc/struct.Layout.html#method.for_value #![stable(feature = "rust1", since = "1.0.0")] -- cgit 1.4.1-3-g733a5 From e808d921ddc0ad81a200934fc4caabc34094afe5 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Fri, 5 Jul 2019 11:38:40 +0200 Subject: Replace SliceConcatExt trait with inherent methods and SliceConcat helper trait Before this change `SliceConcatExt` was an unstable extension trait with stable methods. It was in the libstd prelude, so that its methods could be used on the stable channel. This replaces it with inherent methods, which can be used without any addition to the prelude. Since the methods are stable and very generic (with for example a return type that depends on the types of parameters), an helper trait is still needed. But now that trait does not need to be in scope for the methods to be used. Removing this depedency on the libstd prelude allows the methods to be used in `#![no_std]` crate that use liballoc, which does not have its own implicitly-imported prelude. --- src/liballoc/prelude/v1.rs | 1 - src/liballoc/slice.rs | 129 ++++++++++++++++++++++++--------------------- src/liballoc/str.rs | 14 ++--- src/libstd/prelude/mod.rs | 3 -- src/libstd/prelude/v1.rs | 3 -- 5 files changed, 76 insertions(+), 74 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/prelude/v1.rs b/src/liballoc/prelude/v1.rs index b6b01395ad6..3cb285bf049 100644 --- a/src/liballoc/prelude/v1.rs +++ b/src/liballoc/prelude/v1.rs @@ -6,6 +6,5 @@ #[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::borrow::ToOwned; #[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::boxed::Box; -#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::slice::SliceConcatExt; #[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::string::{String, ToString}; #[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::vec::Vec; diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index f7b0a5e703c..bc4ae167984 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -484,6 +484,56 @@ impl [T] { } buf } + + /// Flattens a slice of `T` into a single value `Self::Output`. + /// + /// # Examples + /// + /// ``` + /// assert_eq!(["hello", "world"].concat(), "helloworld"); + /// assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn concat(&self) -> T::Output + where T: SliceConcat + { + SliceConcat::concat(self) + } + + /// Flattens a slice of `T` into a single value `Self::Output`, placing a + /// given separator between each. + /// + /// # Examples + /// + /// ``` + /// assert_eq!(["hello", "world"].join(" "), "hello world"); + /// assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]); + /// ``` + #[stable(feature = "rename_connect_to_join", since = "1.3.0")] + pub fn join(&self, sep: &Separator) -> T::Output + where T: SliceConcat + { + SliceConcat::join(self, sep) + } + + /// Flattens a slice of `T` into a single value `Self::Output`, placing a + /// given separator between each. + /// + /// # Examples + /// + /// ``` + /// # #![allow(deprecated)] + /// assert_eq!(["hello", "world"].connect(" "), "hello world"); + /// assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_deprecated(since = "1.3.0", reason = "renamed to join")] + pub fn connect(&self, sep: &Separator) -> T::Output + where T: SliceConcat + { + SliceConcat::join(self, sep) + } + } #[lang = "slice_u8_alloc"] @@ -527,87 +577,46 @@ impl [u8] { //////////////////////////////////////////////////////////////////////////////// // Extension traits for slices over specific kinds of data //////////////////////////////////////////////////////////////////////////////// -#[unstable(feature = "slice_concat_ext", - reason = "trait should not have to exist", - issue = "27747")] -/// An extension trait for concatenating slices -/// -/// While this trait is unstable, the methods are stable. `SliceConcatExt` is -/// included in the [standard library prelude], so you can use [`join()`] and -/// [`concat()`] as if they existed on `[T]` itself. -/// -/// [standard library prelude]: ../../std/prelude/index.html -/// [`join()`]: #tymethod.join -/// [`concat()`]: #tymethod.concat -pub trait SliceConcatExt { - #[unstable(feature = "slice_concat_ext", - reason = "trait should not have to exist", - issue = "27747")] + +/// Helper trait for [`[T]::concat`](../../std/primitive.slice.html#method.concat) +/// and [`[T]::join`](../../std/primitive.slice.html#method.join) +#[unstable(feature = "slice_concat_trait", issue = "27747")] +pub trait SliceConcat: Sized { + #[unstable(feature = "slice_concat_trait", issue = "27747")] /// The resulting type after concatenation type Output; - /// Flattens a slice of `T` into a single value `Self::Output`. - /// - /// # Examples - /// - /// ``` - /// assert_eq!(["hello", "world"].concat(), "helloworld"); - /// assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - fn concat(&self) -> Self::Output; - - /// Flattens a slice of `T` into a single value `Self::Output`, placing a - /// given separator between each. - /// - /// # Examples - /// - /// ``` - /// assert_eq!(["hello", "world"].join(" "), "hello world"); - /// assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]); - /// ``` - #[stable(feature = "rename_connect_to_join", since = "1.3.0")] - fn join(&self, sep: &T) -> Self::Output; + /// Implementation of [`[T]::concat`](../../std/primitive.slice.html#method.concat) + #[unstable(feature = "slice_concat_trait", issue = "27747")] + fn concat(slice: &[Self]) -> Self::Output; - /// Flattens a slice of `T` into a single value `Self::Output`, placing a - /// given separator between each. - /// - /// # Examples - /// - /// ``` - /// # #![allow(deprecated)] - /// assert_eq!(["hello", "world"].connect(" "), "hello world"); - /// assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_deprecated(since = "1.3.0", reason = "renamed to join")] - fn connect(&self, sep: &T) -> Self::Output { - self.join(sep) - } + /// Implementation of [`[T]::join`](../../std/primitive.slice.html#method.join) + #[unstable(feature = "slice_concat_trait", issue = "27747")] + fn join(slice: &[Self], sep: &Separator) -> Self::Output; } #[unstable(feature = "slice_concat_ext", reason = "trait should not have to exist", issue = "27747")] -impl> SliceConcatExt for [V] { +impl> SliceConcat for V { type Output = Vec; - fn concat(&self) -> Vec { - let size = self.iter().map(|slice| slice.borrow().len()).sum(); + fn concat(slice: &[Self]) -> Vec { + let size = slice.iter().map(|slice| slice.borrow().len()).sum(); let mut result = Vec::with_capacity(size); - for v in self { + for v in slice { result.extend_from_slice(v.borrow()) } result } - fn join(&self, sep: &T) -> Vec { - let mut iter = self.iter(); + fn join(slice: &[Self], sep: &T) -> Vec { + let mut iter = slice.iter(); let first = match iter.next() { Some(first) => first, None => return vec![], }; - let size = self.iter().map(|slice| slice.borrow().len()).sum::() + self.len() - 1; + let size = slice.iter().map(|slice| slice.borrow().len()).sum::() + slice.len() - 1; let mut result = Vec::with_capacity(size); result.extend_from_slice(first.borrow()); diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs index 70a93157c9e..37a1046d094 100644 --- a/src/liballoc/str.rs +++ b/src/liballoc/str.rs @@ -37,7 +37,7 @@ use core::unicode::conversions; use crate::borrow::ToOwned; use crate::boxed::Box; -use crate::slice::{SliceConcatExt, SliceIndex}; +use crate::slice::{SliceConcat, SliceIndex}; use crate::string::String; use crate::vec::Vec; @@ -74,16 +74,16 @@ pub use core::str::{EscapeDebug, EscapeDefault, EscapeUnicode}; #[unstable(feature = "slice_concat_ext", reason = "trait should not have to exist", issue = "27747")] -impl> SliceConcatExt for [S] { +impl> SliceConcat for S { type Output = String; - fn concat(&self) -> String { - self.join("") + fn concat(slice: &[Self]) -> String { + Self::join(slice, "") } - fn join(&self, sep: &str) -> String { + fn join(slice: &[Self], sep: &str) -> String { unsafe { - String::from_utf8_unchecked( join_generic_copy(self, sep.as_bytes()) ) + String::from_utf8_unchecked( join_generic_copy(slice, sep.as_bytes()) ) } } } @@ -126,7 +126,7 @@ macro_rules! copy_slice_and_advance { // Optimized join implementation that works for both Vec (T: Copy) and String's inner vec // Currently (2018-05-13) there is a bug with type inference and specialization (see issue #36262) -// For this reason SliceConcatExt is not specialized for T: Copy and SliceConcatExt is the +// For this reason SliceConcat is not specialized for T: Copy and SliceConcat is the // only user of this function. It is left in place for the time when that is fixed. // // the bounds for String-join are S: Borrow and for Vec-join Borrow<[T]> diff --git a/src/libstd/prelude/mod.rs b/src/libstd/prelude/mod.rs index 551e982a3c6..3085c3d8296 100644 --- a/src/libstd/prelude/mod.rs +++ b/src/libstd/prelude/mod.rs @@ -71,9 +71,6 @@ //! * [`std::result`]::[`Result`]::{`self`, `Ok`, `Err`}. A type for functions //! that may succeed or fail. Like [`Option`], its variants are exported as //! well. -//! * [`std::slice`]::[`SliceConcatExt`], a trait that exists for technical -//! reasons, but shouldn't have to exist. It provides a few useful methods on -//! slices. //! * [`std::string`]::{[`String`], [`ToString`]}, heap allocated strings. //! * [`std::vec`]::[`Vec`](../vec/struct.Vec.html), a growable, heap-allocated //! vector. diff --git a/src/libstd/prelude/v1.rs b/src/libstd/prelude/v1.rs index ce1e8e3319c..a863bebf4a2 100644 --- a/src/libstd/prelude/v1.rs +++ b/src/libstd/prelude/v1.rs @@ -60,9 +60,6 @@ pub use crate::boxed::Box; pub use crate::borrow::ToOwned; #[stable(feature = "rust1", since = "1.0.0")] #[doc(no_inline)] -pub use crate::slice::SliceConcatExt; -#[stable(feature = "rust1", since = "1.0.0")] -#[doc(no_inline)] pub use crate::string::{String, ToString}; #[stable(feature = "rust1", since = "1.0.0")] #[doc(no_inline)] -- cgit 1.4.1-3-g733a5 From 2534b287a6078688db25ee36ad084afc7378f6e4 Mon Sep 17 00:00:00 2001 From: Chris Gregory Date: Sun, 7 Jul 2019 08:31:50 -0700 Subject: Add doc links to liballoc crate page --- src/liballoc/lib.rs | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 0750665c6b4..ca0c61c599e 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -10,9 +10,9 @@ //! //! ## Boxed values //! -//! The [`Box`](boxed/index.html) type is a smart pointer type. There can -//! only be one owner of a `Box`, and the owner can decide to mutate the -//! contents, which live on the heap. +//! The [`Box`] type is a smart pointer type. There can only be one owner of a +//! [`Box`], and the owner can decide to mutate the contents, which live on the +//! heap. //! //! This type can be sent among threads efficiently as the size of a `Box` value //! is the same as that of a pointer. Tree-like data structures are often built @@ -20,20 +20,20 @@ //! //! ## Reference counted pointers //! -//! The [`Rc`](rc/index.html) type is a non-threadsafe reference-counted pointer -//! type intended for sharing memory within a thread. An `Rc` pointer wraps a -//! type, `T`, and only allows access to `&T`, a shared reference. +//! The [`Rc`] type is a non-threadsafe reference-counted pointer type intended +//! for sharing memory within a thread. An [`Rc`] pointer wraps a type, `T`, and +//! only allows access to `&T`, a shared reference. //! -//! This type is useful when inherited mutability (such as using `Box`) is too -//! constraining for an application, and is often paired with the `Cell` or -//! `RefCell` types in order to allow mutation. +//! This type is useful when inherited mutability (such as using [`Box`]) is too +//! constraining for an application, and is often paired with the [`Cell`] or +//! [`RefCell`] types in order to allow mutation. //! //! ## Atomically reference counted pointers //! -//! The [`Arc`](sync/index.html) type is the threadsafe equivalent of the `Rc` -//! type. It provides all the same functionality of `Rc`, except it requires -//! that the contained type `T` is shareable. Additionally, `Arc` is itself -//! sendable while `Rc` is not. +//! The [`Arc`] type is the threadsafe equivalent of the [`Rc`] type. It +//! provides all the same functionality of [`Rc`], except it requires that the +//! contained type `T` is shareable. Additionally, [`Arc`][`Arc`] is itself +//! sendable while [`Rc`][`Rc`] is not. //! //! This type allows for shared access to the contained data, and is often //! paired with synchronization primitives such as mutexes to allow mutation of @@ -49,6 +49,12 @@ //! //! The [`alloc`](alloc/index.html) module defines the low-level interface to the //! default global allocator. It is not compatible with the libc allocator API. +//! +//! [`Arc`]: sync/index.html +//! [`Box`]: boxed/index.html +//! [`Cell`]: ../core/cell/index.html +//! [`Rc`]: rc/index.html +//! [`RefCell`]: ../core/cell/index.html #![allow(unused_attributes)] #![stable(feature = "alloc", since = "1.36.0")] -- cgit 1.4.1-3-g733a5 From a4a6a67a0142d46205f0aa662dc29c1f37aca86d Mon Sep 17 00:00:00 2001 From: Aaron Loucks Date: Sun, 7 Jul 2019 13:26:06 -0400 Subject: Remove while loop in DrainFilter::drop and add additional docs --- src/liballoc/vec.rs | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 99116ac2d2f..4adbe6467a1 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -2748,10 +2748,19 @@ pub struct DrainFilter<'a, T, F> where F: FnMut(&mut T) -> bool, { vec: &'a mut Vec, + /// The index of the item that will be inspected by the next call to `next`. idx: usize, + /// The number of items that have been drained (removed) thus far. del: usize, + /// The original length of `vec` prior to draining. old_len: usize, + /// The filter test predicate. pred: F, + /// A flag that indicates a panic has occured in the filter test prodicate. + /// This is used as a hint in the drop implmentation to prevent consumption + /// of the remainder of the `DrainFilter`. Any unprocessed items will be + /// backshifted in the `vec`, but no further items will be dropped or + /// tested by the filter predicate. panic_flag: bool, } @@ -2810,25 +2819,18 @@ impl Drop for DrainFilter<'_, T, F> { fn drop(&mut self) { unsafe { - // Backshift any unprocessed elements, preventing double-drop - // of any element that *should* have been previously overwritten - // but was not due to a panic in the filter predicate. This is - // implemented via drop so that it's guaranteed to run even in - // the event of a panic while consuming the remainder of the - // DrainFilter. - while self.drain.idx < self.drain.old_len { - let i = self.drain.idx; - self.drain.idx += 1; - let v = slice::from_raw_parts_mut( - self.drain.vec.as_mut_ptr(), - self.drain.old_len, - ); - if self.drain.del > 0 { - let del = self.drain.del; - let src: *const T = &v[i]; - let dst: *mut T = &mut v[i - del]; - ptr::copy_nonoverlapping(src, dst, 1); - } + if self.drain.idx < self.drain.old_len && self.drain.del > 0 { + // This is a pretty messed up state, and there isn't really an + // obviously right thing to do. We don't want to keep trying + // to execute `pred`, so we just backshift all the unprocessed + // elements and tell the vec that they still exist. The backshift + // is required to prevent a double-drop of the last successfully + // drained item following a panic in the predicate. + let ptr = self.drain.vec.as_mut_ptr(); + let src = ptr.add(self.drain.idx); + let dst = src.sub(self.drain.del); + let tail_len = self.drain.old_len - self.drain.idx; + src.copy_to(dst, tail_len); } self.drain.vec.set_len(self.drain.old_len - self.drain.del); } -- cgit 1.4.1-3-g733a5 From df5b32ee9b98838c1cccc93f75f941ecafc9d086 Mon Sep 17 00:00:00 2001 From: Aaron Loucks Date: Sun, 7 Jul 2019 16:36:19 -0400 Subject: Clarify double-drop comment --- src/liballoc/vec.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/liballoc') diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 4adbe6467a1..8939248adab 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -2825,7 +2825,7 @@ impl Drop for DrainFilter<'_, T, F> // to execute `pred`, so we just backshift all the unprocessed // elements and tell the vec that they still exist. The backshift // is required to prevent a double-drop of the last successfully - // drained item following a panic in the predicate. + // drained item prior to a panic in the predicate. let ptr = self.drain.vec.as_mut_ptr(); let src = ptr.add(self.drain.idx); let dst = src.sub(self.drain.del); -- cgit 1.4.1-3-g733a5 From 5397dfce77f3b3d903580843af3da37615a44e74 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Mon, 8 Jul 2019 18:12:06 +0200 Subject: Remove obsolete “should not have to exist” reasons MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/liballoc/slice.rs | 4 +--- src/liballoc/str.rs | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index bc4ae167984..9a23cdc1768 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -595,9 +595,7 @@ pub trait SliceConcat: Sized { fn join(slice: &[Self], sep: &Separator) -> Self::Output; } -#[unstable(feature = "slice_concat_ext", - reason = "trait should not have to exist", - issue = "27747")] +#[unstable(feature = "slice_concat_ext", issue = "27747")] impl> SliceConcat for V { type Output = Vec; diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs index 37a1046d094..b6512487ddd 100644 --- a/src/liballoc/str.rs +++ b/src/liballoc/str.rs @@ -71,9 +71,7 @@ pub use core::str::SplitAsciiWhitespace; #[stable(feature = "str_escape", since = "1.34.0")] pub use core::str::{EscapeDebug, EscapeDefault, EscapeUnicode}; -#[unstable(feature = "slice_concat_ext", - reason = "trait should not have to exist", - issue = "27747")] +#[unstable(feature = "slice_concat_ext", issue = "27747")] impl> SliceConcat for S { type Output = String; -- cgit 1.4.1-3-g733a5 From 01d93bf59523c4e5c00cf8933c551adc73953cd1 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Mon, 8 Jul 2019 17:47:49 +0200 Subject: Split the SliceConcat trait into Concat and Join --- src/liballoc/slice.rs | 74 +++++++++++++++++++++++++++++++++++++++------------ src/liballoc/str.rs | 17 ++++++++---- 2 files changed, 69 insertions(+), 22 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index 9a23cdc1768..d7a9f83ad24 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -494,10 +494,10 @@ impl [T] { /// assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn concat(&self) -> T::Output - where T: SliceConcat + pub fn concat(&self) -> >::Output + where Self: Concat { - SliceConcat::concat(self) + Concat::concat(self) } /// Flattens a slice of `T` into a single value `Self::Output`, placing a @@ -510,10 +510,10 @@ impl [T] { /// assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]); /// ``` #[stable(feature = "rename_connect_to_join", since = "1.3.0")] - pub fn join(&self, sep: &Separator) -> T::Output - where T: SliceConcat + pub fn join(&self, sep: &Separator) -> >::Output + where Self: Join { - SliceConcat::join(self, sep) + Join::join(self, sep) } /// Flattens a slice of `T` into a single value `Self::Output`, placing a @@ -528,10 +528,10 @@ impl [T] { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[rustc_deprecated(since = "1.3.0", reason = "renamed to join")] - pub fn connect(&self, sep: &Separator) -> T::Output - where T: SliceConcat + pub fn connect(&self, sep: &Separator) -> >::Output + where Self: Join { - SliceConcat::join(self, sep) + Join::join(self, sep) } } @@ -578,28 +578,63 @@ impl [u8] { // Extension traits for slices over specific kinds of data //////////////////////////////////////////////////////////////////////////////// -/// Helper trait for [`[T]::concat`](../../std/primitive.slice.html#method.concat) -/// and [`[T]::join`](../../std/primitive.slice.html#method.join) +/// Helper trait for [`[T]::concat`](../../std/primitive.slice.html#method.concat). +/// +/// Note: the `Item` type parameter is not used in this trait, +/// but it allows impls to be more generic. +/// Without it, we get this error: +/// +/// ```error +/// error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predica +/// --> src/liballoc/slice.rs:608:6 +/// | +/// 608 | impl> Concat for [V] { +/// | ^ unconstrained type parameter +/// ``` +/// +/// This is because there could exist `V` types with multiple `Borrow<[_]>` impls, +/// such that multiple `T` types would apply: +/// +/// ``` +/// # #[allow(dead_code)] +/// pub struct Foo(Vec, Vec); +/// +/// impl std::borrow::Borrow<[u32]> for Foo { +/// fn borrow(&self) -> &[u32] { &self.0 } +/// } +/// +/// impl std::borrow::Borrow<[String]> for Foo { +/// fn borrow(&self) -> &[String] { &self.1 } +/// } +/// ``` #[unstable(feature = "slice_concat_trait", issue = "27747")] -pub trait SliceConcat: Sized { +pub trait Concat { #[unstable(feature = "slice_concat_trait", issue = "27747")] /// The resulting type after concatenation type Output; /// Implementation of [`[T]::concat`](../../std/primitive.slice.html#method.concat) #[unstable(feature = "slice_concat_trait", issue = "27747")] - fn concat(slice: &[Self]) -> Self::Output; + fn concat(slice: &Self) -> Self::Output; +} + +/// Helper trait for [`[T]::join`](../../std/primitive.slice.html#method.join) +#[unstable(feature = "slice_concat_trait", issue = "27747")] +pub trait Join { + #[unstable(feature = "slice_concat_trait", issue = "27747")] + /// The resulting type after concatenation + type Output; /// Implementation of [`[T]::join`](../../std/primitive.slice.html#method.join) #[unstable(feature = "slice_concat_trait", issue = "27747")] - fn join(slice: &[Self], sep: &Separator) -> Self::Output; + fn join(slice: &Self, sep: &Separator) -> Self::Output; } #[unstable(feature = "slice_concat_ext", issue = "27747")] -impl> SliceConcat for V { +impl> Concat for [V] { type Output = Vec; - fn concat(slice: &[Self]) -> Vec { + fn concat(slice: &Self) -> Vec { let size = slice.iter().map(|slice| slice.borrow().len()).sum(); let mut result = Vec::with_capacity(size); for v in slice { @@ -607,8 +642,13 @@ impl> SliceConcat for V { } result } +} + +#[unstable(feature = "slice_concat_ext", issue = "27747")] +impl> Join for [V] { + type Output = Vec; - fn join(slice: &[Self], sep: &T) -> Vec { + fn join(slice: &Self, sep: &T) -> Vec { let mut iter = slice.iter(); let first = match iter.next() { Some(first) => first, diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs index b6512487ddd..726ac1907fa 100644 --- a/src/liballoc/str.rs +++ b/src/liballoc/str.rs @@ -37,7 +37,7 @@ use core::unicode::conversions; use crate::borrow::ToOwned; use crate::boxed::Box; -use crate::slice::{SliceConcat, SliceIndex}; +use crate::slice::{Concat, Join, SliceIndex}; use crate::string::String; use crate::vec::Vec; @@ -71,15 +71,22 @@ pub use core::str::SplitAsciiWhitespace; #[stable(feature = "str_escape", since = "1.34.0")] pub use core::str::{EscapeDebug, EscapeDefault, EscapeUnicode}; +/// Note: `str` in `Concat` is not meaningful here. +/// This type parameter of the trait only exists to enable another impl. #[unstable(feature = "slice_concat_ext", issue = "27747")] -impl> SliceConcat for S { +impl> Concat for [S] { type Output = String; - fn concat(slice: &[Self]) -> String { - Self::join(slice, "") + fn concat(slice: &Self) -> String { + Join::join(slice, "") } +} + +#[unstable(feature = "slice_concat_ext", issue = "27747")] +impl> Join for [S] { + type Output = String; - fn join(slice: &[Self], sep: &str) -> String { + fn join(slice: &Self, sep: &str) -> String { unsafe { String::from_utf8_unchecked( join_generic_copy(slice, sep.as_bytes()) ) } -- cgit 1.4.1-3-g733a5 From 283f6762caebb723a17ce82e1fc120928697cfb9 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Mon, 8 Jul 2019 17:50:27 +0200 Subject: Take separator by value in `[T]::join` --- src/liballoc/slice.rs | 10 +++++----- src/liballoc/str.rs | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index d7a9f83ad24..1b18dbeda9c 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -510,7 +510,7 @@ impl [T] { /// assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]); /// ``` #[stable(feature = "rename_connect_to_join", since = "1.3.0")] - pub fn join(&self, sep: &Separator) -> >::Output + pub fn join(&self, sep: Separator) -> >::Output where Self: Join { Join::join(self, sep) @@ -528,7 +528,7 @@ impl [T] { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[rustc_deprecated(since = "1.3.0", reason = "renamed to join")] - pub fn connect(&self, sep: &Separator) -> >::Output + pub fn connect(&self, sep: Separator) -> >::Output where Self: Join { Join::join(self, sep) @@ -620,14 +620,14 @@ pub trait Concat { /// Helper trait for [`[T]::join`](../../std/primitive.slice.html#method.join) #[unstable(feature = "slice_concat_trait", issue = "27747")] -pub trait Join { +pub trait Join { #[unstable(feature = "slice_concat_trait", issue = "27747")] /// The resulting type after concatenation type Output; /// Implementation of [`[T]::join`](../../std/primitive.slice.html#method.join) #[unstable(feature = "slice_concat_trait", issue = "27747")] - fn join(slice: &Self, sep: &Separator) -> Self::Output; + fn join(slice: &Self, sep: Separator) -> Self::Output; } #[unstable(feature = "slice_concat_ext", issue = "27747")] @@ -645,7 +645,7 @@ impl> Concat for [V] { } #[unstable(feature = "slice_concat_ext", issue = "27747")] -impl> Join for [V] { +impl> Join<&'_ T> for [V] { type Output = Vec; fn join(slice: &Self, sep: &T) -> Vec { diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs index 726ac1907fa..f57cf96a641 100644 --- a/src/liballoc/str.rs +++ b/src/liballoc/str.rs @@ -83,7 +83,7 @@ impl> Concat for [S] { } #[unstable(feature = "slice_concat_ext", issue = "27747")] -impl> Join for [S] { +impl> Join<&'_ str> for [S] { type Output = String; fn join(slice: &Self, sep: &str) -> String { -- cgit 1.4.1-3-g733a5 From b62a77b4905150b14c8b0fd6e685f528e4f90ea7 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Mon, 8 Jul 2019 18:08:54 +0200 Subject: Add joining slices of slices with a slice separator, not just a single item --- src/liballoc/slice.rs | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'src/liballoc') diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index 1b18dbeda9c..d475c628ff1 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -508,6 +508,7 @@ impl [T] { /// ``` /// assert_eq!(["hello", "world"].join(" "), "hello world"); /// assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]); + /// assert_eq!([[1, 2], [3, 4]].join(&[0, 0][..]), [1, 2, 0, 0, 3, 4]); /// ``` #[stable(feature = "rename_connect_to_join", since = "1.3.0")] pub fn join(&self, sep: Separator) -> >::Output @@ -654,7 +655,7 @@ impl> Join<&'_ T> for [V] { Some(first) => first, None => return vec![], }; - let size = slice.iter().map(|slice| slice.borrow().len()).sum::() + slice.len() - 1; + let size = slice.iter().map(|v| v.borrow().len()).sum::() + slice.len() - 1; let mut result = Vec::with_capacity(size); result.extend_from_slice(first.borrow()); @@ -666,6 +667,29 @@ impl> Join<&'_ T> for [V] { } } +#[unstable(feature = "slice_concat_ext", issue = "27747")] +impl> Join<&'_ [T]> for [V] { + type Output = Vec; + + fn join(slice: &Self, sep: &[T]) -> Vec { + let mut iter = slice.iter(); + let first = match iter.next() { + Some(first) => first, + None => return vec![], + }; + let size = slice.iter().map(|v| v.borrow().len()).sum::() + + sep.len() * (slice.len() - 1); + let mut result = Vec::with_capacity(size); + result.extend_from_slice(first.borrow()); + + for v in iter { + result.extend_from_slice(sep); + result.extend_from_slice(v.borrow()) + } + result + } +} + //////////////////////////////////////////////////////////////////////////////// // Standard trait implementations for slices //////////////////////////////////////////////////////////////////////////////// -- cgit 1.4.1-3-g733a5 From d0635ee5f74badbf72355b7e29d7f0723e8551da Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Tue, 9 Jul 2019 18:19:01 +0200 Subject: Update src/liballoc/slice.rs Co-Authored-By: Mazdak Farrokhzad --- src/liballoc/slice.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/liballoc') diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index d475c628ff1..848df2f9dcf 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -646,7 +646,7 @@ impl> Concat for [V] { } #[unstable(feature = "slice_concat_ext", issue = "27747")] -impl> Join<&'_ T> for [V] { +impl> Join<&T> for [V] { type Output = Vec; fn join(slice: &Self, sep: &T) -> Vec { -- cgit 1.4.1-3-g733a5 From bbc9366c1a2d4d071b54cc1af23706a36741b444 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Tue, 9 Jul 2019 18:19:10 +0200 Subject: Update src/liballoc/slice.rs Co-Authored-By: Mazdak Farrokhzad --- src/liballoc/slice.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/liballoc') diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index 848df2f9dcf..881d499c074 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -668,7 +668,7 @@ impl> Join<&T> for [V] { } #[unstable(feature = "slice_concat_ext", issue = "27747")] -impl> Join<&'_ [T]> for [V] { +impl> Join<&[T]> for [V] { type Output = Vec; fn join(slice: &Self, sep: &[T]) -> Vec { -- cgit 1.4.1-3-g733a5 From 5f7768a976edc296c62479b936993b4dc9af065b Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Tue, 9 Jul 2019 18:19:18 +0200 Subject: Update src/liballoc/str.rs Co-Authored-By: Mazdak Farrokhzad --- src/liballoc/str.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/liballoc') diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs index f57cf96a641..9a1342c30d5 100644 --- a/src/liballoc/str.rs +++ b/src/liballoc/str.rs @@ -83,7 +83,7 @@ impl> Concat for [S] { } #[unstable(feature = "slice_concat_ext", issue = "27747")] -impl> Join<&'_ str> for [S] { +impl> Join<&str> for [S] { type Output = String; fn join(slice: &Self, sep: &str) -> String { -- cgit 1.4.1-3-g733a5 From f93032c818da6482777e6fa35a535a494241a0f1 Mon Sep 17 00:00:00 2001 From: Mateusz Mikuła Date: Thu, 18 Jul 2019 14:16:04 +0200 Subject: Fix clippy::clone_on_copy warnings --- src/liballoc/collections/linked_list.rs | 8 ++++---- src/liballoc/rc.rs | 2 +- src/liballoc/sync.rs | 2 +- src/libcore/alloc.rs | 4 ++-- src/libstd/sys/unix/alloc.rs | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs index db0d6e2f9b9..bbb96725ea0 100644 --- a/src/liballoc/collections/linked_list.rs +++ b/src/liballoc/collections/linked_list.rs @@ -237,15 +237,15 @@ impl LinkedList { // Not creating new mutable (unique!) references overlapping `element`. match node.prev { - Some(prev) => (*prev.as_ptr()).next = node.next.clone(), + Some(prev) => (*prev.as_ptr()).next = node.next, // this node is the head node - None => self.head = node.next.clone(), + None => self.head = node.next, }; match node.next { - Some(next) => (*next.as_ptr()).prev = node.prev.clone(), + Some(next) => (*next.as_ptr()).prev = node.prev, // this node is the tail node - None => self.tail = node.prev.clone(), + None => self.tail = node.prev, }; self.len -= 1; diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 36d54656795..0d0ff7c16f1 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -815,7 +815,7 @@ impl Rc<[T]> { let slice = from_raw_parts_mut(self.elems, self.n_elems); ptr::drop_in_place(slice); - Global.dealloc(self.mem, self.layout.clone()); + Global.dealloc(self.mem, self.layout); } } } diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index 7cb826ee024..93aff733724 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -703,7 +703,7 @@ impl Arc<[T]> { let slice = from_raw_parts_mut(self.elems, self.n_elems); ptr::drop_in_place(slice); - Global.dealloc(self.mem.cast(), self.layout.clone()); + Global.dealloc(self.mem.cast(), self.layout); } } } diff --git a/src/libcore/alloc.rs b/src/libcore/alloc.rs index 487f3b76fc7..5d0333d5226 100644 --- a/src/libcore/alloc.rs +++ b/src/libcore/alloc.rs @@ -827,11 +827,11 @@ pub unsafe trait Alloc { let old_size = layout.size(); if new_size >= old_size { - if let Ok(()) = self.grow_in_place(ptr, layout.clone(), new_size) { + if let Ok(()) = self.grow_in_place(ptr, layout, new_size) { return Ok(ptr); } } else if new_size < old_size { - if let Ok(()) = self.shrink_in_place(ptr, layout.clone(), new_size) { + if let Ok(()) = self.shrink_in_place(ptr, layout, new_size) { return Ok(ptr); } } diff --git a/src/libstd/sys/unix/alloc.rs b/src/libstd/sys/unix/alloc.rs index 2c2dd3b77ea..f47dc92d2de 100644 --- a/src/libstd/sys/unix/alloc.rs +++ b/src/libstd/sys/unix/alloc.rs @@ -29,7 +29,7 @@ unsafe impl GlobalAlloc for System { if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() { libc::calloc(layout.size(), 1) as *mut u8 } else { - let ptr = self.alloc(layout.clone()); + let ptr = self.alloc(layout); if !ptr.is_null() { ptr::write_bytes(ptr, 0, layout.size()); } -- cgit 1.4.1-3-g733a5 From 124f6ef7cdea1083b0cbe0371e3f7fbe1152a9d1 Mon Sep 17 00:00:00 2001 From: Mateusz Mikuła Date: Thu, 18 Jul 2019 14:22:22 +0200 Subject: Fix clippy::len_zero warnings --- src/liballoc/collections/btree/map.rs | 6 +++--- src/libcore/str/lossy.rs | 4 ++-- src/libstd/io/mod.rs | 4 ++-- src/libstd/sys/unix/process/process_unix.rs | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs index d466948a017..8bd1a3f44a3 100644 --- a/src/liballoc/collections/btree/map.rs +++ b/src/liballoc/collections/btree/map.rs @@ -200,7 +200,7 @@ impl Clone for BTreeMap { } } - if self.len() == 0 { + if self.is_empty() { // Ideally we'd call `BTreeMap::new` here, but that has the `K: // Ord` constraint, which this method lacks. BTreeMap { @@ -759,12 +759,12 @@ impl BTreeMap { #[stable(feature = "btree_append", since = "1.11.0")] pub fn append(&mut self, other: &mut Self) { // Do we have to append anything at all? - if other.len() == 0 { + if other.is_empty() { return; } // We can just swap `self` and `other` if `self` is empty. - if self.len() == 0 { + if self.is_empty() { mem::swap(self, other); return; } diff --git a/src/libcore/str/lossy.rs b/src/libcore/str/lossy.rs index b291579553a..e8f747f1a67 100644 --- a/src/libcore/str/lossy.rs +++ b/src/libcore/str/lossy.rs @@ -46,7 +46,7 @@ impl<'a> Iterator for Utf8LossyChunksIter<'a> { type Item = Utf8LossyChunk<'a>; fn next(&mut self) -> Option> { - if self.source.len() == 0 { + if self.source.is_empty() { return None; } @@ -141,7 +141,7 @@ impl fmt::Display for Utf8Lossy { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { // If we're the empty string then our iterator won't actually yield // anything, so perform the formatting manually - if self.bytes.len() == 0 { + if self.bytes.is_empty() { return "".fmt(f) } diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index a8d4d1181aa..3fbe9f3125f 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -1923,7 +1923,7 @@ impl Read for Chain { fn read(&mut self, buf: &mut [u8]) -> Result { if !self.done_first { match self.first.read(buf)? { - 0 if buf.len() != 0 => self.done_first = true, + 0 if !buf.is_empty() => self.done_first = true, n => return Ok(n), } } @@ -1955,7 +1955,7 @@ impl BufRead for Chain { fn fill_buf(&mut self) -> Result<&[u8]> { if !self.done_first { match self.first.fill_buf()? { - buf if buf.len() == 0 => { self.done_first = true; } + buf if buf.is_empty() => { self.done_first = true; } buf => return Ok(buf), } } diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs index be38a1334ec..fc1e33137c8 100644 --- a/src/libstd/sys/unix/process/process_unix.rs +++ b/src/libstd/sys/unix/process/process_unix.rs @@ -277,7 +277,7 @@ impl Command { if self.get_gid().is_some() || self.get_uid().is_some() || self.env_saw_path() || - self.get_closures().len() != 0 { + !self.get_closures().is_empty() { return Ok(None) } -- cgit 1.4.1-3-g733a5 From e074db764a0f25af073cb3f472d39a86e6fa7f39 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 19 Jul 2019 10:44:11 +0200 Subject: use const array repeat expressions for uninit_array --- src/liballoc/collections/btree/node.rs | 6 +++--- src/liballoc/lib.rs | 1 + src/libcore/fmt/num.rs | 4 ++-- src/libcore/lib.rs | 1 + src/libcore/macros.rs | 23 ++++++++++++++++++++--- src/libcore/mem/maybe_uninit.rs | 1 + src/libcore/slice/sort.rs | 4 ++-- 7 files changed, 30 insertions(+), 10 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/collections/btree/node.rs b/src/liballoc/collections/btree/node.rs index 7cf077d61d6..e067096f0c7 100644 --- a/src/liballoc/collections/btree/node.rs +++ b/src/liballoc/collections/btree/node.rs @@ -106,8 +106,8 @@ impl LeafNode { LeafNode { // As a general policy, we leave fields uninitialized if they can be, as this should // be both slightly faster and easier to track in Valgrind. - keys: uninitialized_array![_; CAPACITY], - vals: uninitialized_array![_; CAPACITY], + keys: uninit_array![_; CAPACITY], + vals: uninit_array![_; CAPACITY], parent: ptr::null(), parent_idx: MaybeUninit::uninit(), len: 0 @@ -159,7 +159,7 @@ impl InternalNode { unsafe fn new() -> Self { InternalNode { data: LeafNode::new(), - edges: uninitialized_array![_; 2*B], + edges: uninit_array![_; 2*B], } } } diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 2e48825e81c..68df0137ee6 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -77,6 +77,7 @@ #![feature(box_syntax)] #![feature(cfg_target_has_atomic)] #![feature(coerce_unsized)] +#![cfg_attr(not(bootstrap), feature(const_in_array_repeat_expressions))] #![feature(dispatch_from_dyn)] #![feature(core_intrinsics)] #![feature(dropck_eyepatch)] diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs index f9b4c26496c..e2d00e654dd 100644 --- a/src/libcore/fmt/num.rs +++ b/src/libcore/fmt/num.rs @@ -51,7 +51,7 @@ trait GenericRadix { // characters for a base 2 number. let zero = T::zero(); let is_nonnegative = x >= zero; - let mut buf = uninitialized_array![u8; 128]; + let mut buf = uninit_array![u8; 128]; let mut curr = buf.len(); let base = T::from_u8(Self::BASE); if is_nonnegative { @@ -189,7 +189,7 @@ static DEC_DIGITS_LUT: &[u8; 200] = macro_rules! impl_Display { ($($t:ident),* as $u:ident via $conv_fn:ident named $name:ident) => { fn $name(mut n: $u, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut buf = uninitialized_array![u8; 39]; + let mut buf = uninit_array![u8; 39]; let mut curr = buf.len() as isize; let buf_ptr = MaybeUninit::first_ptr_mut(&mut buf); let lut_ptr = DEC_DIGITS_LUT.as_ptr(); diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index fe149d634e2..8d3c42cbf35 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -75,6 +75,7 @@ #![feature(const_fn)] #![feature(const_fn_union)] #![cfg_attr(not(bootstrap), feature(const_generics))] +#![cfg_attr(not(bootstrap), feature(const_in_array_repeat_expressions))] #![feature(custom_inner_attributes)] #![feature(decl_macro)] #![feature(doc_cfg)] diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index 293a2dd9492..9855c5fb9c3 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -626,20 +626,37 @@ macro_rules! todo { /// Creates an array of [`MaybeUninit`]. /// /// This macro constructs an uninitialized array of the type `[MaybeUninit; N]`. +/// It exists solely because bootstrap does not yet support const array-init expressions. /// /// [`MaybeUninit`]: mem/union.MaybeUninit.html +// FIXME: Remove both versions of this macro once bootstrap is 1.38. #[macro_export] #[unstable(feature = "maybe_uninit_array", issue = "53491")] -macro_rules! uninitialized_array { +#[cfg(bootstrap)] +macro_rules! uninit_array { // This `assume_init` is safe because an array of `MaybeUninit` does not // require initialization. - // FIXME(#49147): Could be replaced by an array initializer, once those can - // be any const expression. ($t:ty; $size:expr) => (unsafe { MaybeUninit::<[MaybeUninit<$t>; $size]>::uninit().assume_init() }); } +/// Creates an array of [`MaybeUninit`]. +/// +/// This macro constructs an uninitialized array of the type `[MaybeUninit; N]`. +/// It exists solely because bootstrap does not yet support const array-init expressions. +/// +/// [`MaybeUninit`]: mem/union.MaybeUninit.html +// FIXME: Just inline this version of the macro once bootstrap is 1.38. +#[macro_export] +#[unstable(feature = "maybe_uninit_array", issue = "53491")] +#[cfg(not(bootstrap))] +macro_rules! uninit_array { + ($t:ty; $size:expr) => ( + [MaybeUninit::<$t>::uninit(); $size] + ); +} + /// Built-in macros to the compiler itself. /// /// These macros do not have any corresponding definition with a `macro_rules!` diff --git a/src/libcore/mem/maybe_uninit.rs b/src/libcore/mem/maybe_uninit.rs index f6f7ccffdb0..1c69e7f90f6 100644 --- a/src/libcore/mem/maybe_uninit.rs +++ b/src/libcore/mem/maybe_uninit.rs @@ -248,6 +248,7 @@ impl MaybeUninit { /// [type]: union.MaybeUninit.html #[stable(feature = "maybe_uninit", since = "1.36.0")] #[inline(always)] + #[rustc_promotable] pub const fn uninit() -> MaybeUninit { MaybeUninit { uninit: () } } diff --git a/src/libcore/slice/sort.rs b/src/libcore/slice/sort.rs index c293b190018..fbf9caeaece 100644 --- a/src/libcore/slice/sort.rs +++ b/src/libcore/slice/sort.rs @@ -216,14 +216,14 @@ fn partition_in_blocks(v: &mut [T], pivot: &T, is_less: &mut F) -> usize let mut block_l = BLOCK; let mut start_l = ptr::null_mut(); let mut end_l = ptr::null_mut(); - let mut offsets_l: [MaybeUninit; BLOCK] = uninitialized_array![u8; BLOCK]; + let mut offsets_l: [MaybeUninit; BLOCK] = uninit_array![u8; BLOCK]; // The current block on the right side (from `r.sub(block_r)` to `r`). let mut r = unsafe { l.add(v.len()) }; let mut block_r = BLOCK; let mut start_r = ptr::null_mut(); let mut end_r = ptr::null_mut(); - let mut offsets_r: [MaybeUninit; BLOCK] = uninitialized_array![u8; BLOCK]; + let mut offsets_r: [MaybeUninit; BLOCK] = uninit_array![u8; BLOCK]; // FIXME: When we get VLAs, try creating one array of length `min(v.len(), 2 * BLOCK)` rather // than two fixed-size arrays of length `BLOCK`. VLAs might be more cache-efficient. -- cgit 1.4.1-3-g733a5 From 4b47e78a16524ed4878bfffaaf60c32bb18d88ae Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 21 Jul 2019 12:02:28 +0200 Subject: use a const to hack around promotion limitations --- src/liballoc/lib.rs | 1 + src/libcore/macros.rs | 2 +- src/libcore/mem/maybe_uninit.rs | 9 ++++++++- 3 files changed, 10 insertions(+), 2 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 68df0137ee6..dbc1f3b47c8 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -85,6 +85,7 @@ #![feature(fmt_internals)] #![feature(fn_traits)] #![feature(fundamental)] +#![feature(internal_uninit_const)] #![feature(lang_items)] #![feature(libc)] #![feature(nll)] diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index 9855c5fb9c3..296bb43f9fa 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -653,7 +653,7 @@ macro_rules! uninit_array { #[cfg(not(bootstrap))] macro_rules! uninit_array { ($t:ty; $size:expr) => ( - [MaybeUninit::<$t>::uninit(); $size] + [MaybeUninit::<$t>::UNINIT; $size] ); } diff --git a/src/libcore/mem/maybe_uninit.rs b/src/libcore/mem/maybe_uninit.rs index 1c69e7f90f6..9ce89f9669d 100644 --- a/src/libcore/mem/maybe_uninit.rs +++ b/src/libcore/mem/maybe_uninit.rs @@ -248,11 +248,18 @@ impl MaybeUninit { /// [type]: union.MaybeUninit.html #[stable(feature = "maybe_uninit", since = "1.36.0")] #[inline(always)] - #[rustc_promotable] pub const fn uninit() -> MaybeUninit { MaybeUninit { uninit: () } } + /// A promotable constant, equivalent to `uninit()`. + #[unstable( + feature = "internal_uninit_const", + issue = "0", + reason = "hack to work around promotability", + )] + pub const UNINIT: Self = Self::uninit(); + /// Creates a new `MaybeUninit` in an uninitialized state, with the memory being /// filled with `0` bytes. It depends on `T` whether that already makes for /// proper initialization. For example, `MaybeUninit::zeroed()` is initialized, -- cgit 1.4.1-3-g733a5 From e2ddb85416da4ca3235c67c99456e9cb4a498f55 Mon Sep 17 00:00:00 2001 From: Tomasz Różański Date: Sun, 21 Jul 2019 21:07:38 +0200 Subject: Change wrong variable name. --- src/liballoc/collections/btree/map.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs index d466948a017..7cf779b3e72 100644 --- a/src/liballoc/collections/btree/map.rs +++ b/src/liballoc/collections/btree/map.rs @@ -75,10 +75,10 @@ use Entry::*; /// /// // look up the values associated with some keys. /// let to_find = ["Up!", "Office Space"]; -/// for book in &to_find { -/// match movie_reviews.get(book) { -/// Some(review) => println!("{}: {}", book, review), -/// None => println!("{} is unreviewed.", book) +/// for movie in &to_find { +/// match movie_reviews.get(movie) { +/// Some(review) => println!("{}: {}", movie, review), +/// None => println!("{} is unreviewed.", movie) /// } /// } /// -- cgit 1.4.1-3-g733a5 From 8b57f689d54ff70d13e500e4d6e40c67b21e149e Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 28 Jul 2019 05:06:20 +0200 Subject: Use const generics for some Vec/CCow impls. --- src/liballoc/lib.rs | 2 ++ src/liballoc/vec.rs | 56 ++++++++++++++++++++++------------------------------- 2 files changed, 25 insertions(+), 33 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index dbc1f3b47c8..e42d6434725 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -78,6 +78,8 @@ #![feature(cfg_target_has_atomic)] #![feature(coerce_unsized)] #![cfg_attr(not(bootstrap), feature(const_in_array_repeat_expressions))] +#![feature(const_generic_impls_guard)] +#![feature(const_generics)] #![feature(dispatch_from_dyn)] #![feature(core_intrinsics)] #![feature(dropck_eyepatch)] diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index c076584cc38..dac04e4e624 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -56,6 +56,7 @@ #![stable(feature = "rust1", since = "1.0.0")] +use core::array::LengthAtMost32; use core::cmp::{self, Ordering}; use core::fmt; use core::hash::{self, Hash}; @@ -2171,47 +2172,36 @@ impl<'a, T: 'a + Copy> Extend<&'a T> for Vec { } macro_rules! __impl_slice_eq1 { - ($Lhs: ty, $Rhs: ty) => { - __impl_slice_eq1! { $Lhs, $Rhs, Sized } - }; - ($Lhs: ty, $Rhs: ty, $Bound: ident) => { + ([$($vars:tt)*] $lhs:ty, $rhs:ty, $($constraints:tt)*) => { #[stable(feature = "rust1", since = "1.0.0")] - impl<'a, 'b, A: $Bound, B> PartialEq<$Rhs> for $Lhs where A: PartialEq { + impl PartialEq<$rhs> for $lhs + where + A: PartialEq, + $($constraints)* + { #[inline] - fn eq(&self, other: &$Rhs) -> bool { self[..] == other[..] } + fn eq(&self, other: &$rhs) -> bool { self[..] == other[..] } #[inline] - fn ne(&self, other: &$Rhs) -> bool { self[..] != other[..] } + fn ne(&self, other: &$rhs) -> bool { self[..] != other[..] } } } } -__impl_slice_eq1! { Vec, Vec } -__impl_slice_eq1! { Vec, &'b [B] } -__impl_slice_eq1! { Vec, &'b mut [B] } -__impl_slice_eq1! { Cow<'a, [A]>, &'b [B], Clone } -__impl_slice_eq1! { Cow<'a, [A]>, &'b mut [B], Clone } -__impl_slice_eq1! { Cow<'a, [A]>, Vec, Clone } +__impl_slice_eq1! { [] Vec, Vec, } +__impl_slice_eq1! { [] Vec, &[B], } +__impl_slice_eq1! { [] Vec, &mut [B], } +__impl_slice_eq1! { [] Cow<'_, [A]>, &[B], A: Clone } +__impl_slice_eq1! { [] Cow<'_, [A]>, &mut [B], A: Clone } +__impl_slice_eq1! { [] Cow<'_, [A]>, Vec, A: Clone } +__impl_slice_eq1! { [const N: usize] Vec, [B; N], [B; N]: LengthAtMost32 } +__impl_slice_eq1! { [const N: usize] Vec, &[B; N], [B; N]: LengthAtMost32 } -macro_rules! array_impls { - ($($N: expr)+) => { - $( - // NOTE: some less important impls are omitted to reduce code bloat - __impl_slice_eq1! { Vec, [B; $N] } - __impl_slice_eq1! { Vec, &'b [B; $N] } - // __impl_slice_eq1! { Vec, &'b mut [B; $N] } - // __impl_slice_eq1! { Cow<'a, [A]>, [B; $N], Clone } - // __impl_slice_eq1! { Cow<'a, [A]>, &'b [B; $N], Clone } - // __impl_slice_eq1! { Cow<'a, [A]>, &'b mut [B; $N], Clone } - )+ - } -} - -array_impls! { - 0 1 2 3 4 5 6 7 8 9 - 10 11 12 13 14 15 16 17 18 19 - 20 21 22 23 24 25 26 27 28 29 - 30 31 32 -} +// NOTE: some less important impls are omitted to reduce code bloat +// FIXME(Centril): Reconsider this? +//__impl_slice_eq1! { [const N: usize] Vec, &mut [B; N], [B; N]: LengthAtMost32 } +//__impl_slice_eq1! { [const N: usize] Cow<'a, [A]>, [B; N], [B; N]: LengthAtMost32 } +//__impl_slice_eq1! { [const N: usize] Cow<'a, [A]>, &[B; N], [B; N]: LengthAtMost32 } +//__impl_slice_eq1! { [const N: usize] Cow<'a, [A]>, &mut [B; N], [B; N]: LengthAtMost32 } /// Implements comparison of vectors, lexicographically. #[stable(feature = "rust1", since = "1.0.0")] -- cgit 1.4.1-3-g733a5 From 744ec8809dbdbee03422e2456f8caf549c69656d Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 28 Jul 2019 05:12:16 +0200 Subject: Use const generics for some VecDeque impls. --- src/liballoc/collections/vec_deque.rs | 40 ++++++++++++----------------------- 1 file changed, 14 insertions(+), 26 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index d149f742b01..495165f7786 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -9,6 +9,7 @@ #![stable(feature = "rust1", since = "1.0.0")] +use core::array::LengthAtMost32; use core::cmp::{self, Ordering}; use core::fmt; use core::iter::{repeat_with, FromIterator, FusedIterator}; @@ -2571,13 +2572,14 @@ impl PartialEq for VecDeque { impl Eq for VecDeque {} macro_rules! __impl_slice_eq1 { - ($Lhs: ty, $Rhs: ty) => { - __impl_slice_eq1! { $Lhs, $Rhs, Sized } - }; - ($Lhs: ty, $Rhs: ty, $Bound: ident) => { + ([$($vars:tt)*] $lhs:ty, $rhs:ty, $($constraints:tt)*) => { #[stable(feature = "vec_deque_partial_eq_slice", since = "1.17.0")] - impl PartialEq<$Rhs> for $Lhs where A: PartialEq { - fn eq(&self, other: &$Rhs) -> bool { + impl PartialEq<$rhs> for $lhs + where + A: PartialEq, + $($constraints)* + { + fn eq(&self, other: &$rhs) -> bool { if self.len() != other.len() { return false; } @@ -2589,26 +2591,12 @@ macro_rules! __impl_slice_eq1 { } } -__impl_slice_eq1! { VecDeque, Vec } -__impl_slice_eq1! { VecDeque, &[B] } -__impl_slice_eq1! { VecDeque, &mut [B] } - -macro_rules! array_impls { - ($($N: expr)+) => { - $( - __impl_slice_eq1! { VecDeque, [B; $N] } - __impl_slice_eq1! { VecDeque, &[B; $N] } - __impl_slice_eq1! { VecDeque, &mut [B; $N] } - )+ - } -} - -array_impls! { - 0 1 2 3 4 5 6 7 8 9 - 10 11 12 13 14 15 16 17 18 19 - 20 21 22 23 24 25 26 27 28 29 - 30 31 32 -} +__impl_slice_eq1! { [] VecDeque, Vec, } +__impl_slice_eq1! { [] VecDeque, &[B], } +__impl_slice_eq1! { [] VecDeque, &mut [B], } +__impl_slice_eq1! { [const N: usize] VecDeque, [B; N], [B; N]: LengthAtMost32 } +__impl_slice_eq1! { [const N: usize] VecDeque, &[B; N], [B; N]: LengthAtMost32 } +__impl_slice_eq1! { [const N: usize] VecDeque, &mut [B; N], [B; N]: LengthAtMost32 } #[stable(feature = "rust1", since = "1.0.0")] impl PartialOrd for VecDeque { -- cgit 1.4.1-3-g733a5 From 434152157f9d73ad1899fb8da3a61aed6f8a46d6 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 23 Jul 2019 20:34:17 +0300 Subject: Remove lint annotations in specific crates that are already enforced by rustbuild Remove some random unnecessary lint `allow`s --- src/bootstrap/bin/main.rs | 3 +- src/bootstrap/bin/rustc.rs | 3 +- src/bootstrap/bin/rustdoc.rs | 3 +- src/bootstrap/lib.rs | 5 +- src/build_helper/lib.rs | 3 +- src/liballoc/lib.rs | 2 - src/liballoc/tests/lib.rs | 1 - src/libarena/lib.rs | 1 - src/libcore/lib.rs | 2 - src/libcore/tests/lib.rs | 1 - src/libfmt_macros/lib.rs | 1 - src/libgraphviz/lib.rs | 2 - src/libpanic_abort/lib.rs | 1 - src/libpanic_unwind/lib.rs | 2 - src/libproc_macro/lib.rs | 2 - src/libprofiler_builtins/lib.rs | 1 - src/librustc/error_codes.rs | 2 - src/librustc/lib.rs | 4 +- src/librustc/session/config.rs | 2 +- src/librustc/ty/query/job.rs | 3 +- src/librustc_apfloat/lib.rs | 1 - src/librustc_asan/lib.rs | 2 - src/librustc_ast_borrowck/lib.rs | 1 - src/librustc_codegen_llvm/error_codes.rs | 2 - src/librustc_codegen_llvm/intrinsic.rs | 2 - src/librustc_codegen_llvm/lib.rs | 2 - src/librustc_codegen_llvm/llvm/ffi.rs | 3 + src/librustc_codegen_llvm/llvm/mod.rs | 3 - src/librustc_codegen_llvm/type_.rs | 2 - src/librustc_codegen_ssa/base.rs | 6 - src/librustc_codegen_ssa/error_codes.rs | 2 - src/librustc_codegen_ssa/lib.rs | 3 - src/librustc_codegen_utils/codegen_backend.rs | 2 - src/librustc_codegen_utils/lib.rs | 2 - src/librustc_data_structures/lib.rs | 1 - src/librustc_driver/lib.rs | 1 - src/librustc_errors/lib.rs | 2 - src/librustc_fs_util/lib.rs | 2 - src/librustc_incremental/lib.rs | 1 - src/librustc_interface/interface.rs | 1 - src/librustc_interface/lib.rs | 3 - src/librustc_interface/passes.rs | 19 +- src/librustc_interface/queries.rs | 16 +- src/librustc_lint/lib.rs | 1 - src/librustc_llvm/lib.rs | 1 - src/librustc_lsan/lib.rs | 2 - src/librustc_macros/src/lib.rs | 1 - src/librustc_metadata/error_codes.rs | 2 - src/librustc_metadata/lib.rs | 1 - .../borrow_check/nll/type_check/mod.rs | 2 - src/librustc_mir/error_codes.rs | 2 - src/librustc_mir/lib.rs | 1 - src/librustc_msan/lib.rs | 2 - src/librustc_passes/error_codes.rs | 2 - src/librustc_passes/lib.rs | 1 - src/librustc_plugin/error_codes.rs | 2 - src/librustc_plugin/lib.rs | 2 - src/librustc_privacy/error_codes.rs | 2 - src/librustc_privacy/lib.rs | 1 - src/librustc_resolve/error_codes.rs | 2 - src/librustc_resolve/lib.rs | 1 - src/librustc_save_analysis/lib.rs | 2 - src/librustc_target/abi/call/hexagon.rs | 2 - src/librustc_target/lib.rs | 1 - src/librustc_traits/lib.rs | 1 - src/librustc_tsan/lib.rs | 2 - src/librustc_typeck/error_codes.rs | 2 - src/librustc_typeck/lib.rs | 1 - src/librustdoc/lib.rs | 1 - src/libserialize/lib.rs | 2 - src/libstd/build.rs | 2 - src/libstd/lib.rs | 2 - src/libsyntax/diagnostics/plugin.rs | 3 +- src/libsyntax/error_codes.rs | 2 - src/libsyntax/json.rs | 1 - src/libsyntax/lib.rs | 1 - src/libsyntax_ext/error_codes.rs | 2 - src/libsyntax_ext/lib.rs | 1 - src/libsyntax_pos/lib.rs | 1 - src/libterm/lib.rs | 2 - src/libtest/lib.rs | 1 - src/libunwind/lib.rs | 2 - src/test/run-make-fulldeps/issue-19371/foo.rs | 3 +- src/test/ui-fulldeps/plugin-as-extern-crate.rs | 1 - src/test/ui-fulldeps/plugin-as-extern-crate.stderr | 2 +- src/test/ui/enable-unstable-lib-feature.rs | 1 - src/test/ui/enable-unstable-lib-feature.stderr | 2 +- src/test/ui/error-codes/E0254.rs | 2 +- src/test/ui/error-codes/E0259.rs | 1 - src/test/ui/error-codes/E0259.stderr | 2 +- src/test/ui/error-codes/E0260.rs | 2 - src/test/ui/error-codes/E0260.stderr | 2 +- src/test/ui/issues/issue-36881.rs | 1 - src/test/ui/issues/issue-36881.stderr | 2 +- src/test/ui/lint/lint-stability-deprecated.rs | 1 - src/test/ui/lint/lint-stability-deprecated.stderr | 210 ++++++++++----------- src/test/ui/macros/macro-use-bad-args-1.rs | 1 - src/test/ui/macros/macro-use-bad-args-1.stderr | 2 +- src/test/ui/macros/macro-use-bad-args-2.rs | 1 - src/test/ui/macros/macro-use-bad-args-2.stderr | 2 +- src/test/ui/no-std-inject.rs | 1 - src/test/ui/no-std-inject.stderr | 2 +- ...esolve-conflict-extern-crate-vs-extern-crate.rs | 1 - ...ve-conflict-extern-crate-vs-extern-crate.stderr | 4 - src/test/ui/resolve_self_super_hint.rs | 2 - src/test/ui/resolve_self_super_hint.stderr | 8 +- src/tools/build-manifest/src/main.rs | 2 - src/tools/cargotest/main.rs | 2 - src/tools/compiletest/src/main.rs | 1 - src/tools/error_index_generator/main.rs | 2 - src/tools/linkchecker/main.rs | 2 - src/tools/remote-test-client/src/main.rs | 2 - src/tools/remote-test-server/src/main.rs | 2 - src/tools/rustbook/src/main.rs | 2 - src/tools/rustc-std-workspace-core/lib.rs | 1 - src/tools/rustdoc-themes/main.rs | 2 - src/tools/rustdoc/main.rs | 2 - src/tools/tidy/src/main.rs | 2 - src/tools/unstable-book-gen/src/main.rs | 5 - 119 files changed, 146 insertions(+), 322 deletions(-) (limited to 'src/liballoc') diff --git a/src/bootstrap/bin/main.rs b/src/bootstrap/bin/main.rs index 0732cb83f39..da35c971f97 100644 --- a/src/bootstrap/bin/main.rs +++ b/src/bootstrap/bin/main.rs @@ -5,7 +5,8 @@ //! parent directory, and otherwise documentation can be found throughout the `build` //! directory in each respective module. -#![deny(warnings)] +// NO-RUSTC-WRAPPER +#![deny(warnings, rust_2018_idioms)] use std::env; diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs index a9225f2870f..3888d0ef627 100644 --- a/src/bootstrap/bin/rustc.rs +++ b/src/bootstrap/bin/rustc.rs @@ -15,7 +15,8 @@ //! switching compilers for the bootstrap and for build scripts will probably //! never get replaced. -#![deny(warnings)] +// NO-RUSTC-WRAPPER +#![deny(warnings, rust_2018_idioms)] use std::env; use std::ffi::OsString; diff --git a/src/bootstrap/bin/rustdoc.rs b/src/bootstrap/bin/rustdoc.rs index 1c9f6e1ab28..057daaf2dc4 100644 --- a/src/bootstrap/bin/rustdoc.rs +++ b/src/bootstrap/bin/rustdoc.rs @@ -2,7 +2,8 @@ //! //! See comments in `src/bootstrap/rustc.rs` for more information. -#![deny(warnings)] +// NO-RUSTC-WRAPPER +#![deny(warnings, rust_2018_idioms)] use std::env; use std::process::Command; diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 7011b7f1664..0f7e4f6e977 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -103,8 +103,9 @@ //! More documentation can be found in each respective module below, and you can //! also check out the `src/bootstrap/README.md` file for more information. -#![deny(rust_2018_idioms)] -#![deny(warnings)] +// NO-RUSTC-WRAPPER +#![deny(warnings, rust_2018_idioms)] + #![feature(core_intrinsics)] #![feature(drain_filter)] diff --git a/src/build_helper/lib.rs b/src/build_helper/lib.rs index 8b00c1d81b0..f9371e878ef 100644 --- a/src/build_helper/lib.rs +++ b/src/build_helper/lib.rs @@ -1,4 +1,5 @@ -#![deny(rust_2018_idioms)] +// NO-RUSTC-WRAPPER +#![deny(warnings, rust_2018_idioms)] use std::fs::File; use std::path::{Path, PathBuf}; diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index e42d6434725..c0f345443b9 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -62,8 +62,6 @@ #![warn(missing_docs)] #![warn(missing_debug_implementations)] #![deny(intra_doc_link_resolution_failure)] // rustdoc is run without -D warnings - -#![deny(rust_2018_idioms)] #![allow(explicit_outlives_requirements)] #![cfg_attr(not(test), feature(generator_trait))] diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs index 5a43c8e09a2..6d774f3fecd 100644 --- a/src/liballoc/tests/lib.rs +++ b/src/liballoc/tests/lib.rs @@ -8,7 +8,6 @@ #![feature(trusted_len)] #![feature(try_reserve)] #![feature(unboxed_closures)] -#![deny(rust_2018_idioms)] use std::hash::{Hash, Hasher}; use std::collections::hash_map::DefaultHasher; diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index 967b4ad4720..7baec3ed1cf 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -11,7 +11,6 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/", test(no_crate_inject, attr(deny(warnings))))] -#![deny(rust_2018_idioms)] #![deny(unused_lifetimes)] #![feature(core_intrinsics)] diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 2bb941b490e..bdfc1e66fd4 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -62,8 +62,6 @@ #![warn(missing_docs)] #![warn(missing_debug_implementations)] #![deny(intra_doc_link_resolution_failure)] // rustdoc is run without -D warnings - -#![deny(rust_2018_idioms)] #![allow(explicit_outlives_requirements)] #![feature(allow_internal_unstable)] diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 505f8b0a261..a3b108b2e9c 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -32,7 +32,6 @@ #![feature(const_fn)] #![feature(iter_partition_in_place)] #![feature(iter_is_partitioned)] -#![warn(rust_2018_idioms)] extern crate test; diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs index f1c2b1fb871..d673088fe45 100644 --- a/src/libfmt_macros/lib.rs +++ b/src/libfmt_macros/lib.rs @@ -8,7 +8,6 @@ html_playground_url = "https://play.rust-lang.org/", test(attr(deny(warnings))))] -#![deny(rust_2018_idioms)] #![deny(unused_lifetimes)] #![feature(nll)] diff --git a/src/libgraphviz/lib.rs b/src/libgraphviz/lib.rs index a34e4fb89ff..bb996e5f906 100644 --- a/src/libgraphviz/lib.rs +++ b/src/libgraphviz/lib.rs @@ -274,8 +274,6 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/", test(attr(allow(unused_variables), deny(warnings))))] -#![deny(rust_2018_idioms)] - #![feature(nll)] use LabelText::*; diff --git a/src/libpanic_abort/lib.rs b/src/libpanic_abort/lib.rs index 8c20a6ea55a..ee9dd858ef4 100644 --- a/src/libpanic_abort/lib.rs +++ b/src/libpanic_abort/lib.rs @@ -10,7 +10,6 @@ #![panic_runtime] #![allow(unused_features)] -#![deny(rust_2018_idioms)] #![feature(core_intrinsics)] #![feature(libc)] diff --git a/src/libpanic_unwind/lib.rs b/src/libpanic_unwind/lib.rs index 2bb9ce6ab22..06e6e768f45 100644 --- a/src/libpanic_unwind/lib.rs +++ b/src/libpanic_unwind/lib.rs @@ -17,8 +17,6 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/", issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/")] -#![deny(rust_2018_idioms)] - #![feature(core_intrinsics)] #![feature(lang_items)] #![feature(libc)] diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index 2c097238b95..c0f7714ca21 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -17,8 +17,6 @@ test(no_crate_inject, attr(deny(warnings))), test(attr(allow(dead_code, deprecated, unused_variables, unused_mut))))] -#![deny(rust_2018_idioms)] - #![feature(nll)] #![feature(staged_api)] #![feature(const_fn)] diff --git a/src/libprofiler_builtins/lib.rs b/src/libprofiler_builtins/lib.rs index 2ce1a110b44..0d12ba01c87 100644 --- a/src/libprofiler_builtins/lib.rs +++ b/src/libprofiler_builtins/lib.rs @@ -7,4 +7,3 @@ #![allow(unused_features)] #![feature(nll)] #![feature(staged_api)] -#![deny(rust_2018_idioms)] diff --git a/src/librustc/error_codes.rs b/src/librustc/error_codes.rs index 655028324e1..1edadbd5bae 100644 --- a/src/librustc/error_codes.rs +++ b/src/librustc/error_codes.rs @@ -1,5 +1,3 @@ -#![allow(non_snake_case)] - // Error messages for EXXXX errors. // Each message should start and end with a new line, and be wrapped to 80 characters. // In vim you can `:set tw=80` and use `gq` to wrap paragraphs. Use `:set tw=0` to disable. diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 79f60778d3c..9957b173116 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -28,7 +28,6 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] -#![deny(rust_2018_idioms)] #![deny(unused_lifetimes)] #![feature(arbitrary_self_types)] @@ -81,8 +80,7 @@ extern crate libc; // Use the test crate here so we depend on getopts through it. This allow tools to link to both // librustc_driver and libtest. -#[allow(unused_extern_crates)] -extern crate test; +extern crate test as _; #[macro_use] mod macros; diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 74653d4fbda..886915db449 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1628,7 +1628,7 @@ impl RustcOptGroup { // *unstable* options, i.e., options that are only enabled when the // user also passes the `-Z unstable-options` debugging flag. mod opt { - // The `fn opt_u` etc below are written so that we can use them + // The `fn flag*` etc below are written so that we can use them // in the future; do not warn about them not being used right now. #![allow(dead_code)] diff --git a/src/librustc/ty/query/job.rs b/src/librustc/ty/query/job.rs index dcc467a61b5..c4e798f7461 100644 --- a/src/librustc/ty/query/job.rs +++ b/src/librustc/ty/query/job.rs @@ -1,4 +1,4 @@ -#![allow(warnings)] +#![allow(unused_imports)] // `cfg(parallel_compiler)` use std::mem; use std::process; @@ -138,6 +138,7 @@ impl<'tcx> QueryJob<'tcx> { self.latch.set(); } + #[cfg(parallel_compiler)] fn as_ptr(&self) -> *const QueryJob<'tcx> { self as *const _ } diff --git a/src/librustc_apfloat/lib.rs b/src/librustc_apfloat/lib.rs index ceade5d2788..9e6d5a6f624 100644 --- a/src/librustc_apfloat/lib.rs +++ b/src/librustc_apfloat/lib.rs @@ -32,7 +32,6 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![forbid(unsafe_code)] -#![deny(rust_2018_idioms)] #![feature(nll)] diff --git a/src/librustc_asan/lib.rs b/src/librustc_asan/lib.rs index 3bdb86d313d..d6c8e54c18d 100644 --- a/src/librustc_asan/lib.rs +++ b/src/librustc_asan/lib.rs @@ -6,5 +6,3 @@ #![unstable(feature = "sanitizer_runtime_lib", reason = "internal implementation detail of sanitizers", issue = "0")] - -#![deny(rust_2018_idioms)] diff --git a/src/librustc_ast_borrowck/lib.rs b/src/librustc_ast_borrowck/lib.rs index b857c625ec2..045671e37c0 100644 --- a/src/librustc_ast_borrowck/lib.rs +++ b/src/librustc_ast_borrowck/lib.rs @@ -1,7 +1,6 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![allow(non_camel_case_types)] -#![deny(rust_2018_idioms)] #![deny(unused_lifetimes)] #![feature(in_band_lifetimes)] diff --git a/src/librustc_codegen_llvm/error_codes.rs b/src/librustc_codegen_llvm/error_codes.rs index 872fa424e4c..c6b5dc03a6f 100644 --- a/src/librustc_codegen_llvm/error_codes.rs +++ b/src/librustc_codegen_llvm/error_codes.rs @@ -1,5 +1,3 @@ -#![allow(non_snake_case)] - register_long_diagnostics! { E0511: r##" diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index 44b3eff2ac5..199170182e4 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -1,5 +1,3 @@ -#![allow(non_upper_case_globals)] - use crate::attributes; use crate::llvm; use crate::llvm_util; diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index 8dd241bd81a..90609d6c85a 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -12,7 +12,6 @@ #![feature(crate_visibility_modifier)] #![feature(extern_types)] #![feature(in_band_lifetimes)] -#![allow(unused_attributes)] #![feature(libc)] #![feature(nll)] #![feature(rustc_diagnostic_macros)] @@ -22,7 +21,6 @@ #![feature(static_nobundle)] #![feature(trusted_len)] #![feature(mem_take)] -#![deny(rust_2018_idioms)] #![deny(unused_lifetimes)] use back::write::{create_target_machine, create_informational_target_machine}; diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index 8c6ea00eb8c..d82e1c68df0 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -1,3 +1,6 @@ +#![allow(non_camel_case_types)] +#![allow(non_upper_case_globals)] + use super::debuginfo::{ DIBuilder, DIDescriptor, DIFile, DILexicalBlock, DISubprogram, DIType, DIBasicType, DIDerivedType, DICompositeType, DIScope, DIVariable, diff --git a/src/librustc_codegen_llvm/llvm/mod.rs b/src/librustc_codegen_llvm/llvm/mod.rs index 543cc912930..57815933af0 100644 --- a/src/librustc_codegen_llvm/llvm/mod.rs +++ b/src/librustc_codegen_llvm/llvm/mod.rs @@ -1,7 +1,4 @@ -#![allow(non_upper_case_globals)] -#![allow(non_camel_case_types)] #![allow(non_snake_case)] -#![deny(bare_trait_objects)] pub use self::IntPredicate::*; pub use self::RealPredicate::*; diff --git a/src/librustc_codegen_llvm/type_.rs b/src/librustc_codegen_llvm/type_.rs index 2c167256ad5..8d6cd0bcf47 100644 --- a/src/librustc_codegen_llvm/type_.rs +++ b/src/librustc_codegen_llvm/type_.rs @@ -1,5 +1,3 @@ -#![allow(non_upper_case_globals)] - pub use crate::llvm::Type; use crate::llvm; diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs index 00471095f2f..fc04976f511 100644 --- a/src/librustc_codegen_ssa/base.rs +++ b/src/librustc_codegen_ssa/base.rs @@ -781,12 +781,6 @@ impl CrateInfo { } } -fn is_codegened_item(tcx: TyCtxt<'_>, id: DefId) -> bool { - let (all_mono_items, _) = - tcx.collect_and_partition_mono_items(LOCAL_CRATE); - all_mono_items.contains(&id) -} - pub fn provide_both(providers: &mut Providers<'_>) { providers.backend_optimization_level = |tcx, cratenum| { let for_speed = match tcx.sess.opts.optimize { diff --git a/src/librustc_codegen_ssa/error_codes.rs b/src/librustc_codegen_ssa/error_codes.rs index e7ef178cfab..8d46dcb7c09 100644 --- a/src/librustc_codegen_ssa/error_codes.rs +++ b/src/librustc_codegen_ssa/error_codes.rs @@ -1,5 +1,3 @@ -#![allow(non_snake_case)] - register_long_diagnostics! { E0668: r##" diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs index d0f4b0a870b..4e2977a011c 100644 --- a/src/librustc_codegen_ssa/lib.rs +++ b/src/librustc_codegen_ssa/lib.rs @@ -11,9 +11,6 @@ #![feature(nll)] #![feature(trusted_len)] #![feature(mem_take)] -#![allow(unused_attributes)] -#![allow(dead_code)] -#![deny(rust_2018_idioms)] #![deny(unused_lifetimes)] #![recursion_limit="256"] diff --git a/src/librustc_codegen_utils/codegen_backend.rs b/src/librustc_codegen_utils/codegen_backend.rs index 7a7a50a25fa..262cfb1658e 100644 --- a/src/librustc_codegen_utils/codegen_backend.rs +++ b/src/librustc_codegen_utils/codegen_backend.rs @@ -5,8 +5,6 @@ //! This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] -#![deny(warnings)] -#![feature(box_syntax)] use std::any::Any; use std::sync::mpsc; diff --git a/src/librustc_codegen_utils/lib.rs b/src/librustc_codegen_utils/lib.rs index f38b672afd9..e3fafc2f2cd 100644 --- a/src/librustc_codegen_utils/lib.rs +++ b/src/librustc_codegen_utils/lib.rs @@ -10,13 +10,11 @@ #![feature(core_intrinsics)] #![feature(never_type)] #![feature(nll)] -#![allow(unused_attributes)] #![feature(rustc_diagnostic_macros)] #![feature(in_band_lifetimes)] #![recursion_limit="256"] -#![deny(rust_2018_idioms)] #![deny(unused_lifetimes)] #[macro_use] diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index 3047119029a..bb27637912b 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -26,7 +26,6 @@ #![cfg_attr(unix, feature(libc))] #![cfg_attr(test, feature(test))] -#![deny(rust_2018_idioms)] #![cfg_attr(not(bootstrap), allow(rustc::default_hash_types))] #[macro_use] diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index c139be07aa1..66739761ef0 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -16,7 +16,6 @@ #![recursion_limit="256"] -#![deny(rust_2018_idioms)] #![deny(unused_lifetimes)] pub extern crate getopts; diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 0a6c02c0ca6..f252d0573dc 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -5,11 +5,9 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![feature(crate_visibility_modifier)] -#![allow(unused_attributes)] #![cfg_attr(unix, feature(libc))] #![feature(nll)] #![feature(optin_builtin_traits)] -#![deny(rust_2018_idioms)] #![deny(unused_lifetimes)] pub use emitter::ColorConfig; diff --git a/src/librustc_fs_util/lib.rs b/src/librustc_fs_util/lib.rs index ce63bcafd79..eaf08d76b99 100644 --- a/src/librustc_fs_util/lib.rs +++ b/src/librustc_fs_util/lib.rs @@ -1,5 +1,3 @@ -#![deny(rust_2018_idioms)] - use std::path::{Path, PathBuf}; use std::ffi::CString; use std::fs; diff --git a/src/librustc_incremental/lib.rs b/src/librustc_incremental/lib.rs index 55aba7caa9d..0b5eb41605b 100644 --- a/src/librustc_incremental/lib.rs +++ b/src/librustc_incremental/lib.rs @@ -8,7 +8,6 @@ #![recursion_limit="256"] -#![deny(rust_2018_idioms)] #![deny(unused_lifetimes)] #[macro_use] extern crate rustc; diff --git a/src/librustc_interface/interface.rs b/src/librustc_interface/interface.rs index 674b2b60e44..fef60a47dc4 100644 --- a/src/librustc_interface/interface.rs +++ b/src/librustc_interface/interface.rs @@ -12,7 +12,6 @@ use rustc_data_structures::OnDrop; use rustc_data_structures::sync::Lrc; use rustc_data_structures::fx::{FxHashSet, FxHashMap}; use rustc_metadata::cstore::CStore; -use std::io::Write; use std::path::PathBuf; use std::result; use std::sync::{Arc, Mutex}; diff --git a/src/librustc_interface/lib.rs b/src/librustc_interface/lib.rs index 4bc50c24e81..f4e4612007c 100644 --- a/src/librustc_interface/lib.rs +++ b/src/librustc_interface/lib.rs @@ -6,11 +6,8 @@ #![feature(generators)] #![cfg_attr(unix, feature(libc))] -#![deny(rust_2018_idioms)] #![deny(unused_lifetimes)] -#![allow(unused_imports)] - #![recursion_limit="256"] #[cfg(unix)] diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 3c7d854b36b..ac36ad7e30b 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -2,7 +2,7 @@ use crate::interface::{Compiler, Result}; use crate::util; use crate::proc_macro_decls; -use log::{debug, info, warn, log_enabled}; +use log::{info, warn, log_enabled}; use rustc::dep_graph::DepGraph; use rustc::hir; use rustc::hir::lowering::lower_crate; @@ -10,13 +10,11 @@ use rustc::hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc::lint; use rustc::middle::{self, reachable, resolve_lifetime, stability}; use rustc::middle::cstore::CrateStore; -use rustc::middle::privacy::AccessLevels; use rustc::ty::{self, AllArenas, Resolutions, TyCtxt, GlobalCtxt}; use rustc::ty::steal::Steal; use rustc::traits; use rustc::util::common::{time, ErrorReported}; -use rustc::util::profiling::ProfileCategory; -use rustc::session::{CompileResult, CrateDisambiguator, Session}; +use rustc::session::Session; use rustc::session::config::{self, CrateType, Input, OutputFilenames, OutputType}; use rustc::session::search_paths::PathKind; use rustc_allocator as allocator; @@ -25,31 +23,27 @@ use rustc_codegen_ssa::back::link::emit_metadata; use rustc_codegen_utils::codegen_backend::CodegenBackend; use rustc_codegen_utils::link::filename_for_metadata; use rustc_data_structures::{box_region_allow_access, declare_box_region_type, parallel}; -use rustc_data_structures::fingerprint::Fingerprint; -use rustc_data_structures::stable_hasher::StableHasher; use rustc_data_structures::sync::{Lrc, ParallelIterator, par_iter}; use rustc_incremental; -use rustc_incremental::DepGraphFuture; use rustc_metadata::creader::CrateLoader; use rustc_metadata::cstore::{self, CStore}; use rustc_mir as mir; -use rustc_passes::{self, ast_validation, hir_stats, loops, rvalue_promotion, layout_test}; +use rustc_passes::{self, ast_validation, hir_stats, layout_test}; use rustc_plugin as plugin; use rustc_plugin::registry::Registry; use rustc_privacy; use rustc_resolve::{Resolver, ResolverArenas}; use rustc_traits; use rustc_typeck as typeck; -use syntax::{self, ast, attr, diagnostics, visit}; +use syntax::{self, ast, diagnostics, visit}; use syntax::early_buffered_lints::BufferedEarlyLint; use syntax::ext::base::{NamedSyntaxExtension, ExtCtxt}; use syntax::mut_visit::MutVisitor; use syntax::parse::{self, PResult}; use syntax::util::node_count::NodeCounter; -use syntax::util::lev_distance::find_best_match_for_name; use syntax::symbol::Symbol; use syntax::feature_gate::AttributeType; -use syntax_pos::{FileName, edition::Edition, hygiene}; +use syntax_pos::FileName; use syntax_ext; use rustc_serialize::json; @@ -61,12 +55,11 @@ use std::ffi::OsString; use std::fs; use std::io::{self, Write}; use std::iter; -use std::path::{Path, PathBuf}; +use std::path::PathBuf; use std::sync::mpsc; use std::cell::RefCell; use std::rc::Rc; use std::mem; -use std::ops::Generator; pub fn parse<'a>(sess: &'a Session, input: &Input) -> PResult<'a, ast::Crate> { sess.diagnostic() diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index 9b79dc6350c..2e7952cd004 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -2,30 +2,18 @@ use crate::interface::{Compiler, Result}; use crate::passes::{self, BoxedResolver, ExpansionResult, BoxedGlobalCtxt, PluginInfo}; use rustc_incremental::DepGraphFuture; -use rustc_data_structures::sync::Lrc; -use rustc::session::config::{Input, OutputFilenames, OutputType}; -use rustc::session::Session; +use rustc::session::config::{OutputFilenames, OutputType}; use rustc::util::common::{time, ErrorReported}; -use rustc::util::profiling::ProfileCategory; -use rustc::lint; use rustc::hir; use rustc::hir::def_id::LOCAL_CRATE; -use rustc::ty; use rustc::ty::steal::Steal; use rustc::dep_graph::DepGraph; -use rustc_passes::hir_stats; -use rustc_plugin::registry::Registry; -use rustc_serialize::json; use std::cell::{Ref, RefMut, RefCell}; -use std::ops::Deref; use std::rc::Rc; use std::sync::mpsc; use std::any::Any; use std::mem; -use syntax::parse::{self, PResult}; -use syntax::util::node_count::NodeCounter; -use syntax::{self, ast, attr, diagnostics, visit}; -use syntax_pos::hygiene; +use syntax::{self, ast}; /// Represent the result of a query. /// This result can be stolen with the `take` method and returned with the `give` method. diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index c7a8c2b8923..1d3b2b62996 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -19,7 +19,6 @@ #![recursion_limit="256"] -#![deny(rust_2018_idioms)] #![deny(unused_lifetimes)] #[macro_use] diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index dea7e6ae0a2..647d473f015 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -1,4 +1,3 @@ -#![deny(rust_2018_idioms)] #![feature(nll)] #![feature(static_nobundle)] diff --git a/src/librustc_lsan/lib.rs b/src/librustc_lsan/lib.rs index 3bdb86d313d..d6c8e54c18d 100644 --- a/src/librustc_lsan/lib.rs +++ b/src/librustc_lsan/lib.rs @@ -6,5 +6,3 @@ #![unstable(feature = "sanitizer_runtime_lib", reason = "internal implementation detail of sanitizers", issue = "0")] - -#![deny(rust_2018_idioms)] diff --git a/src/librustc_macros/src/lib.rs b/src/librustc_macros/src/lib.rs index 53bbecd0e6a..85e2247ebd7 100644 --- a/src/librustc_macros/src/lib.rs +++ b/src/librustc_macros/src/lib.rs @@ -1,5 +1,4 @@ #![feature(proc_macro_hygiene)] -#![deny(rust_2018_idioms)] #![cfg_attr(not(bootstrap), allow(rustc::default_hash_types))] #![recursion_limit="128"] diff --git a/src/librustc_metadata/error_codes.rs b/src/librustc_metadata/error_codes.rs index 909fca2ab58..0708a6243bf 100644 --- a/src/librustc_metadata/error_codes.rs +++ b/src/librustc_metadata/error_codes.rs @@ -1,5 +1,3 @@ -#![allow(non_snake_case)] - use syntax::{register_diagnostics, register_long_diagnostics}; register_long_diagnostics! { diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs index 8db3ec491df..ce7fb7cdc66 100644 --- a/src/librustc_metadata/lib.rs +++ b/src/librustc_metadata/lib.rs @@ -15,7 +15,6 @@ #![recursion_limit="256"] -#![deny(rust_2018_idioms)] #![deny(unused_lifetimes)] extern crate libc; diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index 45b806bd286..50c0640f885 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -1,7 +1,5 @@ //! This pass type-checks the MIR to ensure it is not broken. -#![allow(unreachable_code)] - use crate::borrow_check::borrow_set::BorrowSet; use crate::borrow_check::location::LocationTable; use crate::borrow_check::nll::constraints::{OutlivesConstraintSet, OutlivesConstraint}; diff --git a/src/librustc_mir/error_codes.rs b/src/librustc_mir/error_codes.rs index 83d441b90be..a5e44a1933c 100644 --- a/src/librustc_mir/error_codes.rs +++ b/src/librustc_mir/error_codes.rs @@ -1,5 +1,3 @@ -#![allow(non_snake_case)] - register_long_diagnostics! { diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index 964f04d79b9..28e5c5dc99a 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -26,7 +26,6 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![recursion_limit="256"] -#![deny(rust_2018_idioms)] #![deny(unused_lifetimes)] #[macro_use] extern crate log; diff --git a/src/librustc_msan/lib.rs b/src/librustc_msan/lib.rs index 3bdb86d313d..d6c8e54c18d 100644 --- a/src/librustc_msan/lib.rs +++ b/src/librustc_msan/lib.rs @@ -6,5 +6,3 @@ #![unstable(feature = "sanitizer_runtime_lib", reason = "internal implementation detail of sanitizers", issue = "0")] - -#![deny(rust_2018_idioms)] diff --git a/src/librustc_passes/error_codes.rs b/src/librustc_passes/error_codes.rs index 36ebe5cf455..cd33943e77e 100644 --- a/src/librustc_passes/error_codes.rs +++ b/src/librustc_passes/error_codes.rs @@ -1,5 +1,3 @@ -#![allow(non_snake_case)] - use syntax::{register_diagnostics, register_long_diagnostics}; register_long_diagnostics! { diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs index 0a96ad3e344..6c11d82958b 100644 --- a/src/librustc_passes/lib.rs +++ b/src/librustc_passes/lib.rs @@ -13,7 +13,6 @@ #![recursion_limit="256"] -#![deny(rust_2018_idioms)] #![deny(unused_lifetimes)] #[macro_use] diff --git a/src/librustc_plugin/error_codes.rs b/src/librustc_plugin/error_codes.rs index 9e76f52a111..b5f6a8d905d 100644 --- a/src/librustc_plugin/error_codes.rs +++ b/src/librustc_plugin/error_codes.rs @@ -1,5 +1,3 @@ -#![allow(non_snake_case)] - use syntax::{register_diagnostics, register_long_diagnostics}; register_long_diagnostics! { diff --git a/src/librustc_plugin/lib.rs b/src/librustc_plugin/lib.rs index 6520cdc3062..25a7a8cdeb6 100644 --- a/src/librustc_plugin/lib.rs +++ b/src/librustc_plugin/lib.rs @@ -59,8 +59,6 @@ #![recursion_limit="256"] -#![deny(rust_2018_idioms)] - pub use registry::Registry; mod error_codes; diff --git a/src/librustc_privacy/error_codes.rs b/src/librustc_privacy/error_codes.rs index fa4df53e47b..70a799d426a 100644 --- a/src/librustc_privacy/error_codes.rs +++ b/src/librustc_privacy/error_codes.rs @@ -1,5 +1,3 @@ -#![allow(non_snake_case)] - register_long_diagnostics! { E0445: r##" diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 05df3a6f6bc..75c98753d31 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -1,6 +1,5 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] -#![deny(rust_2018_idioms)] #![deny(unused_lifetimes)] #![feature(in_band_lifetimes)] diff --git a/src/librustc_resolve/error_codes.rs b/src/librustc_resolve/error_codes.rs index 15194a5d146..e01f53786ed 100644 --- a/src/librustc_resolve/error_codes.rs +++ b/src/librustc_resolve/error_codes.rs @@ -1,5 +1,3 @@ -#![allow(non_snake_case)] - use syntax::{register_diagnostics, register_long_diagnostics}; // Error messages for EXXXX errors. Each message should start and end with a diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index a5e498fa756..c7982b4a396 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -10,7 +10,6 @@ #![recursion_limit="256"] -#![deny(rust_2018_idioms)] #![deny(unused_lifetimes)] pub use rustc::hir::def::{Namespace, PerNS}; diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index ade5e2eca60..1e18b34e5c8 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -1,8 +1,6 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![feature(nll)] -#![deny(rust_2018_idioms)] #![deny(unused_lifetimes)] -#![allow(unused_attributes)] #![recursion_limit="256"] diff --git a/src/librustc_target/abi/call/hexagon.rs b/src/librustc_target/abi/call/hexagon.rs index db8c915cdb4..1aec990064a 100644 --- a/src/librustc_target/abi/call/hexagon.rs +++ b/src/librustc_target/abi/call/hexagon.rs @@ -1,5 +1,3 @@ -#![allow(non_upper_case_globals)] - use crate::abi::call::{FnType, ArgType}; fn classify_ret_ty(ret: &mut ArgType<'_, Ty>) { diff --git a/src/librustc_target/lib.rs b/src/librustc_target/lib.rs index a14bc66cc38..0fc5fbdc6a2 100644 --- a/src/librustc_target/lib.rs +++ b/src/librustc_target/lib.rs @@ -13,7 +13,6 @@ #![feature(nll)] #![feature(slice_patterns)] -#![deny(rust_2018_idioms)] #![deny(unused_lifetimes)] #[macro_use] extern crate log; diff --git a/src/librustc_traits/lib.rs b/src/librustc_traits/lib.rs index 12b19a2648d..ec5a8bc544b 100644 --- a/src/librustc_traits/lib.rs +++ b/src/librustc_traits/lib.rs @@ -1,7 +1,6 @@ //! New recursive solver modeled on Chalk's recursive solver. Most of //! the guts are broken up into modules; see the comments in those modules. -#![deny(rust_2018_idioms)] #![deny(unused_lifetimes)] #![feature(crate_visibility_modifier)] diff --git a/src/librustc_tsan/lib.rs b/src/librustc_tsan/lib.rs index 3bdb86d313d..d6c8e54c18d 100644 --- a/src/librustc_tsan/lib.rs +++ b/src/librustc_tsan/lib.rs @@ -6,5 +6,3 @@ #![unstable(feature = "sanitizer_runtime_lib", reason = "internal implementation detail of sanitizers", issue = "0")] - -#![deny(rust_2018_idioms)] diff --git a/src/librustc_typeck/error_codes.rs b/src/librustc_typeck/error_codes.rs index b4c85692119..4bdcb0fa291 100644 --- a/src/librustc_typeck/error_codes.rs +++ b/src/librustc_typeck/error_codes.rs @@ -1,7 +1,5 @@ // ignore-tidy-filelength -#![allow(non_snake_case)] - register_long_diagnostics! { E0023: r##" diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 934fc684eae..284b1d533d5 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -73,7 +73,6 @@ This API is completely unstable and subject to change. #![recursion_limit="256"] -#![deny(rust_2018_idioms)] #![deny(unused_lifetimes)] #[macro_use] extern crate log; diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 3627ce6a5aa..74a7b2b9152 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -1,4 +1,3 @@ -#![deny(rust_2018_idioms)] #![deny(unused_lifetimes)] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/", diff --git a/src/libserialize/lib.rs b/src/libserialize/lib.rs index b8eeb4d2b34..2ad85c603d1 100644 --- a/src/libserialize/lib.rs +++ b/src/libserialize/lib.rs @@ -8,8 +8,6 @@ Core encoding and decoding interfaces. html_playground_url = "https://play.rust-lang.org/", test(attr(allow(unused_variables), deny(warnings))))] -#![deny(rust_2018_idioms)] - #![feature(box_syntax)] #![feature(core_intrinsics)] #![feature(specialization)] diff --git a/src/libstd/build.rs b/src/libstd/build.rs index 20397369387..8db7bc12cd3 100644 --- a/src/libstd/build.rs +++ b/src/libstd/build.rs @@ -1,5 +1,3 @@ -#![deny(warnings)] - use std::env; fn main() { diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 722c08a22a6..1390341cf7c 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -209,8 +209,6 @@ #![warn(missing_docs)] #![warn(missing_debug_implementations)] #![deny(intra_doc_link_resolution_failure)] // rustdoc is run without -D warnings - -#![deny(rust_2018_idioms)] #![allow(explicit_outlives_requirements)] // Tell the compiler to link to either panic_abort or panic_unwind diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs index ee640a1603a..e5e55a6444a 100644 --- a/src/libsyntax/diagnostics/plugin.rs +++ b/src/libsyntax/diagnostics/plugin.rs @@ -123,7 +123,6 @@ pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt<'_>, MacEager::items(smallvec![]) } -#[allow(deprecated)] pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt<'_>, span: Span, token_tree: &[TokenTree]) @@ -149,7 +148,7 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt<'_>, ecx.span_bug(span, &format!( "error writing metadata for triple `{}` and crate `{}`, error: {}, \ cause: {:?}", - target_triple, crate_name, e.description(), e.cause() + target_triple, crate_name, e.description(), e.source() )); } }); diff --git a/src/libsyntax/error_codes.rs b/src/libsyntax/error_codes.rs index 029ce73498c..1ba29011f75 100644 --- a/src/libsyntax/error_codes.rs +++ b/src/libsyntax/error_codes.rs @@ -1,5 +1,3 @@ -#![allow(non_snake_case)] - // Error messages for EXXXX errors. // Each message should start and end with a new line, and be wrapped to 80 characters. // In vim you can `:set tw=80` and use `gq` to wrap paragraphs. Use `:set tw=0` to disable. diff --git a/src/libsyntax/json.rs b/src/libsyntax/json.rs index ec0222d90eb..83c9c692bd3 100644 --- a/src/libsyntax/json.rs +++ b/src/libsyntax/json.rs @@ -122,7 +122,6 @@ struct Diagnostic { } #[derive(RustcEncodable)] -#[allow(unused_attributes)] struct DiagnosticSpan { file_name: String, byte_start: u32, diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index bb6a8dfb141..5ef80518b40 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -7,7 +7,6 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/", test(attr(deny(warnings))))] -#![deny(rust_2018_idioms)] #![deny(unused_lifetimes)] #![feature(bind_by_move_pattern_guards)] diff --git a/src/libsyntax_ext/error_codes.rs b/src/libsyntax_ext/error_codes.rs index 9ec551b4395..5982a4df226 100644 --- a/src/libsyntax_ext/error_codes.rs +++ b/src/libsyntax_ext/error_codes.rs @@ -1,5 +1,3 @@ -#![allow(non_snake_case)] - use syntax::register_long_diagnostics; // Error messages for EXXXX errors. diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs index fae884860ed..21031109f2a 100644 --- a/src/libsyntax_ext/lib.rs +++ b/src/libsyntax_ext/lib.rs @@ -3,7 +3,6 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] -#![deny(rust_2018_idioms)] #![deny(unused_lifetimes)] #![feature(crate_visibility_modifier)] diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index e5f0892b37b..bc7be9f34ee 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -6,7 +6,6 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] -#![deny(rust_2018_idioms)] #![deny(unused_lifetimes)] #![feature(const_fn)] diff --git a/src/libterm/lib.rs b/src/libterm/lib.rs index 3b5ac7baf20..ad1a83316be 100644 --- a/src/libterm/lib.rs +++ b/src/libterm/lib.rs @@ -35,8 +35,6 @@ test(attr(deny(warnings))))] #![deny(missing_docs)] -#![deny(rust_2018_idioms)] - #![cfg_attr(windows, feature(libc))] use std::io::prelude::*; diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index fa45c9d7d9d..653dce32e50 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -17,7 +17,6 @@ // this crate, which relies on this attribute (rather than the value of `--crate-name` passed by // cargo) to detect this crate. -#![deny(rust_2018_idioms)] #![crate_name = "test"] #![unstable(feature = "test", issue = "27812")] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/", test(attr(deny(warnings))))] diff --git a/src/libunwind/lib.rs b/src/libunwind/lib.rs index 9182e349b19..b9ce71b6b84 100644 --- a/src/libunwind/lib.rs +++ b/src/libunwind/lib.rs @@ -1,8 +1,6 @@ #![no_std] #![unstable(feature = "panic_unwind", issue = "32837")] -#![deny(rust_2018_idioms)] - #![feature(link_cfg)] #![feature(nll)] #![feature(staged_api)] diff --git a/src/test/run-make-fulldeps/issue-19371/foo.rs b/src/test/run-make-fulldeps/issue-19371/foo.rs index 3c4f2cd541f..afc92638fda 100644 --- a/src/test/run-make-fulldeps/issue-19371/foo.rs +++ b/src/test/run-make-fulldeps/issue-19371/foo.rs @@ -2,8 +2,7 @@ extern crate rustc; extern crate rustc_interface; -#[allow(unused_extern_crates)] -extern crate rustc_driver; +extern crate rustc_driver as _; extern crate syntax; use rustc::session::DiagnosticOutput; diff --git a/src/test/ui-fulldeps/plugin-as-extern-crate.rs b/src/test/ui-fulldeps/plugin-as-extern-crate.rs index c671ab581ef..dde73ba69f7 100644 --- a/src/test/ui-fulldeps/plugin-as-extern-crate.rs +++ b/src/test/ui-fulldeps/plugin-as-extern-crate.rs @@ -5,7 +5,6 @@ // libsyntax is not compiled for it. #![deny(plugin_as_library)] -#![allow(unused_extern_crates)] extern crate attr_plugin_test; //~ ERROR compiler plugin used as an ordinary library diff --git a/src/test/ui-fulldeps/plugin-as-extern-crate.stderr b/src/test/ui-fulldeps/plugin-as-extern-crate.stderr index ccc9580a60c..4daa4a2c821 100644 --- a/src/test/ui-fulldeps/plugin-as-extern-crate.stderr +++ b/src/test/ui-fulldeps/plugin-as-extern-crate.stderr @@ -1,5 +1,5 @@ error: compiler plugin used as an ordinary library - --> $DIR/plugin-as-extern-crate.rs:10:1 + --> $DIR/plugin-as-extern-crate.rs:9:1 | LL | extern crate attr_plugin_test; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/enable-unstable-lib-feature.rs b/src/test/ui/enable-unstable-lib-feature.rs index 383c6868ce2..aa6a973d7bd 100644 --- a/src/test/ui/enable-unstable-lib-feature.rs +++ b/src/test/ui/enable-unstable-lib-feature.rs @@ -6,7 +6,6 @@ #![deny(non_snake_case)] // To trigger a hard error // Shouldn't generate a warning about unstable features -#[allow(unused_extern_crates)] extern crate stability_cfg2; pub fn BOGUS() { } //~ ERROR diff --git a/src/test/ui/enable-unstable-lib-feature.stderr b/src/test/ui/enable-unstable-lib-feature.stderr index 5b6ebc4c0d9..d5b8c0efaad 100644 --- a/src/test/ui/enable-unstable-lib-feature.stderr +++ b/src/test/ui/enable-unstable-lib-feature.stderr @@ -1,5 +1,5 @@ error: function `BOGUS` should have a snake case name - --> $DIR/enable-unstable-lib-feature.rs:12:8 + --> $DIR/enable-unstable-lib-feature.rs:11:8 | LL | pub fn BOGUS() { } | ^^^^^ help: convert the identifier to snake case: `bogus` diff --git a/src/test/ui/error-codes/E0254.rs b/src/test/ui/error-codes/E0254.rs index d166aff5657..e291268be86 100644 --- a/src/test/ui/error-codes/E0254.rs +++ b/src/test/ui/error-codes/E0254.rs @@ -1,4 +1,4 @@ -#![allow(unused_extern_crates, non_camel_case_types)] +#![allow(non_camel_case_types)] extern crate alloc; diff --git a/src/test/ui/error-codes/E0259.rs b/src/test/ui/error-codes/E0259.rs index c83561be9c6..e7e94d58635 100644 --- a/src/test/ui/error-codes/E0259.rs +++ b/src/test/ui/error-codes/E0259.rs @@ -1,5 +1,4 @@ #![feature(rustc_private)] -#![allow(unused_extern_crates)] extern crate alloc; diff --git a/src/test/ui/error-codes/E0259.stderr b/src/test/ui/error-codes/E0259.stderr index fd6a4087aec..4a48a4d5541 100644 --- a/src/test/ui/error-codes/E0259.stderr +++ b/src/test/ui/error-codes/E0259.stderr @@ -1,5 +1,5 @@ error[E0259]: the name `alloc` is defined multiple times - --> $DIR/E0259.rs:6:1 + --> $DIR/E0259.rs:5:1 | LL | extern crate alloc; | ------------------- previous import of the extern crate `alloc` here diff --git a/src/test/ui/error-codes/E0260.rs b/src/test/ui/error-codes/E0260.rs index 73b8934159f..f7eb220b08f 100644 --- a/src/test/ui/error-codes/E0260.rs +++ b/src/test/ui/error-codes/E0260.rs @@ -1,5 +1,3 @@ -#![allow(unused_extern_crates)] - extern crate alloc; mod alloc { diff --git a/src/test/ui/error-codes/E0260.stderr b/src/test/ui/error-codes/E0260.stderr index 7d0b3022914..737b20b91ec 100644 --- a/src/test/ui/error-codes/E0260.stderr +++ b/src/test/ui/error-codes/E0260.stderr @@ -1,5 +1,5 @@ error[E0260]: the name `alloc` is defined multiple times - --> $DIR/E0260.rs:5:1 + --> $DIR/E0260.rs:3:1 | LL | extern crate alloc; | ------------------- previous import of the extern crate `alloc` here diff --git a/src/test/ui/issues/issue-36881.rs b/src/test/ui/issues/issue-36881.rs index 2b0508d08ea..04313872d27 100644 --- a/src/test/ui/issues/issue-36881.rs +++ b/src/test/ui/issues/issue-36881.rs @@ -1,7 +1,6 @@ // aux-build:issue-36881-aux.rs fn main() { - #[allow(unused_extern_crates)] extern crate issue_36881_aux; use issue_36881_aux::Foo; //~ ERROR unresolved import } diff --git a/src/test/ui/issues/issue-36881.stderr b/src/test/ui/issues/issue-36881.stderr index 2ec636fde60..07d2c99d7d2 100644 --- a/src/test/ui/issues/issue-36881.stderr +++ b/src/test/ui/issues/issue-36881.stderr @@ -1,5 +1,5 @@ error[E0432]: unresolved import `issue_36881_aux` - --> $DIR/issue-36881.rs:6:9 + --> $DIR/issue-36881.rs:5:9 | LL | use issue_36881_aux::Foo; | ^^^^^^^^^^^^^^^ maybe a missing `extern crate issue_36881_aux;`? diff --git a/src/test/ui/lint/lint-stability-deprecated.rs b/src/test/ui/lint/lint-stability-deprecated.rs index 652fd04bdf5..5e747467a12 100644 --- a/src/test/ui/lint/lint-stability-deprecated.rs +++ b/src/test/ui/lint/lint-stability-deprecated.rs @@ -5,7 +5,6 @@ // aux-build:stability-cfg2.rs // ignore-tidy-linelength #![warn(deprecated)] -#![allow(dead_code, unused_extern_crates)] #![feature(staged_api, unstable_test_feature)] #![stable(feature = "rust1", since = "1.0.0")] diff --git a/src/test/ui/lint/lint-stability-deprecated.stderr b/src/test/ui/lint/lint-stability-deprecated.stderr index 811004ee12c..8132a66df8a 100644 --- a/src/test/ui/lint/lint-stability-deprecated.stderr +++ b/src/test/ui/lint/lint-stability-deprecated.stderr @@ -1,5 +1,5 @@ warning: use of deprecated item 'lint_stability::deprecated': text - --> $DIR/lint-stability-deprecated.rs:26:9 + --> $DIR/lint-stability-deprecated.rs:25:9 | LL | deprecated(); | ^^^^^^^^^^ @@ -11,625 +11,625 @@ LL | #![warn(deprecated)] | ^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:31:9 + --> $DIR/lint-stability-deprecated.rs:30:9 | LL | Trait::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:33:9 + --> $DIR/lint-stability-deprecated.rs:32:9 | LL | ::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:35:9 + --> $DIR/lint-stability-deprecated.rs:34:9 | LL | deprecated_text(); | ^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:40:9 + --> $DIR/lint-stability-deprecated.rs:39:9 | LL | Trait::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:42:9 + --> $DIR/lint-stability-deprecated.rs:41:9 | LL | ::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::deprecated_unstable': text - --> $DIR/lint-stability-deprecated.rs:44:9 + --> $DIR/lint-stability-deprecated.rs:43:9 | LL | deprecated_unstable(); | ^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text - --> $DIR/lint-stability-deprecated.rs:49:9 + --> $DIR/lint-stability-deprecated.rs:48:9 | LL | Trait::trait_deprecated_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text - --> $DIR/lint-stability-deprecated.rs:51:9 + --> $DIR/lint-stability-deprecated.rs:50:9 | LL | ::trait_deprecated_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::deprecated_unstable_text': text - --> $DIR/lint-stability-deprecated.rs:53:9 + --> $DIR/lint-stability-deprecated.rs:52:9 | LL | deprecated_unstable_text(); | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text - --> $DIR/lint-stability-deprecated.rs:58:9 + --> $DIR/lint-stability-deprecated.rs:57:9 | LL | Trait::trait_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text - --> $DIR/lint-stability-deprecated.rs:60:9 + --> $DIR/lint-stability-deprecated.rs:59:9 | LL | ::trait_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::DeprecatedStruct': text - --> $DIR/lint-stability-deprecated.rs:107:17 + --> $DIR/lint-stability-deprecated.rs:106:17 | LL | let _ = DeprecatedStruct { | ^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::DeprecatedUnstableStruct': text - --> $DIR/lint-stability-deprecated.rs:110:17 + --> $DIR/lint-stability-deprecated.rs:109:17 | LL | let _ = DeprecatedUnstableStruct { | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::DeprecatedUnitStruct': text - --> $DIR/lint-stability-deprecated.rs:117:17 + --> $DIR/lint-stability-deprecated.rs:116:17 | LL | let _ = DeprecatedUnitStruct; | ^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::DeprecatedUnstableUnitStruct': text - --> $DIR/lint-stability-deprecated.rs:118:17 + --> $DIR/lint-stability-deprecated.rs:117:17 | LL | let _ = DeprecatedUnstableUnitStruct; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Enum::DeprecatedVariant': text - --> $DIR/lint-stability-deprecated.rs:122:17 + --> $DIR/lint-stability-deprecated.rs:121:17 | LL | let _ = Enum::DeprecatedVariant; | ^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Enum::DeprecatedUnstableVariant': text - --> $DIR/lint-stability-deprecated.rs:123:17 + --> $DIR/lint-stability-deprecated.rs:122:17 | LL | let _ = Enum::DeprecatedUnstableVariant; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::DeprecatedTupleStruct': text - --> $DIR/lint-stability-deprecated.rs:127:17 + --> $DIR/lint-stability-deprecated.rs:126:17 | LL | let _ = DeprecatedTupleStruct (1); | ^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::DeprecatedUnstableTupleStruct': text - --> $DIR/lint-stability-deprecated.rs:128:17 + --> $DIR/lint-stability-deprecated.rs:127:17 | LL | let _ = DeprecatedUnstableTupleStruct (1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:137:25 + --> $DIR/lint-stability-deprecated.rs:136:25 | LL | macro_test_arg!(deprecated_text()); | ^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::deprecated_unstable_text': text - --> $DIR/lint-stability-deprecated.rs:138:25 + --> $DIR/lint-stability-deprecated.rs:137:25 | LL | macro_test_arg!(deprecated_unstable_text()); | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:139:41 + --> $DIR/lint-stability-deprecated.rs:138:41 | LL | macro_test_arg!(macro_test_arg!(deprecated_text())); | ^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:144:9 + --> $DIR/lint-stability-deprecated.rs:143:9 | LL | Trait::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:146:9 + --> $DIR/lint-stability-deprecated.rs:145:9 | LL | ::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:148:9 + --> $DIR/lint-stability-deprecated.rs:147:9 | LL | Trait::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:150:9 + --> $DIR/lint-stability-deprecated.rs:149:9 | LL | ::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text - --> $DIR/lint-stability-deprecated.rs:152:9 + --> $DIR/lint-stability-deprecated.rs:151:9 | LL | Trait::trait_deprecated_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text - --> $DIR/lint-stability-deprecated.rs:154:9 + --> $DIR/lint-stability-deprecated.rs:153:9 | LL | ::trait_deprecated_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text - --> $DIR/lint-stability-deprecated.rs:156:9 + --> $DIR/lint-stability-deprecated.rs:155:9 | LL | Trait::trait_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text - --> $DIR/lint-stability-deprecated.rs:158:9 + --> $DIR/lint-stability-deprecated.rs:157:9 | LL | ::trait_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::DeprecatedTrait': text - --> $DIR/lint-stability-deprecated.rs:186:10 + --> $DIR/lint-stability-deprecated.rs:185:10 | LL | impl DeprecatedTrait for S {} | ^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::DeprecatedTrait': text - --> $DIR/lint-stability-deprecated.rs:188:25 + --> $DIR/lint-stability-deprecated.rs:187:25 | LL | trait LocalTrait2 : DeprecatedTrait { } | ^^^^^^^^^^^^^^^ warning: use of deprecated item 'inheritance::inherited_stability::unstable_mod::deprecated': text - --> $DIR/lint-stability-deprecated.rs:207:9 + --> $DIR/lint-stability-deprecated.rs:206:9 | LL | unstable_mod::deprecated(); | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::deprecated': text - --> $DIR/lint-stability-deprecated.rs:329:9 + --> $DIR/lint-stability-deprecated.rs:328:9 | LL | deprecated(); | ^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:334:9 + --> $DIR/lint-stability-deprecated.rs:333:9 | LL | Trait::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:336:9 + --> $DIR/lint-stability-deprecated.rs:335:9 | LL | ::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:338:9 + --> $DIR/lint-stability-deprecated.rs:337:9 | LL | deprecated_text(); | ^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:343:9 + --> $DIR/lint-stability-deprecated.rs:342:9 | LL | Trait::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:345:9 + --> $DIR/lint-stability-deprecated.rs:344:9 | LL | ::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::DeprecatedStruct': text - --> $DIR/lint-stability-deprecated.rs:383:17 + --> $DIR/lint-stability-deprecated.rs:382:17 | LL | let _ = DeprecatedStruct { | ^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::DeprecatedUnitStruct': text - --> $DIR/lint-stability-deprecated.rs:390:17 + --> $DIR/lint-stability-deprecated.rs:389:17 | LL | let _ = DeprecatedUnitStruct; | ^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Enum::DeprecatedVariant': text - --> $DIR/lint-stability-deprecated.rs:394:17 + --> $DIR/lint-stability-deprecated.rs:393:17 | LL | let _ = Enum::DeprecatedVariant; | ^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::DeprecatedTupleStruct': text - --> $DIR/lint-stability-deprecated.rs:398:17 + --> $DIR/lint-stability-deprecated.rs:397:17 | LL | let _ = DeprecatedTupleStruct (1); | ^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:405:9 + --> $DIR/lint-stability-deprecated.rs:404:9 | LL | Trait::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:407:9 + --> $DIR/lint-stability-deprecated.rs:406:9 | LL | ::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:409:9 + --> $DIR/lint-stability-deprecated.rs:408:9 | LL | Trait::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:411:9 + --> $DIR/lint-stability-deprecated.rs:410:9 | LL | ::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::test_fn_body::fn_in_body': text - --> $DIR/lint-stability-deprecated.rs:438:9 + --> $DIR/lint-stability-deprecated.rs:437:9 | LL | fn_in_body(); | ^^^^^^^^^^ warning: use of deprecated item 'this_crate::DeprecatedTrait': text - --> $DIR/lint-stability-deprecated.rs:458:10 + --> $DIR/lint-stability-deprecated.rs:457:10 | LL | impl DeprecatedTrait for S { } | ^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::DeprecatedTrait': text - --> $DIR/lint-stability-deprecated.rs:460:24 + --> $DIR/lint-stability-deprecated.rs:459:24 | LL | trait LocalTrait : DeprecatedTrait { } | ^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::MethodTester::test_method_body::fn_in_body': text - --> $DIR/lint-stability-deprecated.rs:446:13 + --> $DIR/lint-stability-deprecated.rs:445:13 | LL | fn_in_body(); | ^^^^^^^^^^ warning: use of deprecated item 'lint_stability::TraitWithAssociatedTypes::TypeDeprecated': text - --> $DIR/lint-stability-deprecated.rs:99:48 + --> $DIR/lint-stability-deprecated.rs:98:48 | LL | struct S2(T::TypeDeprecated); | ^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::TraitWithAssociatedTypes::TypeDeprecated': text - --> $DIR/lint-stability-deprecated.rs:103:13 + --> $DIR/lint-stability-deprecated.rs:102:13 | LL | TypeDeprecated = u16, | ^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated': text - --> $DIR/lint-stability-deprecated.rs:27:13 + --> $DIR/lint-stability-deprecated.rs:26:13 | LL | foo.method_deprecated(); | ^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated': text - --> $DIR/lint-stability-deprecated.rs:28:9 + --> $DIR/lint-stability-deprecated.rs:27:9 | LL | Foo::method_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated': text - --> $DIR/lint-stability-deprecated.rs:29:9 + --> $DIR/lint-stability-deprecated.rs:28:9 | LL | ::method_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:30:13 + --> $DIR/lint-stability-deprecated.rs:29:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:32:9 + --> $DIR/lint-stability-deprecated.rs:31:9 | LL | ::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:36:13 + --> $DIR/lint-stability-deprecated.rs:35:13 | LL | foo.method_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:37:9 + --> $DIR/lint-stability-deprecated.rs:36:9 | LL | Foo::method_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:38:9 + --> $DIR/lint-stability-deprecated.rs:37:9 | LL | ::method_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:39:13 + --> $DIR/lint-stability-deprecated.rs:38:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:41:9 + --> $DIR/lint-stability-deprecated.rs:40:9 | LL | ::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable': text - --> $DIR/lint-stability-deprecated.rs:45:13 + --> $DIR/lint-stability-deprecated.rs:44:13 | LL | foo.method_deprecated_unstable(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable': text - --> $DIR/lint-stability-deprecated.rs:46:9 + --> $DIR/lint-stability-deprecated.rs:45:9 | LL | Foo::method_deprecated_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable': text - --> $DIR/lint-stability-deprecated.rs:47:9 + --> $DIR/lint-stability-deprecated.rs:46:9 | LL | ::method_deprecated_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text - --> $DIR/lint-stability-deprecated.rs:48:13 + --> $DIR/lint-stability-deprecated.rs:47:13 | LL | foo.trait_deprecated_unstable(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text - --> $DIR/lint-stability-deprecated.rs:50:9 + --> $DIR/lint-stability-deprecated.rs:49:9 | LL | ::trait_deprecated_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable_text': text - --> $DIR/lint-stability-deprecated.rs:54:13 + --> $DIR/lint-stability-deprecated.rs:53:13 | LL | foo.method_deprecated_unstable_text(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable_text': text - --> $DIR/lint-stability-deprecated.rs:55:9 + --> $DIR/lint-stability-deprecated.rs:54:9 | LL | Foo::method_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable_text': text - --> $DIR/lint-stability-deprecated.rs:56:9 + --> $DIR/lint-stability-deprecated.rs:55:9 | LL | ::method_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text - --> $DIR/lint-stability-deprecated.rs:57:13 + --> $DIR/lint-stability-deprecated.rs:56:13 | LL | foo.trait_deprecated_unstable_text(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text - --> $DIR/lint-stability-deprecated.rs:59:9 + --> $DIR/lint-stability-deprecated.rs:58:9 | LL | ::trait_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::DeprecatedStruct::i': text - --> $DIR/lint-stability-deprecated.rs:108:13 + --> $DIR/lint-stability-deprecated.rs:107:13 | LL | i: 0 | ^^^^ warning: use of deprecated item 'lint_stability::DeprecatedUnstableStruct::i': text - --> $DIR/lint-stability-deprecated.rs:112:13 + --> $DIR/lint-stability-deprecated.rs:111:13 | LL | i: 0 | ^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:143:13 + --> $DIR/lint-stability-deprecated.rs:142:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:145:9 + --> $DIR/lint-stability-deprecated.rs:144:9 | LL | ::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:147:13 + --> $DIR/lint-stability-deprecated.rs:146:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:149:9 + --> $DIR/lint-stability-deprecated.rs:148:9 | LL | ::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text - --> $DIR/lint-stability-deprecated.rs:151:13 + --> $DIR/lint-stability-deprecated.rs:150:13 | LL | foo.trait_deprecated_unstable(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text - --> $DIR/lint-stability-deprecated.rs:153:9 + --> $DIR/lint-stability-deprecated.rs:152:9 | LL | ::trait_deprecated_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text - --> $DIR/lint-stability-deprecated.rs:155:13 + --> $DIR/lint-stability-deprecated.rs:154:13 | LL | foo.trait_deprecated_unstable_text(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text - --> $DIR/lint-stability-deprecated.rs:157:9 + --> $DIR/lint-stability-deprecated.rs:156:9 | LL | ::trait_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:174:13 + --> $DIR/lint-stability-deprecated.rs:173:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:175:13 + --> $DIR/lint-stability-deprecated.rs:174:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text - --> $DIR/lint-stability-deprecated.rs:176:13 + --> $DIR/lint-stability-deprecated.rs:175:13 | LL | foo.trait_deprecated_unstable(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text - --> $DIR/lint-stability-deprecated.rs:177:13 + --> $DIR/lint-stability-deprecated.rs:176:13 | LL | foo.trait_deprecated_unstable_text(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::MethodTester::method_deprecated': text - --> $DIR/lint-stability-deprecated.rs:330:13 + --> $DIR/lint-stability-deprecated.rs:329:13 | LL | foo.method_deprecated(); | ^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::MethodTester::method_deprecated': text - --> $DIR/lint-stability-deprecated.rs:331:9 + --> $DIR/lint-stability-deprecated.rs:330:9 | LL | Foo::method_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::MethodTester::method_deprecated': text - --> $DIR/lint-stability-deprecated.rs:332:9 + --> $DIR/lint-stability-deprecated.rs:331:9 | LL | ::method_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:333:13 + --> $DIR/lint-stability-deprecated.rs:332:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:335:9 + --> $DIR/lint-stability-deprecated.rs:334:9 | LL | ::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:339:13 + --> $DIR/lint-stability-deprecated.rs:338:13 | LL | foo.method_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:340:9 + --> $DIR/lint-stability-deprecated.rs:339:9 | LL | Foo::method_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:341:9 + --> $DIR/lint-stability-deprecated.rs:340:9 | LL | ::method_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:342:13 + --> $DIR/lint-stability-deprecated.rs:341:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:344:9 + --> $DIR/lint-stability-deprecated.rs:343:9 | LL | ::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::DeprecatedStruct::i': text - --> $DIR/lint-stability-deprecated.rs:385:13 + --> $DIR/lint-stability-deprecated.rs:384:13 | LL | i: 0 | ^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:404:13 + --> $DIR/lint-stability-deprecated.rs:403:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:406:9 + --> $DIR/lint-stability-deprecated.rs:405:9 | LL | ::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:408:13 + --> $DIR/lint-stability-deprecated.rs:407:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:410:9 + --> $DIR/lint-stability-deprecated.rs:409:9 | LL | ::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:427:13 + --> $DIR/lint-stability-deprecated.rs:426:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:428:13 + --> $DIR/lint-stability-deprecated.rs:427:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/macros/macro-use-bad-args-1.rs b/src/test/ui/macros/macro-use-bad-args-1.rs index 061c5cc7b3c..ec0b64a1095 100644 --- a/src/test/ui/macros/macro-use-bad-args-1.rs +++ b/src/test/ui/macros/macro-use-bad-args-1.rs @@ -1,6 +1,5 @@ #![no_std] -#[allow(unused_extern_crates)] #[macro_use(foo(bar))] //~ ERROR bad macro import extern crate std; diff --git a/src/test/ui/macros/macro-use-bad-args-1.stderr b/src/test/ui/macros/macro-use-bad-args-1.stderr index f403c8a3660..4e5482a518c 100644 --- a/src/test/ui/macros/macro-use-bad-args-1.stderr +++ b/src/test/ui/macros/macro-use-bad-args-1.stderr @@ -1,5 +1,5 @@ error[E0466]: bad macro import - --> $DIR/macro-use-bad-args-1.rs:4:13 + --> $DIR/macro-use-bad-args-1.rs:3:13 | LL | #[macro_use(foo(bar))] | ^^^^^^^^ diff --git a/src/test/ui/macros/macro-use-bad-args-2.rs b/src/test/ui/macros/macro-use-bad-args-2.rs index cb231ce292a..c5f8f62c186 100644 --- a/src/test/ui/macros/macro-use-bad-args-2.rs +++ b/src/test/ui/macros/macro-use-bad-args-2.rs @@ -1,6 +1,5 @@ #![no_std] -#[allow(unused_extern_crates)] #[macro_use(foo="bar")] //~ ERROR bad macro import extern crate std; diff --git a/src/test/ui/macros/macro-use-bad-args-2.stderr b/src/test/ui/macros/macro-use-bad-args-2.stderr index 93617edeeae..c958104eac4 100644 --- a/src/test/ui/macros/macro-use-bad-args-2.stderr +++ b/src/test/ui/macros/macro-use-bad-args-2.stderr @@ -1,5 +1,5 @@ error[E0466]: bad macro import - --> $DIR/macro-use-bad-args-2.rs:4:13 + --> $DIR/macro-use-bad-args-2.rs:3:13 | LL | #[macro_use(foo="bar")] | ^^^^^^^^^ diff --git a/src/test/ui/no-std-inject.rs b/src/test/ui/no-std-inject.rs index 09879c791f8..e9664a4dd48 100644 --- a/src/test/ui/no-std-inject.rs +++ b/src/test/ui/no-std-inject.rs @@ -1,5 +1,4 @@ #![no_std] -#![allow(unused_extern_crates)] extern crate core; //~ ERROR: the name `core` is defined multiple times extern crate std; diff --git a/src/test/ui/no-std-inject.stderr b/src/test/ui/no-std-inject.stderr index 975f5c2f50c..a82931e0fbd 100644 --- a/src/test/ui/no-std-inject.stderr +++ b/src/test/ui/no-std-inject.stderr @@ -1,5 +1,5 @@ error[E0259]: the name `core` is defined multiple times - --> $DIR/no-std-inject.rs:4:1 + --> $DIR/no-std-inject.rs:3:1 | LL | extern crate core; | ^^^^^^^^^^^^^^^^^^ `core` reimported here diff --git a/src/test/ui/resolve/resolve-conflict-extern-crate-vs-extern-crate.rs b/src/test/ui/resolve/resolve-conflict-extern-crate-vs-extern-crate.rs index e4bb0d32942..3cb6ab52e0a 100644 --- a/src/test/ui/resolve/resolve-conflict-extern-crate-vs-extern-crate.rs +++ b/src/test/ui/resolve/resolve-conflict-extern-crate-vs-extern-crate.rs @@ -1,4 +1,3 @@ -#[allow(unused_extern_crates)] extern crate std; //~^ ERROR the name `std` is defined multiple times diff --git a/src/test/ui/resolve/resolve-conflict-extern-crate-vs-extern-crate.stderr b/src/test/ui/resolve/resolve-conflict-extern-crate-vs-extern-crate.stderr index 9e43cd4839f..ea6cb9eb00d 100644 --- a/src/test/ui/resolve/resolve-conflict-extern-crate-vs-extern-crate.stderr +++ b/src/test/ui/resolve/resolve-conflict-extern-crate-vs-extern-crate.stderr @@ -1,8 +1,4 @@ error[E0259]: the name `std` is defined multiple times - --> $DIR/resolve-conflict-extern-crate-vs-extern-crate.rs:2:1 - | -LL | extern crate std; - | ^^^^^^^^^^^^^^^^^ `std` reimported here | = note: `std` must be defined only once in the type namespace of this module help: you can use `as` to change the binding name of the import diff --git a/src/test/ui/resolve_self_super_hint.rs b/src/test/ui/resolve_self_super_hint.rs index a9423830d90..a14ec5b7290 100644 --- a/src/test/ui/resolve_self_super_hint.rs +++ b/src/test/ui/resolve_self_super_hint.rs @@ -1,5 +1,3 @@ -#![allow(unused_extern_crates)] - mod a { extern crate alloc; use alloc::HashMap; diff --git a/src/test/ui/resolve_self_super_hint.stderr b/src/test/ui/resolve_self_super_hint.stderr index 14cdae97d14..bc862553b5b 100644 --- a/src/test/ui/resolve_self_super_hint.stderr +++ b/src/test/ui/resolve_self_super_hint.stderr @@ -1,17 +1,17 @@ error[E0432]: unresolved import `alloc` - --> $DIR/resolve_self_super_hint.rs:5:9 + --> $DIR/resolve_self_super_hint.rs:3:9 | LL | use alloc::HashMap; | ^^^^^ help: a similar path exists: `self::alloc` error[E0432]: unresolved import `alloc` - --> $DIR/resolve_self_super_hint.rs:10:13 + --> $DIR/resolve_self_super_hint.rs:8:13 | LL | use alloc::HashMap; | ^^^^^ help: a similar path exists: `super::alloc` error[E0432]: unresolved import `alloc` - --> $DIR/resolve_self_super_hint.rs:15:17 + --> $DIR/resolve_self_super_hint.rs:13:17 | LL | use alloc::HashMap; | ^^^^^ @@ -20,7 +20,7 @@ LL | use alloc::HashMap; | help: a similar path exists: `a::alloc` error[E0432]: unresolved import `alloc` - --> $DIR/resolve_self_super_hint.rs:20:21 + --> $DIR/resolve_self_super_hint.rs:18:21 | LL | use alloc::HashMap; | ^^^^^ diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 20176557bcb..a935bc6a4de 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -1,5 +1,3 @@ -#![deny(rust_2018_idioms)] - use toml; use serde::Serialize; diff --git a/src/tools/cargotest/main.rs b/src/tools/cargotest/main.rs index 14035eedbb4..729287faeb6 100644 --- a/src/tools/cargotest/main.rs +++ b/src/tools/cargotest/main.rs @@ -1,5 +1,3 @@ -#![deny(rust_2018_idioms)] - use std::env; use std::process::Command; use std::path::{Path, PathBuf}; diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index 31360c000ce..d709475541a 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -1,7 +1,6 @@ #![crate_name = "compiletest"] #![feature(test)] #![feature(vec_remove_item)] -#![deny(warnings, rust_2018_idioms)] extern crate test; diff --git a/src/tools/error_index_generator/main.rs b/src/tools/error_index_generator/main.rs index 3e7c7ab6379..c31a5069e46 100644 --- a/src/tools/error_index_generator/main.rs +++ b/src/tools/error_index_generator/main.rs @@ -1,7 +1,5 @@ #![feature(rustc_private)] -#![deny(rust_2018_idioms)] - extern crate env_logger; extern crate syntax; extern crate serialize as rustc_serialize; diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs index e2bcd4d40af..49c149afe17 100644 --- a/src/tools/linkchecker/main.rs +++ b/src/tools/linkchecker/main.rs @@ -14,8 +14,6 @@ //! A few whitelisted exceptions are allowed as there's known bugs in rustdoc, //! but this should catch the majority of "broken link" cases. -#![deny(rust_2018_idioms)] - use std::collections::hash_map::Entry; use std::collections::{HashMap, HashSet}; use std::env; diff --git a/src/tools/remote-test-client/src/main.rs b/src/tools/remote-test-client/src/main.rs index f42de441767..a1d52251263 100644 --- a/src/tools/remote-test-client/src/main.rs +++ b/src/tools/remote-test-client/src/main.rs @@ -1,5 +1,3 @@ -#![deny(rust_2018_idioms)] - /// This is a small client program intended to pair with `remote-test-server` in /// this repository. This client connects to the server over TCP and is used to /// push artifacts and run tests on the server instead of locally. diff --git a/src/tools/remote-test-server/src/main.rs b/src/tools/remote-test-server/src/main.rs index e1270489d31..d2238730196 100644 --- a/src/tools/remote-test-server/src/main.rs +++ b/src/tools/remote-test-server/src/main.rs @@ -1,5 +1,3 @@ -#![deny(rust_2018_idioms)] - /// This is a small server which is intended to run inside of an emulator or /// on a remote test device. This server pairs with the `remote-test-client` /// program in this repository. The `remote-test-client` connects to this diff --git a/src/tools/rustbook/src/main.rs b/src/tools/rustbook/src/main.rs index 4689bee3e13..6bce7c3a978 100644 --- a/src/tools/rustbook/src/main.rs +++ b/src/tools/rustbook/src/main.rs @@ -1,5 +1,3 @@ -#![deny(rust_2018_idioms)] - use clap::{crate_version}; use std::env; diff --git a/src/tools/rustc-std-workspace-core/lib.rs b/src/tools/rustc-std-workspace-core/lib.rs index 99d51bc2d56..14327852561 100644 --- a/src/tools/rustc-std-workspace-core/lib.rs +++ b/src/tools/rustc-std-workspace-core/lib.rs @@ -1,5 +1,4 @@ #![feature(no_core)] #![no_core] -#![deny(rust_2018_idioms)] pub use core::*; diff --git a/src/tools/rustdoc-themes/main.rs b/src/tools/rustdoc-themes/main.rs index 63432a6585a..616b5444832 100644 --- a/src/tools/rustdoc-themes/main.rs +++ b/src/tools/rustdoc-themes/main.rs @@ -1,5 +1,3 @@ -#![deny(rust_2018_idioms)] - use std::env::args; use std::fs::read_dir; use std::path::Path; diff --git a/src/tools/rustdoc/main.rs b/src/tools/rustdoc/main.rs index 8171708e99d..99573cadb95 100644 --- a/src/tools/rustdoc/main.rs +++ b/src/tools/rustdoc/main.rs @@ -1,3 +1 @@ -#![deny(rust_2018_idioms)] - fn main() { rustdoc::main() } diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index 19f02f0a96e..3acb50547da 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -4,8 +4,6 @@ //! etc. This is run by default on `make check` and as part of the auto //! builders. -#![deny(warnings)] - use tidy::*; use std::process; diff --git a/src/tools/unstable-book-gen/src/main.rs b/src/tools/unstable-book-gen/src/main.rs index e92d174a4e1..036349ea1c8 100644 --- a/src/tools/unstable-book-gen/src/main.rs +++ b/src/tools/unstable-book-gen/src/main.rs @@ -1,10 +1,5 @@ //! Auto-generate stub docs for the unstable book -#![deny(rust_2018_idioms)] -#![deny(warnings)] - - - use tidy::features::{Feature, Features, collect_lib_features, collect_lang_features}; use tidy::unstable_book::{collect_unstable_feature_names, collect_unstable_book_section_file_names, PATH_STR, LANG_FEATURES_DIR, LIB_FEATURES_DIR}; -- cgit 1.4.1-3-g733a5 From 676d282dd3cd2dedba651e98c9a41af42983f08b Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 23 Jul 2019 22:17:27 +0300 Subject: Deny `unused_lifetimes` through rustbuild --- src/bootstrap/bin/main.rs | 2 +- src/bootstrap/bin/rustc.rs | 3 ++- src/bootstrap/bin/rustdoc.rs | 2 +- src/bootstrap/lib.rs | 4 ++-- src/build_helper/lib.rs | 2 +- src/liballoc/string.rs | 2 ++ src/libarena/lib.rs | 2 -- src/libcore/array.rs | 10 +++++----- src/libcore/pin.rs | 2 +- src/libcore/ptr/unique.rs | 2 +- src/libfmt_macros/lib.rs | 2 -- src/libproc_macro/bridge/scoped_cell.rs | 1 + src/librustc/lib.rs | 2 -- src/librustc_ast_borrowck/lib.rs | 1 - src/librustc_codegen_llvm/lib.rs | 1 - src/librustc_codegen_ssa/lib.rs | 1 - src/librustc_codegen_utils/lib.rs | 2 -- src/librustc_data_structures/graph/mod.rs | 2 ++ src/librustc_data_structures/owning_ref/mod.rs | 3 +++ src/librustc_driver/lib.rs | 2 -- src/librustc_errors/lib.rs | 1 - src/librustc_incremental/lib.rs | 2 -- src/librustc_interface/lib.rs | 2 -- src/librustc_lint/lib.rs | 2 -- src/librustc_metadata/lib.rs | 2 -- src/librustc_mir/lib.rs | 2 -- src/librustc_passes/lib.rs | 2 -- src/librustc_privacy/lib.rs | 2 -- src/librustc_resolve/lib.rs | 2 -- src/librustc_save_analysis/lib.rs | 2 -- src/librustc_target/lib.rs | 2 -- src/librustc_traits/lib.rs | 2 -- src/librustc_typeck/lib.rs | 2 -- src/librustdoc/lib.rs | 2 -- src/libstd/lib.rs | 1 + src/libsyntax/lib.rs | 2 -- src/libsyntax_ext/lib.rs | 2 -- src/libsyntax_pos/lib.rs | 2 -- 38 files changed, 23 insertions(+), 59 deletions(-) (limited to 'src/liballoc') diff --git a/src/bootstrap/bin/main.rs b/src/bootstrap/bin/main.rs index da35c971f97..bd1a87c5744 100644 --- a/src/bootstrap/bin/main.rs +++ b/src/bootstrap/bin/main.rs @@ -6,7 +6,7 @@ //! directory in each respective module. // NO-RUSTC-WRAPPER -#![deny(warnings, rust_2018_idioms)] +#![deny(warnings, rust_2018_idioms, unused_lifetimes)] use std::env; diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs index 3888d0ef627..2e9044a8150 100644 --- a/src/bootstrap/bin/rustc.rs +++ b/src/bootstrap/bin/rustc.rs @@ -16,7 +16,7 @@ //! never get replaced. // NO-RUSTC-WRAPPER -#![deny(warnings, rust_2018_idioms)] +#![deny(warnings, rust_2018_idioms, unused_lifetimes)] use std::env; use std::ffi::OsString; @@ -129,6 +129,7 @@ fn main() { env::var_os("RUSTC_EXTERNAL_TOOL").is_none() { cmd.arg("-Dwarnings"); cmd.arg("-Drust_2018_idioms"); + cmd.arg("-Dunused_lifetimes"); // cfg(not(bootstrap)): Remove this during the next stage 0 compiler update. // `-Drustc::internal` is a new feature and `rustc_version` mis-reports the `stage`. let cfg_not_bootstrap = stage != "0" && crate_name != Some("rustc_version"); diff --git a/src/bootstrap/bin/rustdoc.rs b/src/bootstrap/bin/rustdoc.rs index 057daaf2dc4..ff38ee8788f 100644 --- a/src/bootstrap/bin/rustdoc.rs +++ b/src/bootstrap/bin/rustdoc.rs @@ -3,7 +3,7 @@ //! See comments in `src/bootstrap/rustc.rs` for more information. // NO-RUSTC-WRAPPER -#![deny(warnings, rust_2018_idioms)] +#![deny(warnings, rust_2018_idioms, unused_lifetimes)] use std::env; use std::process::Command; diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 0f7e4f6e977..c2e64ef51a7 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -104,7 +104,7 @@ //! also check out the `src/bootstrap/README.md` file for more information. // NO-RUSTC-WRAPPER -#![deny(warnings, rust_2018_idioms)] +#![deny(warnings, rust_2018_idioms, unused_lifetimes)] #![feature(core_intrinsics)] #![feature(drain_filter)] @@ -1313,7 +1313,7 @@ fn chmod(path: &Path, perms: u32) { fn chmod(_path: &Path, _perms: u32) {} -impl<'a> Compiler { +impl Compiler { pub fn with_stage(mut self, stage: u32) -> Compiler { self.stage = stage; self diff --git a/src/build_helper/lib.rs b/src/build_helper/lib.rs index f9371e878ef..c30307f3a1b 100644 --- a/src/build_helper/lib.rs +++ b/src/build_helper/lib.rs @@ -1,5 +1,5 @@ // NO-RUSTC-WRAPPER -#![deny(warnings, rust_2018_idioms)] +#![deny(warnings, rust_2018_idioms, unused_lifetimes)] use std::fs::File; use std::path::{Path, PathBuf}; diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index 366191e2c85..eca726cd410 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -1838,6 +1838,7 @@ impl PartialEq for String { macro_rules! impl_eq { ($lhs:ty, $rhs: ty) => { #[stable(feature = "rust1", since = "1.0.0")] + #[allow(unused_lifetimes)] impl<'a, 'b> PartialEq<$rhs> for $lhs { #[inline] fn eq(&self, other: &$rhs) -> bool { PartialEq::eq(&self[..], &other[..]) } @@ -1846,6 +1847,7 @@ macro_rules! impl_eq { } #[stable(feature = "rust1", since = "1.0.0")] + #[allow(unused_lifetimes)] impl<'a, 'b> PartialEq<$lhs> for $rhs { #[inline] fn eq(&self, other: &$lhs) -> bool { PartialEq::eq(&self[..], &other[..]) } diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index 7baec3ed1cf..690d8344acf 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -11,8 +11,6 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/", test(no_crate_inject, attr(deny(warnings))))] -#![deny(unused_lifetimes)] - #![feature(core_intrinsics)] #![feature(dropck_eyepatch)] #![feature(raw_vec_internals)] diff --git a/src/libcore/array.rs b/src/libcore/array.rs index 6ecc0487fae..6023bc21e74 100644 --- a/src/libcore/array.rs +++ b/src/libcore/array.rs @@ -250,7 +250,7 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, 'b, A, B, const N: usize> PartialEq<[A; N]> for [B] +impl PartialEq<[A; N]> for [B] where B: PartialEq, [A; N]: LengthAtMost32, @@ -266,7 +266,7 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, 'b, A, B, const N: usize> PartialEq<&'b [B]> for [A; N] +impl<'b, A, B, const N: usize> PartialEq<&'b [B]> for [A; N] where A: PartialEq, [A; N]: LengthAtMost32, @@ -282,7 +282,7 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, 'b, A, B, const N: usize> PartialEq<[A; N]> for &'b [B] +impl<'b, A, B, const N: usize> PartialEq<[A; N]> for &'b [B] where B: PartialEq, [A; N]: LengthAtMost32, @@ -298,7 +298,7 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, 'b, A, B, const N: usize> PartialEq<&'b mut [B]> for [A; N] +impl<'b, A, B, const N: usize> PartialEq<&'b mut [B]> for [A; N] where A: PartialEq, [A; N]: LengthAtMost32, @@ -314,7 +314,7 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, 'b, A, B, const N: usize> PartialEq<[A; N]> for &'b mut [B] +impl<'b, A, B, const N: usize> PartialEq<[A; N]> for &'b mut [B] where B: PartialEq, [A; N]: LengthAtMost32, diff --git a/src/libcore/pin.rs b/src/libcore/pin.rs index 2feaab7a09c..88a56174629 100644 --- a/src/libcore/pin.rs +++ b/src/libcore/pin.rs @@ -775,7 +775,7 @@ where {} #[stable(feature = "pin", since = "1.33.0")] -impl<'a, P, U> DispatchFromDyn> for Pin

+impl DispatchFromDyn> for Pin

where P: DispatchFromDyn, {} diff --git a/src/libcore/ptr/unique.rs b/src/libcore/ptr/unique.rs index d2517e51fc5..f0d011fe6b2 100644 --- a/src/libcore/ptr/unique.rs +++ b/src/libcore/ptr/unique.rs @@ -172,7 +172,7 @@ impl From<&T> for Unique { } #[unstable(feature = "ptr_internals", issue = "0")] -impl<'a, T: ?Sized> From> for Unique { +impl From> for Unique { #[inline] fn from(p: NonNull) -> Self { unsafe { Unique::new_unchecked(p.as_ptr()) } diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs index d673088fe45..83e24a48ea0 100644 --- a/src/libfmt_macros/lib.rs +++ b/src/libfmt_macros/lib.rs @@ -8,8 +8,6 @@ html_playground_url = "https://play.rust-lang.org/", test(attr(deny(warnings))))] -#![deny(unused_lifetimes)] - #![feature(nll)] #![feature(rustc_private)] #![feature(unicode_internals)] diff --git a/src/libproc_macro/bridge/scoped_cell.rs b/src/libproc_macro/bridge/scoped_cell.rs index 89fb7070015..2cde1f65adf 100644 --- a/src/libproc_macro/bridge/scoped_cell.rs +++ b/src/libproc_macro/bridge/scoped_cell.rs @@ -5,6 +5,7 @@ use std::mem; use std::ops::{Deref, DerefMut}; /// Type lambda application, with a lifetime. +#[allow(unused_lifetimes)] pub trait ApplyL<'a> { type Out; } diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 9957b173116..4b3fefcd4de 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -28,8 +28,6 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] -#![deny(unused_lifetimes)] - #![feature(arbitrary_self_types)] #![feature(box_patterns)] #![feature(box_syntax)] diff --git a/src/librustc_ast_borrowck/lib.rs b/src/librustc_ast_borrowck/lib.rs index 045671e37c0..dc818278a4b 100644 --- a/src/librustc_ast_borrowck/lib.rs +++ b/src/librustc_ast_borrowck/lib.rs @@ -1,7 +1,6 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![allow(non_camel_case_types)] -#![deny(unused_lifetimes)] #![feature(in_band_lifetimes)] #![feature(nll)] diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index 90609d6c85a..a630817fb33 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -21,7 +21,6 @@ #![feature(static_nobundle)] #![feature(trusted_len)] #![feature(mem_take)] -#![deny(unused_lifetimes)] use back::write::{create_target_machine, create_informational_target_machine}; use syntax_pos::symbol::Symbol; diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs index 4e2977a011c..73ef16e0091 100644 --- a/src/librustc_codegen_ssa/lib.rs +++ b/src/librustc_codegen_ssa/lib.rs @@ -11,7 +11,6 @@ #![feature(nll)] #![feature(trusted_len)] #![feature(mem_take)] -#![deny(unused_lifetimes)] #![recursion_limit="256"] diff --git a/src/librustc_codegen_utils/lib.rs b/src/librustc_codegen_utils/lib.rs index e3fafc2f2cd..4ea375b59b2 100644 --- a/src/librustc_codegen_utils/lib.rs +++ b/src/librustc_codegen_utils/lib.rs @@ -15,8 +15,6 @@ #![recursion_limit="256"] -#![deny(unused_lifetimes)] - #[macro_use] extern crate rustc; diff --git a/src/librustc_data_structures/graph/mod.rs b/src/librustc_data_structures/graph/mod.rs index e59085a9e3a..749709521e8 100644 --- a/src/librustc_data_structures/graph/mod.rs +++ b/src/librustc_data_structures/graph/mod.rs @@ -39,6 +39,7 @@ where } } +#[allow(unused_lifetimes)] pub trait GraphSuccessors<'graph> { type Item; type Iter: Iterator; @@ -54,6 +55,7 @@ where ) -> >::Iter; } +#[allow(unused_lifetimes)] pub trait GraphPredecessors<'graph> { type Item; type Iter: Iterator; diff --git a/src/librustc_data_structures/owning_ref/mod.rs b/src/librustc_data_structures/owning_ref/mod.rs index a7af615fa50..3b49ce71063 100644 --- a/src/librustc_data_structures/owning_ref/mod.rs +++ b/src/librustc_data_structures/owning_ref/mod.rs @@ -283,6 +283,7 @@ impl Erased for T {} /// Helper trait for erasing the concrete type of what an owner dereferences to, /// for example `Box -> Box`. This would be unneeded with /// higher kinded types support in the language. +#[allow(unused_lifetimes)] pub unsafe trait IntoErased<'a> { /// Owner with the dereference type substituted to `Erased`. type Erased; @@ -293,6 +294,7 @@ pub unsafe trait IntoErased<'a> { /// Helper trait for erasing the concrete type of what an owner dereferences to, /// for example `Box -> Box`. This would be unneeded with /// higher kinded types support in the language. +#[allow(unused_lifetimes)] pub unsafe trait IntoErasedSend<'a> { /// Owner with the dereference type substituted to `Erased + Send`. type Erased: Send; @@ -303,6 +305,7 @@ pub unsafe trait IntoErasedSend<'a> { /// Helper trait for erasing the concrete type of what an owner dereferences to, /// for example `Box -> Box`. This would be unneeded with /// higher kinded types support in the language. +#[allow(unused_lifetimes)] pub unsafe trait IntoErasedSendSync<'a> { /// Owner with the dereference type substituted to `Erased + Send + Sync`. type Erased: Send + Sync; diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 66739761ef0..77b7ef96d3f 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -16,8 +16,6 @@ #![recursion_limit="256"] -#![deny(unused_lifetimes)] - pub extern crate getopts; #[cfg(unix)] extern crate libc; diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index f252d0573dc..3f758c2521b 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -8,7 +8,6 @@ #![cfg_attr(unix, feature(libc))] #![feature(nll)] #![feature(optin_builtin_traits)] -#![deny(unused_lifetimes)] pub use emitter::ColorConfig; diff --git a/src/librustc_incremental/lib.rs b/src/librustc_incremental/lib.rs index 0b5eb41605b..b2573111385 100644 --- a/src/librustc_incremental/lib.rs +++ b/src/librustc_incremental/lib.rs @@ -8,8 +8,6 @@ #![recursion_limit="256"] -#![deny(unused_lifetimes)] - #[macro_use] extern crate rustc; #[macro_use] extern crate log; diff --git a/src/librustc_interface/lib.rs b/src/librustc_interface/lib.rs index f4e4612007c..2e593d44155 100644 --- a/src/librustc_interface/lib.rs +++ b/src/librustc_interface/lib.rs @@ -6,8 +6,6 @@ #![feature(generators)] #![cfg_attr(unix, feature(libc))] -#![deny(unused_lifetimes)] - #![recursion_limit="256"] #[cfg(unix)] diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 1d3b2b62996..d3975360525 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -19,8 +19,6 @@ #![recursion_limit="256"] -#![deny(unused_lifetimes)] - #[macro_use] extern crate rustc; diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs index ce7fb7cdc66..c96d02d9b37 100644 --- a/src/librustc_metadata/lib.rs +++ b/src/librustc_metadata/lib.rs @@ -15,8 +15,6 @@ #![recursion_limit="256"] -#![deny(unused_lifetimes)] - extern crate libc; extern crate proc_macro; diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index 28e5c5dc99a..20d5e54d2ce 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -26,8 +26,6 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![recursion_limit="256"] -#![deny(unused_lifetimes)] - #[macro_use] extern crate log; #[macro_use] extern crate rustc; #[macro_use] extern crate rustc_data_structures; diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs index 6c11d82958b..5614b570b92 100644 --- a/src/librustc_passes/lib.rs +++ b/src/librustc_passes/lib.rs @@ -13,8 +13,6 @@ #![recursion_limit="256"] -#![deny(unused_lifetimes)] - #[macro_use] extern crate rustc; diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 75c98753d31..e291f40ffd2 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -1,7 +1,5 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] -#![deny(unused_lifetimes)] - #![feature(in_band_lifetimes)] #![feature(nll)] #![feature(rustc_diagnostic_macros)] diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index c7982b4a396..bc5898fe78d 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -10,8 +10,6 @@ #![recursion_limit="256"] -#![deny(unused_lifetimes)] - pub use rustc::hir::def::{Namespace, PerNS}; use Determinacy::*; diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 1e18b34e5c8..9edb4c0fa67 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -1,10 +1,8 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![feature(nll)] -#![deny(unused_lifetimes)] #![recursion_limit="256"] - mod dumper; mod dump_visitor; #[macro_use] diff --git a/src/librustc_target/lib.rs b/src/librustc_target/lib.rs index 0fc5fbdc6a2..a349dc26e83 100644 --- a/src/librustc_target/lib.rs +++ b/src/librustc_target/lib.rs @@ -13,8 +13,6 @@ #![feature(nll)] #![feature(slice_patterns)] -#![deny(unused_lifetimes)] - #[macro_use] extern crate log; pub mod abi; diff --git a/src/librustc_traits/lib.rs b/src/librustc_traits/lib.rs index ec5a8bc544b..ebe6b7c6138 100644 --- a/src/librustc_traits/lib.rs +++ b/src/librustc_traits/lib.rs @@ -1,8 +1,6 @@ //! New recursive solver modeled on Chalk's recursive solver. Most of //! the guts are broken up into modules; see the comments in those modules. -#![deny(unused_lifetimes)] - #![feature(crate_visibility_modifier)] #![feature(in_band_lifetimes)] #![feature(nll)] diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 284b1d533d5..a34b137aca9 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -73,8 +73,6 @@ This API is completely unstable and subject to change. #![recursion_limit="256"] -#![deny(unused_lifetimes)] - #[macro_use] extern crate log; #[macro_use] extern crate syntax; diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 74a7b2b9152..a8d7ff4a2eb 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -1,5 +1,3 @@ -#![deny(unused_lifetimes)] - #![doc(html_root_url = "https://doc.rust-lang.org/nightly/", html_playground_url = "https://play.rust-lang.org/")] diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 1390341cf7c..8fd76eabe39 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -210,6 +210,7 @@ #![warn(missing_debug_implementations)] #![deny(intra_doc_link_resolution_failure)] // rustdoc is run without -D warnings #![allow(explicit_outlives_requirements)] +#![allow(unused_lifetimes)] // Tell the compiler to link to either panic_abort or panic_unwind #![needs_panic_runtime] diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 5ef80518b40..1fd20fa0b31 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -7,8 +7,6 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/", test(attr(deny(warnings))))] -#![deny(unused_lifetimes)] - #![feature(bind_by_move_pattern_guards)] #![feature(box_syntax)] #![feature(const_fn)] diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs index 21031109f2a..da11f2ff23f 100644 --- a/src/libsyntax_ext/lib.rs +++ b/src/libsyntax_ext/lib.rs @@ -3,8 +3,6 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] -#![deny(unused_lifetimes)] - #![feature(crate_visibility_modifier)] #![feature(decl_macro)] #![feature(mem_take)] diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index bc7be9f34ee..acc13aec402 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -6,8 +6,6 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] -#![deny(unused_lifetimes)] - #![feature(const_fn)] #![feature(crate_visibility_modifier)] #![feature(nll)] -- cgit 1.4.1-3-g733a5 From 624c5da1aacf44354dead47dce5033f1806e9228 Mon Sep 17 00:00:00 2001 From: Maximilian Roos Date: Fri, 26 Jul 2019 02:58:37 -0400 Subject: impl Debug for Chars --- src/liballoc/tests/str.rs | 10 ++++++++++ src/libcore/str/mod.rs | 12 +++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) (limited to 'src/liballoc') diff --git a/src/liballoc/tests/str.rs b/src/liballoc/tests/str.rs index b197516403f..20132fea651 100644 --- a/src/liballoc/tests/str.rs +++ b/src/liballoc/tests/str.rs @@ -1108,6 +1108,16 @@ fn test_iterator_last() { assert_eq!(it.last(), Some('m')); } +#[test] +fn test_chars_display() { + let s = "ศไทย中华Việt Nam"; + let c = s.chars(); + assert_eq!( + format!("{:?}", c), + r#"Chars(['ศ', 'ไ', 'ท', 'ย', '中', '华', 'V', 'i', 'ệ', 't', ' ', 'N', 'a', 'm'])"# + ); +} + #[test] fn test_bytesator() { let s = "ศไทย中华Việt Nam"; diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 4ecaa37460c..ee791748c1d 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -464,7 +464,7 @@ Section: Iterators /// /// [`chars`]: ../../std/primitive.str.html#method.chars /// [`str`]: ../../std/primitive.str.html -#[derive(Clone, Debug)] +#[derive(Clone)] #[stable(feature = "rust1", since = "1.0.0")] pub struct Chars<'a> { iter: slice::Iter<'a, u8> @@ -600,6 +600,16 @@ impl<'a> Iterator for Chars<'a> { } } +#[stable(feature = "chars_debug_impl", since = "1.38.0")] +impl<'a> fmt::Debug for Chars<'a> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Chars(")?; + f.debug_list().entries(self.clone()).finish()?; + write!(f, ")")?; + Ok(()) + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl<'a> DoubleEndedIterator for Chars<'a> { #[inline] -- cgit 1.4.1-3-g733a5 From 3325ff6df47f75cdf4891b35dcaf565f7ffb22cf Mon Sep 17 00:00:00 2001 From: Maximilian Roos Date: Mon, 29 Jul 2019 12:26:59 -0400 Subject: comments from @lzutao --- src/liballoc/tests/str.rs | 2 +- src/libcore/str/mod.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/tests/str.rs b/src/liballoc/tests/str.rs index 20132fea651..c5198ca39fe 100644 --- a/src/liballoc/tests/str.rs +++ b/src/liballoc/tests/str.rs @@ -1109,7 +1109,7 @@ fn test_iterator_last() { } #[test] -fn test_chars_display() { +fn test_chars_debug() { let s = "ศไทย中华Việt Nam"; let c = s.chars(); assert_eq!( diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index ee791748c1d..4faf9ff4d2e 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -601,7 +601,7 @@ impl<'a> Iterator for Chars<'a> { } #[stable(feature = "chars_debug_impl", since = "1.38.0")] -impl<'a> fmt::Debug for Chars<'a> { +impl fmt::Debug for Chars<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "Chars(")?; f.debug_list().entries(self.clone()).finish()?; -- cgit 1.4.1-3-g733a5 From 8a9017323904e7047a7e69f0b07dd57938942697 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 29 Jul 2019 02:01:38 +0200 Subject: Allow 'incomplete_features' in libcore/alloc. --- src/liballoc/lib.rs | 1 + src/libcore/lib.rs | 1 + 2 files changed, 2 insertions(+) (limited to 'src/liballoc') diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index c0f345443b9..1211747abd8 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -63,6 +63,7 @@ #![warn(missing_debug_implementations)] #![deny(intra_doc_link_resolution_failure)] // rustdoc is run without -D warnings #![allow(explicit_outlives_requirements)] +#![cfg_attr(not(bootstrap), allow(incomplete_features))] #![cfg_attr(not(test), feature(generator_trait))] #![cfg_attr(test, feature(test))] diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index bdfc1e66fd4..4d627383fd7 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -63,6 +63,7 @@ #![warn(missing_debug_implementations)] #![deny(intra_doc_link_resolution_failure)] // rustdoc is run without -D warnings #![allow(explicit_outlives_requirements)] +#![cfg_attr(not(bootstrap), allow(incomplete_features))] #![feature(allow_internal_unstable)] #![feature(arbitrary_self_types)] -- cgit 1.4.1-3-g733a5 From 3d0d6ee271a34d2329235b9a04cf4a421d9026cd Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 2 Aug 2019 01:40:56 +0300 Subject: liballoc: Unconfigure tests during normal build Remove additional libcore-like restrictions from liballoc, turns out the testing works ok if the tests are a part of liballoc itself. --- src/liballoc/alloc.rs | 36 +- src/liballoc/alloc/tests.rs | 30 ++ src/liballoc/collections/linked_list.rs | 273 +-------------- src/liballoc/collections/linked_list/tests.rs | 265 ++++++++++++++ src/liballoc/collections/vec_deque.rs | 389 +-------------------- src/liballoc/collections/vec_deque/tests.rs | 379 ++++++++++++++++++++ src/liballoc/raw_vec.rs | 82 +---- src/liballoc/raw_vec/tests.rs | 73 ++++ src/liballoc/rc.rs | 433 +---------------------- src/liballoc/rc/tests.rs | 427 ++++++++++++++++++++++ src/liballoc/sync.rs | 486 +------------------------- src/liballoc/sync/tests.rs | 480 +++++++++++++++++++++++++ src/tools/tidy/src/unit_tests.rs | 36 +- 13 files changed, 1682 insertions(+), 1707 deletions(-) create mode 100644 src/liballoc/alloc/tests.rs create mode 100644 src/liballoc/collections/linked_list/tests.rs create mode 100644 src/liballoc/collections/vec_deque/tests.rs create mode 100644 src/liballoc/raw_vec/tests.rs create mode 100644 src/liballoc/rc/tests.rs create mode 100644 src/liballoc/sync/tests.rs (limited to 'src/liballoc') diff --git a/src/liballoc/alloc.rs b/src/liballoc/alloc.rs index cef2b5eea34..dc7fd1adc29 100644 --- a/src/liballoc/alloc.rs +++ b/src/liballoc/alloc.rs @@ -10,6 +10,9 @@ use core::usize; #[doc(inline)] pub use core::alloc::*; +#[cfg(test)] +mod tests; + extern "Rust" { // These are the magic symbols to call the global allocator. rustc generates // them from the `#[global_allocator]` attribute if there is one, or uses the @@ -244,36 +247,3 @@ pub fn handle_alloc_error(layout: Layout) -> ! { } unsafe { oom_impl(layout) } } - -#[cfg(test)] -mod tests { - extern crate test; - use test::Bencher; - use crate::boxed::Box; - use crate::alloc::{Global, Alloc, Layout, handle_alloc_error}; - - #[test] - fn allocate_zeroed() { - unsafe { - let layout = Layout::from_size_align(1024, 1).unwrap(); - let ptr = Global.alloc_zeroed(layout.clone()) - .unwrap_or_else(|_| handle_alloc_error(layout)); - - let mut i = ptr.cast::().as_ptr(); - let end = i.add(layout.size()); - while i < end { - assert_eq!(*i, 0); - i = i.offset(1); - } - Global.dealloc(ptr, layout); - } - } - - #[bench] - #[cfg(not(miri))] // Miri does not support benchmarks - fn alloc_owned_small(b: &mut Bencher) { - b.iter(|| { - let _: Box<_> = box 10; - }) - } -} diff --git a/src/liballoc/alloc/tests.rs b/src/liballoc/alloc/tests.rs new file mode 100644 index 00000000000..c69f4e49ee1 --- /dev/null +++ b/src/liballoc/alloc/tests.rs @@ -0,0 +1,30 @@ +use super::*; + +extern crate test; +use test::Bencher; +use crate::boxed::Box; + +#[test] +fn allocate_zeroed() { + unsafe { + let layout = Layout::from_size_align(1024, 1).unwrap(); + let ptr = Global.alloc_zeroed(layout.clone()) + .unwrap_or_else(|_| handle_alloc_error(layout)); + + let mut i = ptr.cast::().as_ptr(); + let end = i.add(layout.size()); + while i < end { + assert_eq!(*i, 0); + i = i.offset(1); + } + Global.dealloc(ptr, layout); + } +} + +#[bench] +#[cfg(not(miri))] // Miri does not support benchmarks +fn alloc_owned_small(b: &mut Bencher) { + b.iter(|| { + let _: Box<_> = box 10; + }) +} diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs index bbb96725ea0..a14a3fe9994 100644 --- a/src/liballoc/collections/linked_list.rs +++ b/src/liballoc/collections/linked_list.rs @@ -23,6 +23,9 @@ use core::ptr::NonNull; use crate::boxed::Box; use super::SpecExtend; +#[cfg(test)] +mod tests; + /// A doubly-linked list with owned nodes. /// /// The `LinkedList` allows pushing and popping elements at either end @@ -1244,273 +1247,3 @@ unsafe impl Send for IterMut<'_, T> {} #[stable(feature = "rust1", since = "1.0.0")] unsafe impl Sync for IterMut<'_, T> {} - -#[cfg(test)] -mod tests { - use std::thread; - use std::vec::Vec; - - use rand::{thread_rng, RngCore}; - - use super::{LinkedList, Node}; - - #[cfg(test)] - fn list_from(v: &[T]) -> LinkedList { - v.iter().cloned().collect() - } - - pub fn check_links(list: &LinkedList) { - unsafe { - let mut len = 0; - let mut last_ptr: Option<&Node> = None; - let mut node_ptr: &Node; - match list.head { - None => { - // tail node should also be None. - assert!(list.tail.is_none()); - assert_eq!(0, list.len); - return; - } - Some(node) => node_ptr = &*node.as_ptr(), - } - loop { - match (last_ptr, node_ptr.prev) { - (None, None) => {} - (None, _) => panic!("prev link for head"), - (Some(p), Some(pptr)) => { - assert_eq!(p as *const Node, pptr.as_ptr() as *const Node); - } - _ => panic!("prev link is none, not good"), - } - match node_ptr.next { - Some(next) => { - last_ptr = Some(node_ptr); - node_ptr = &*next.as_ptr(); - len += 1; - } - None => { - len += 1; - break; - } - } - } - - // verify that the tail node points to the last node. - let tail = list.tail.as_ref().expect("some tail node").as_ref(); - assert_eq!(tail as *const Node, node_ptr as *const Node); - // check that len matches interior links. - assert_eq!(len, list.len); - } - } - - #[test] - fn test_append() { - // Empty to empty - { - let mut m = LinkedList::::new(); - let mut n = LinkedList::new(); - m.append(&mut n); - check_links(&m); - assert_eq!(m.len(), 0); - assert_eq!(n.len(), 0); - } - // Non-empty to empty - { - let mut m = LinkedList::new(); - let mut n = LinkedList::new(); - n.push_back(2); - m.append(&mut n); - check_links(&m); - assert_eq!(m.len(), 1); - assert_eq!(m.pop_back(), Some(2)); - assert_eq!(n.len(), 0); - check_links(&m); - } - // Empty to non-empty - { - let mut m = LinkedList::new(); - let mut n = LinkedList::new(); - m.push_back(2); - m.append(&mut n); - check_links(&m); - assert_eq!(m.len(), 1); - assert_eq!(m.pop_back(), Some(2)); - check_links(&m); - } - - // Non-empty to non-empty - let v = vec![1, 2, 3, 4, 5]; - let u = vec![9, 8, 1, 2, 3, 4, 5]; - let mut m = list_from(&v); - let mut n = list_from(&u); - m.append(&mut n); - check_links(&m); - let mut sum = v; - sum.extend_from_slice(&u); - assert_eq!(sum.len(), m.len()); - for elt in sum { - assert_eq!(m.pop_front(), Some(elt)) - } - assert_eq!(n.len(), 0); - // let's make sure it's working properly, since we - // did some direct changes to private members - n.push_back(3); - assert_eq!(n.len(), 1); - assert_eq!(n.pop_front(), Some(3)); - check_links(&n); - } - - #[test] - fn test_insert_prev() { - let mut m = list_from(&[0, 2, 4, 6, 8]); - let len = m.len(); - { - let mut it = m.iter_mut(); - it.insert_next(-2); - loop { - match it.next() { - None => break, - Some(elt) => { - it.insert_next(*elt + 1); - match it.peek_next() { - Some(x) => assert_eq!(*x, *elt + 2), - None => assert_eq!(8, *elt), - } - } - } - } - it.insert_next(0); - it.insert_next(1); - } - check_links(&m); - assert_eq!(m.len(), 3 + len * 2); - assert_eq!(m.into_iter().collect::>(), - [-2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1]); - } - - #[test] - #[cfg_attr(target_os = "emscripten", ignore)] - #[cfg(not(miri))] // Miri does not support threads - fn test_send() { - let n = list_from(&[1, 2, 3]); - thread::spawn(move || { - check_links(&n); - let a: &[_] = &[&1, &2, &3]; - assert_eq!(a, &*n.iter().collect::>()); - }) - .join() - .ok() - .unwrap(); - } - - #[test] - fn test_fuzz() { - for _ in 0..25 { - fuzz_test(3); - fuzz_test(16); - #[cfg(not(miri))] // Miri is too slow - fuzz_test(189); - } - } - - #[test] - fn test_26021() { - // There was a bug in split_off that failed to null out the RHS's head's prev ptr. - // This caused the RHS's dtor to walk up into the LHS at drop and delete all of - // its nodes. - // - // https://github.com/rust-lang/rust/issues/26021 - let mut v1 = LinkedList::new(); - v1.push_front(1); - v1.push_front(1); - v1.push_front(1); - v1.push_front(1); - let _ = v1.split_off(3); // Dropping this now should not cause laundry consumption - assert_eq!(v1.len(), 3); - - assert_eq!(v1.iter().len(), 3); - assert_eq!(v1.iter().collect::>().len(), 3); - } - - #[test] - fn test_split_off() { - let mut v1 = LinkedList::new(); - v1.push_front(1); - v1.push_front(1); - v1.push_front(1); - v1.push_front(1); - - // test all splits - for ix in 0..1 + v1.len() { - let mut a = v1.clone(); - let b = a.split_off(ix); - check_links(&a); - check_links(&b); - a.extend(b); - assert_eq!(v1, a); - } - } - - #[cfg(test)] - fn fuzz_test(sz: i32) { - let mut m: LinkedList<_> = LinkedList::new(); - let mut v = vec![]; - for i in 0..sz { - check_links(&m); - let r: u8 = thread_rng().next_u32() as u8; - match r % 6 { - 0 => { - m.pop_back(); - v.pop(); - } - 1 => { - if !v.is_empty() { - m.pop_front(); - v.remove(0); - } - } - 2 | 4 => { - m.push_front(-i); - v.insert(0, -i); - } - 3 | 5 | _ => { - m.push_back(i); - v.push(i); - } - } - } - - check_links(&m); - - let mut i = 0; - for (a, &b) in m.into_iter().zip(&v) { - i += 1; - assert_eq!(a, b); - } - assert_eq!(i, v.len()); - } - - #[test] - fn drain_filter_test() { - let mut m: LinkedList = LinkedList::new(); - m.extend(&[1, 2, 3, 4, 5, 6]); - let deleted = m.drain_filter(|v| *v < 4).collect::>(); - - check_links(&m); - - assert_eq!(deleted, &[1, 2, 3]); - assert_eq!(m.into_iter().collect::>(), &[4, 5, 6]); - } - - #[test] - fn drain_to_empty_test() { - let mut m: LinkedList = LinkedList::new(); - m.extend(&[1, 2, 3, 4, 5, 6]); - let deleted = m.drain_filter(|_| true).collect::>(); - - check_links(&m); - - assert_eq!(deleted, &[1, 2, 3, 4, 5, 6]); - assert_eq!(m.into_iter().collect::>(), &[]); - } -} diff --git a/src/liballoc/collections/linked_list/tests.rs b/src/liballoc/collections/linked_list/tests.rs new file mode 100644 index 00000000000..953b0d4eb28 --- /dev/null +++ b/src/liballoc/collections/linked_list/tests.rs @@ -0,0 +1,265 @@ +use super::*; + +use std::thread; +use std::vec::Vec; + +use rand::{thread_rng, RngCore}; + +fn list_from(v: &[T]) -> LinkedList { + v.iter().cloned().collect() +} + +pub fn check_links(list: &LinkedList) { + unsafe { + let mut len = 0; + let mut last_ptr: Option<&Node> = None; + let mut node_ptr: &Node; + match list.head { + None => { + // tail node should also be None. + assert!(list.tail.is_none()); + assert_eq!(0, list.len); + return; + } + Some(node) => node_ptr = &*node.as_ptr(), + } + loop { + match (last_ptr, node_ptr.prev) { + (None, None) => {} + (None, _) => panic!("prev link for head"), + (Some(p), Some(pptr)) => { + assert_eq!(p as *const Node, pptr.as_ptr() as *const Node); + } + _ => panic!("prev link is none, not good"), + } + match node_ptr.next { + Some(next) => { + last_ptr = Some(node_ptr); + node_ptr = &*next.as_ptr(); + len += 1; + } + None => { + len += 1; + break; + } + } + } + + // verify that the tail node points to the last node. + let tail = list.tail.as_ref().expect("some tail node").as_ref(); + assert_eq!(tail as *const Node, node_ptr as *const Node); + // check that len matches interior links. + assert_eq!(len, list.len); + } +} + +#[test] +fn test_append() { + // Empty to empty + { + let mut m = LinkedList::::new(); + let mut n = LinkedList::new(); + m.append(&mut n); + check_links(&m); + assert_eq!(m.len(), 0); + assert_eq!(n.len(), 0); + } + // Non-empty to empty + { + let mut m = LinkedList::new(); + let mut n = LinkedList::new(); + n.push_back(2); + m.append(&mut n); + check_links(&m); + assert_eq!(m.len(), 1); + assert_eq!(m.pop_back(), Some(2)); + assert_eq!(n.len(), 0); + check_links(&m); + } + // Empty to non-empty + { + let mut m = LinkedList::new(); + let mut n = LinkedList::new(); + m.push_back(2); + m.append(&mut n); + check_links(&m); + assert_eq!(m.len(), 1); + assert_eq!(m.pop_back(), Some(2)); + check_links(&m); + } + + // Non-empty to non-empty + let v = vec![1, 2, 3, 4, 5]; + let u = vec![9, 8, 1, 2, 3, 4, 5]; + let mut m = list_from(&v); + let mut n = list_from(&u); + m.append(&mut n); + check_links(&m); + let mut sum = v; + sum.extend_from_slice(&u); + assert_eq!(sum.len(), m.len()); + for elt in sum { + assert_eq!(m.pop_front(), Some(elt)) + } + assert_eq!(n.len(), 0); + // let's make sure it's working properly, since we + // did some direct changes to private members + n.push_back(3); + assert_eq!(n.len(), 1); + assert_eq!(n.pop_front(), Some(3)); + check_links(&n); +} + +#[test] +fn test_insert_prev() { + let mut m = list_from(&[0, 2, 4, 6, 8]); + let len = m.len(); + { + let mut it = m.iter_mut(); + it.insert_next(-2); + loop { + match it.next() { + None => break, + Some(elt) => { + it.insert_next(*elt + 1); + match it.peek_next() { + Some(x) => assert_eq!(*x, *elt + 2), + None => assert_eq!(8, *elt), + } + } + } + } + it.insert_next(0); + it.insert_next(1); + } + check_links(&m); + assert_eq!(m.len(), 3 + len * 2); + assert_eq!(m.into_iter().collect::>(), + [-2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1]); +} + +#[test] +#[cfg_attr(target_os = "emscripten", ignore)] +#[cfg(not(miri))] // Miri does not support threads +fn test_send() { + let n = list_from(&[1, 2, 3]); + thread::spawn(move || { + check_links(&n); + let a: &[_] = &[&1, &2, &3]; + assert_eq!(a, &*n.iter().collect::>()); + }) + .join() + .ok() + .unwrap(); +} + +#[test] +fn test_fuzz() { + for _ in 0..25 { + fuzz_test(3); + fuzz_test(16); + #[cfg(not(miri))] // Miri is too slow + fuzz_test(189); + } +} + +#[test] +fn test_26021() { + // There was a bug in split_off that failed to null out the RHS's head's prev ptr. + // This caused the RHS's dtor to walk up into the LHS at drop and delete all of + // its nodes. + // + // https://github.com/rust-lang/rust/issues/26021 + let mut v1 = LinkedList::new(); + v1.push_front(1); + v1.push_front(1); + v1.push_front(1); + v1.push_front(1); + let _ = v1.split_off(3); // Dropping this now should not cause laundry consumption + assert_eq!(v1.len(), 3); + + assert_eq!(v1.iter().len(), 3); + assert_eq!(v1.iter().collect::>().len(), 3); +} + +#[test] +fn test_split_off() { + let mut v1 = LinkedList::new(); + v1.push_front(1); + v1.push_front(1); + v1.push_front(1); + v1.push_front(1); + + // test all splits + for ix in 0..1 + v1.len() { + let mut a = v1.clone(); + let b = a.split_off(ix); + check_links(&a); + check_links(&b); + a.extend(b); + assert_eq!(v1, a); + } +} + +#[cfg(test)] +fn fuzz_test(sz: i32) { + let mut m: LinkedList<_> = LinkedList::new(); + let mut v = vec![]; + for i in 0..sz { + check_links(&m); + let r: u8 = thread_rng().next_u32() as u8; + match r % 6 { + 0 => { + m.pop_back(); + v.pop(); + } + 1 => { + if !v.is_empty() { + m.pop_front(); + v.remove(0); + } + } + 2 | 4 => { + m.push_front(-i); + v.insert(0, -i); + } + 3 | 5 | _ => { + m.push_back(i); + v.push(i); + } + } + } + + check_links(&m); + + let mut i = 0; + for (a, &b) in m.into_iter().zip(&v) { + i += 1; + assert_eq!(a, b); + } + assert_eq!(i, v.len()); +} + +#[test] +fn drain_filter_test() { + let mut m: LinkedList = LinkedList::new(); + m.extend(&[1, 2, 3, 4, 5, 6]); + let deleted = m.drain_filter(|v| *v < 4).collect::>(); + + check_links(&m); + + assert_eq!(deleted, &[1, 2, 3]); + assert_eq!(m.into_iter().collect::>(), &[4, 5, 6]); +} + +#[test] +fn drain_to_empty_test() { + let mut m: LinkedList = LinkedList::new(); + m.extend(&[1, 2, 3, 4, 5, 6]); + let deleted = m.drain_filter(|_| true).collect::>(); + + check_links(&m); + + assert_eq!(deleted, &[1, 2, 3, 4, 5, 6]); + assert_eq!(m.into_iter().collect::>(), &[]); +} diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index 495165f7786..9240346ace9 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -1,5 +1,3 @@ -// ignore-tidy-filelength - //! A double-ended queue implemented with a growable ring buffer. //! //! This queue has `O(1)` amortized inserts and removals from both ends of the @@ -24,6 +22,9 @@ use crate::collections::CollectionAllocErr; use crate::raw_vec::RawVec; use crate::vec::Vec; +#[cfg(test)] +mod tests; + const INITIAL_CAPACITY: usize = 7; // 2^3 - 1 const MINIMUM_CAPACITY: usize = 1; // 2 - 1 #[cfg(target_pointer_width = "16")] @@ -2838,387 +2839,3 @@ impl From> for Vec { } } } - -#[cfg(test)] -mod tests { - use ::test; - - use super::VecDeque; - - #[bench] - #[cfg(not(miri))] // Miri does not support benchmarks - fn bench_push_back_100(b: &mut test::Bencher) { - let mut deq = VecDeque::with_capacity(101); - b.iter(|| { - for i in 0..100 { - deq.push_back(i); - } - deq.head = 0; - deq.tail = 0; - }) - } - - #[bench] - #[cfg(not(miri))] // Miri does not support benchmarks - fn bench_push_front_100(b: &mut test::Bencher) { - let mut deq = VecDeque::with_capacity(101); - b.iter(|| { - for i in 0..100 { - deq.push_front(i); - } - deq.head = 0; - deq.tail = 0; - }) - } - - #[bench] - #[cfg(not(miri))] // Miri does not support benchmarks - fn bench_pop_back_100(b: &mut test::Bencher) { - let mut deq = VecDeque::::with_capacity(101); - - b.iter(|| { - deq.head = 100; - deq.tail = 0; - while !deq.is_empty() { - test::black_box(deq.pop_back()); - } - }) - } - - #[bench] - #[cfg(not(miri))] // Miri does not support benchmarks - fn bench_pop_front_100(b: &mut test::Bencher) { - let mut deq = VecDeque::::with_capacity(101); - - b.iter(|| { - deq.head = 100; - deq.tail = 0; - while !deq.is_empty() { - test::black_box(deq.pop_front()); - } - }) - } - - #[test] - fn test_swap_front_back_remove() { - fn test(back: bool) { - // This test checks that every single combination of tail position and length is tested. - // Capacity 15 should be large enough to cover every case. - let mut tester = VecDeque::with_capacity(15); - let usable_cap = tester.capacity(); - let final_len = usable_cap / 2; - - for len in 0..final_len { - let expected: VecDeque<_> = if back { - (0..len).collect() - } else { - (0..len).rev().collect() - }; - for tail_pos in 0..usable_cap { - tester.tail = tail_pos; - tester.head = tail_pos; - if back { - for i in 0..len * 2 { - tester.push_front(i); - } - for i in 0..len { - assert_eq!(tester.swap_remove_back(i), Some(len * 2 - 1 - i)); - } - } else { - for i in 0..len * 2 { - tester.push_back(i); - } - for i in 0..len { - let idx = tester.len() - 1 - i; - assert_eq!(tester.swap_remove_front(idx), Some(len * 2 - 1 - i)); - } - } - assert!(tester.tail < tester.cap()); - assert!(tester.head < tester.cap()); - assert_eq!(tester, expected); - } - } - } - test(true); - test(false); - } - - #[test] - fn test_insert() { - // This test checks that every single combination of tail position, length, and - // insertion position is tested. Capacity 15 should be large enough to cover every case. - - let mut tester = VecDeque::with_capacity(15); - // can't guarantee we got 15, so have to get what we got. - // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else - // this test isn't covering what it wants to - let cap = tester.capacity(); - - - // len is the length *after* insertion - for len in 1..cap { - // 0, 1, 2, .., len - 1 - let expected = (0..).take(len).collect::>(); - for tail_pos in 0..cap { - for to_insert in 0..len { - tester.tail = tail_pos; - tester.head = tail_pos; - for i in 0..len { - if i != to_insert { - tester.push_back(i); - } - } - tester.insert(to_insert, to_insert); - assert!(tester.tail < tester.cap()); - assert!(tester.head < tester.cap()); - assert_eq!(tester, expected); - } - } - } - } - - #[test] - fn test_remove() { - // This test checks that every single combination of tail position, length, and - // removal position is tested. Capacity 15 should be large enough to cover every case. - - let mut tester = VecDeque::with_capacity(15); - // can't guarantee we got 15, so have to get what we got. - // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else - // this test isn't covering what it wants to - let cap = tester.capacity(); - - // len is the length *after* removal - for len in 0..cap - 1 { - // 0, 1, 2, .., len - 1 - let expected = (0..).take(len).collect::>(); - for tail_pos in 0..cap { - for to_remove in 0..=len { - tester.tail = tail_pos; - tester.head = tail_pos; - for i in 0..len { - if i == to_remove { - tester.push_back(1234); - } - tester.push_back(i); - } - if to_remove == len { - tester.push_back(1234); - } - tester.remove(to_remove); - assert!(tester.tail < tester.cap()); - assert!(tester.head < tester.cap()); - assert_eq!(tester, expected); - } - } - } - } - - #[test] - fn test_drain() { - let mut tester: VecDeque = VecDeque::with_capacity(7); - - let cap = tester.capacity(); - for len in 0..=cap { - for tail in 0..=cap { - for drain_start in 0..=len { - for drain_end in drain_start..=len { - tester.tail = tail; - tester.head = tail; - for i in 0..len { - tester.push_back(i); - } - - // Check that we drain the correct values - let drained: VecDeque<_> = tester.drain(drain_start..drain_end).collect(); - let drained_expected: VecDeque<_> = (drain_start..drain_end).collect(); - assert_eq!(drained, drained_expected); - - // We shouldn't have changed the capacity or made the - // head or tail out of bounds - assert_eq!(tester.capacity(), cap); - assert!(tester.tail < tester.cap()); - assert!(tester.head < tester.cap()); - - // We should see the correct values in the VecDeque - let expected: VecDeque<_> = (0..drain_start) - .chain(drain_end..len) - .collect(); - assert_eq!(expected, tester); - } - } - } - } - } - - #[test] - fn test_shrink_to_fit() { - // This test checks that every single combination of head and tail position, - // is tested. Capacity 15 should be large enough to cover every case. - - let mut tester = VecDeque::with_capacity(15); - // can't guarantee we got 15, so have to get what we got. - // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else - // this test isn't covering what it wants to - let cap = tester.capacity(); - tester.reserve(63); - let max_cap = tester.capacity(); - - for len in 0..=cap { - // 0, 1, 2, .., len - 1 - let expected = (0..).take(len).collect::>(); - for tail_pos in 0..=max_cap { - tester.tail = tail_pos; - tester.head = tail_pos; - tester.reserve(63); - for i in 0..len { - tester.push_back(i); - } - tester.shrink_to_fit(); - assert!(tester.capacity() <= cap); - assert!(tester.tail < tester.cap()); - assert!(tester.head < tester.cap()); - assert_eq!(tester, expected); - } - } - } - - #[test] - fn test_split_off() { - // This test checks that every single combination of tail position, length, and - // split position is tested. Capacity 15 should be large enough to cover every case. - - let mut tester = VecDeque::with_capacity(15); - // can't guarantee we got 15, so have to get what we got. - // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else - // this test isn't covering what it wants to - let cap = tester.capacity(); - - // len is the length *before* splitting - for len in 0..cap { - // index to split at - for at in 0..=len { - // 0, 1, 2, .., at - 1 (may be empty) - let expected_self = (0..).take(at).collect::>(); - // at, at + 1, .., len - 1 (may be empty) - let expected_other = (at..).take(len - at).collect::>(); - - for tail_pos in 0..cap { - tester.tail = tail_pos; - tester.head = tail_pos; - for i in 0..len { - tester.push_back(i); - } - let result = tester.split_off(at); - assert!(tester.tail < tester.cap()); - assert!(tester.head < tester.cap()); - assert!(result.tail < result.cap()); - assert!(result.head < result.cap()); - assert_eq!(tester, expected_self); - assert_eq!(result, expected_other); - } - } - } - } - - #[test] - fn test_from_vec() { - use crate::vec::Vec; - for cap in 0..35 { - for len in 0..=cap { - let mut vec = Vec::with_capacity(cap); - vec.extend(0..len); - - let vd = VecDeque::from(vec.clone()); - assert!(vd.cap().is_power_of_two()); - assert_eq!(vd.len(), vec.len()); - assert!(vd.into_iter().eq(vec)); - } - } - } - - #[test] - fn test_vec_from_vecdeque() { - use crate::vec::Vec; - - fn create_vec_and_test_convert(capacity: usize, offset: usize, len: usize) { - let mut vd = VecDeque::with_capacity(capacity); - for _ in 0..offset { - vd.push_back(0); - vd.pop_front(); - } - vd.extend(0..len); - - let vec: Vec<_> = Vec::from(vd.clone()); - assert_eq!(vec.len(), vd.len()); - assert!(vec.into_iter().eq(vd)); - } - - #[cfg(not(miri))] // Miri is too slow - let max_pwr = 7; - #[cfg(miri)] - let max_pwr = 5; - - for cap_pwr in 0..max_pwr { - // Make capacity as a (2^x)-1, so that the ring size is 2^x - let cap = (2i32.pow(cap_pwr) - 1) as usize; - - // In these cases there is enough free space to solve it with copies - for len in 0..((cap + 1) / 2) { - // Test contiguous cases - for offset in 0..(cap - len) { - create_vec_and_test_convert(cap, offset, len) - } - - // Test cases where block at end of buffer is bigger than block at start - for offset in (cap - len)..(cap - (len / 2)) { - create_vec_and_test_convert(cap, offset, len) - } - - // Test cases where block at start of buffer is bigger than block at end - for offset in (cap - (len / 2))..cap { - create_vec_and_test_convert(cap, offset, len) - } - } - - // Now there's not (necessarily) space to straighten the ring with simple copies, - // the ring will use swapping when: - // (cap + 1 - offset) > (cap + 1 - len) && (len - (cap + 1 - offset)) > (cap + 1 - len)) - // right block size > free space && left block size > free space - for len in ((cap + 1) / 2)..cap { - // Test contiguous cases - for offset in 0..(cap - len) { - create_vec_and_test_convert(cap, offset, len) - } - - // Test cases where block at end of buffer is bigger than block at start - for offset in (cap - len)..(cap - (len / 2)) { - create_vec_and_test_convert(cap, offset, len) - } - - // Test cases where block at start of buffer is bigger than block at end - for offset in (cap - (len / 2))..cap { - create_vec_and_test_convert(cap, offset, len) - } - } - } - } - - #[test] - fn issue_53529() { - use crate::boxed::Box; - - let mut dst = VecDeque::new(); - dst.push_front(Box::new(1)); - dst.push_front(Box::new(2)); - assert_eq!(*dst.pop_back().unwrap(), 1); - - let mut src = VecDeque::new(); - src.push_front(Box::new(2)); - dst.append(&mut src); - for a in dst { - assert_eq!(*a, 2); - } - } - -} diff --git a/src/liballoc/collections/vec_deque/tests.rs b/src/liballoc/collections/vec_deque/tests.rs new file mode 100644 index 00000000000..d2535239979 --- /dev/null +++ b/src/liballoc/collections/vec_deque/tests.rs @@ -0,0 +1,379 @@ +use super::*; + +use ::test; + +#[bench] +#[cfg(not(miri))] // Miri does not support benchmarks +fn bench_push_back_100(b: &mut test::Bencher) { + let mut deq = VecDeque::with_capacity(101); + b.iter(|| { + for i in 0..100 { + deq.push_back(i); + } + deq.head = 0; + deq.tail = 0; + }) +} + +#[bench] +#[cfg(not(miri))] // Miri does not support benchmarks +fn bench_push_front_100(b: &mut test::Bencher) { + let mut deq = VecDeque::with_capacity(101); + b.iter(|| { + for i in 0..100 { + deq.push_front(i); + } + deq.head = 0; + deq.tail = 0; + }) +} + +#[bench] +#[cfg(not(miri))] // Miri does not support benchmarks +fn bench_pop_back_100(b: &mut test::Bencher) { + let mut deq = VecDeque::::with_capacity(101); + + b.iter(|| { + deq.head = 100; + deq.tail = 0; + while !deq.is_empty() { + test::black_box(deq.pop_back()); + } + }) +} + +#[bench] +#[cfg(not(miri))] // Miri does not support benchmarks +fn bench_pop_front_100(b: &mut test::Bencher) { + let mut deq = VecDeque::::with_capacity(101); + + b.iter(|| { + deq.head = 100; + deq.tail = 0; + while !deq.is_empty() { + test::black_box(deq.pop_front()); + } + }) +} + +#[test] +fn test_swap_front_back_remove() { + fn test(back: bool) { + // This test checks that every single combination of tail position and length is tested. + // Capacity 15 should be large enough to cover every case. + let mut tester = VecDeque::with_capacity(15); + let usable_cap = tester.capacity(); + let final_len = usable_cap / 2; + + for len in 0..final_len { + let expected: VecDeque<_> = if back { + (0..len).collect() + } else { + (0..len).rev().collect() + }; + for tail_pos in 0..usable_cap { + tester.tail = tail_pos; + tester.head = tail_pos; + if back { + for i in 0..len * 2 { + tester.push_front(i); + } + for i in 0..len { + assert_eq!(tester.swap_remove_back(i), Some(len * 2 - 1 - i)); + } + } else { + for i in 0..len * 2 { + tester.push_back(i); + } + for i in 0..len { + let idx = tester.len() - 1 - i; + assert_eq!(tester.swap_remove_front(idx), Some(len * 2 - 1 - i)); + } + } + assert!(tester.tail < tester.cap()); + assert!(tester.head < tester.cap()); + assert_eq!(tester, expected); + } + } + } + test(true); + test(false); +} + +#[test] +fn test_insert() { + // This test checks that every single combination of tail position, length, and + // insertion position is tested. Capacity 15 should be large enough to cover every case. + + let mut tester = VecDeque::with_capacity(15); + // can't guarantee we got 15, so have to get what we got. + // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else + // this test isn't covering what it wants to + let cap = tester.capacity(); + + + // len is the length *after* insertion + for len in 1..cap { + // 0, 1, 2, .., len - 1 + let expected = (0..).take(len).collect::>(); + for tail_pos in 0..cap { + for to_insert in 0..len { + tester.tail = tail_pos; + tester.head = tail_pos; + for i in 0..len { + if i != to_insert { + tester.push_back(i); + } + } + tester.insert(to_insert, to_insert); + assert!(tester.tail < tester.cap()); + assert!(tester.head < tester.cap()); + assert_eq!(tester, expected); + } + } + } +} + +#[test] +fn test_remove() { + // This test checks that every single combination of tail position, length, and + // removal position is tested. Capacity 15 should be large enough to cover every case. + + let mut tester = VecDeque::with_capacity(15); + // can't guarantee we got 15, so have to get what we got. + // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else + // this test isn't covering what it wants to + let cap = tester.capacity(); + + // len is the length *after* removal + for len in 0..cap - 1 { + // 0, 1, 2, .., len - 1 + let expected = (0..).take(len).collect::>(); + for tail_pos in 0..cap { + for to_remove in 0..=len { + tester.tail = tail_pos; + tester.head = tail_pos; + for i in 0..len { + if i == to_remove { + tester.push_back(1234); + } + tester.push_back(i); + } + if to_remove == len { + tester.push_back(1234); + } + tester.remove(to_remove); + assert!(tester.tail < tester.cap()); + assert!(tester.head < tester.cap()); + assert_eq!(tester, expected); + } + } + } +} + +#[test] +fn test_drain() { + let mut tester: VecDeque = VecDeque::with_capacity(7); + + let cap = tester.capacity(); + for len in 0..=cap { + for tail in 0..=cap { + for drain_start in 0..=len { + for drain_end in drain_start..=len { + tester.tail = tail; + tester.head = tail; + for i in 0..len { + tester.push_back(i); + } + + // Check that we drain the correct values + let drained: VecDeque<_> = tester.drain(drain_start..drain_end).collect(); + let drained_expected: VecDeque<_> = (drain_start..drain_end).collect(); + assert_eq!(drained, drained_expected); + + // We shouldn't have changed the capacity or made the + // head or tail out of bounds + assert_eq!(tester.capacity(), cap); + assert!(tester.tail < tester.cap()); + assert!(tester.head < tester.cap()); + + // We should see the correct values in the VecDeque + let expected: VecDeque<_> = (0..drain_start) + .chain(drain_end..len) + .collect(); + assert_eq!(expected, tester); + } + } + } + } +} + +#[test] +fn test_shrink_to_fit() { + // This test checks that every single combination of head and tail position, + // is tested. Capacity 15 should be large enough to cover every case. + + let mut tester = VecDeque::with_capacity(15); + // can't guarantee we got 15, so have to get what we got. + // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else + // this test isn't covering what it wants to + let cap = tester.capacity(); + tester.reserve(63); + let max_cap = tester.capacity(); + + for len in 0..=cap { + // 0, 1, 2, .., len - 1 + let expected = (0..).take(len).collect::>(); + for tail_pos in 0..=max_cap { + tester.tail = tail_pos; + tester.head = tail_pos; + tester.reserve(63); + for i in 0..len { + tester.push_back(i); + } + tester.shrink_to_fit(); + assert!(tester.capacity() <= cap); + assert!(tester.tail < tester.cap()); + assert!(tester.head < tester.cap()); + assert_eq!(tester, expected); + } + } +} + +#[test] +fn test_split_off() { + // This test checks that every single combination of tail position, length, and + // split position is tested. Capacity 15 should be large enough to cover every case. + + let mut tester = VecDeque::with_capacity(15); + // can't guarantee we got 15, so have to get what we got. + // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else + // this test isn't covering what it wants to + let cap = tester.capacity(); + + // len is the length *before* splitting + for len in 0..cap { + // index to split at + for at in 0..=len { + // 0, 1, 2, .., at - 1 (may be empty) + let expected_self = (0..).take(at).collect::>(); + // at, at + 1, .., len - 1 (may be empty) + let expected_other = (at..).take(len - at).collect::>(); + + for tail_pos in 0..cap { + tester.tail = tail_pos; + tester.head = tail_pos; + for i in 0..len { + tester.push_back(i); + } + let result = tester.split_off(at); + assert!(tester.tail < tester.cap()); + assert!(tester.head < tester.cap()); + assert!(result.tail < result.cap()); + assert!(result.head < result.cap()); + assert_eq!(tester, expected_self); + assert_eq!(result, expected_other); + } + } + } +} + +#[test] +fn test_from_vec() { + use crate::vec::Vec; + for cap in 0..35 { + for len in 0..=cap { + let mut vec = Vec::with_capacity(cap); + vec.extend(0..len); + + let vd = VecDeque::from(vec.clone()); + assert!(vd.cap().is_power_of_two()); + assert_eq!(vd.len(), vec.len()); + assert!(vd.into_iter().eq(vec)); + } + } +} + +#[test] +fn test_vec_from_vecdeque() { + use crate::vec::Vec; + + fn create_vec_and_test_convert(capacity: usize, offset: usize, len: usize) { + let mut vd = VecDeque::with_capacity(capacity); + for _ in 0..offset { + vd.push_back(0); + vd.pop_front(); + } + vd.extend(0..len); + + let vec: Vec<_> = Vec::from(vd.clone()); + assert_eq!(vec.len(), vd.len()); + assert!(vec.into_iter().eq(vd)); + } + + #[cfg(not(miri))] // Miri is too slow + let max_pwr = 7; + #[cfg(miri)] + let max_pwr = 5; + + for cap_pwr in 0..max_pwr { + // Make capacity as a (2^x)-1, so that the ring size is 2^x + let cap = (2i32.pow(cap_pwr) - 1) as usize; + + // In these cases there is enough free space to solve it with copies + for len in 0..((cap + 1) / 2) { + // Test contiguous cases + for offset in 0..(cap - len) { + create_vec_and_test_convert(cap, offset, len) + } + + // Test cases where block at end of buffer is bigger than block at start + for offset in (cap - len)..(cap - (len / 2)) { + create_vec_and_test_convert(cap, offset, len) + } + + // Test cases where block at start of buffer is bigger than block at end + for offset in (cap - (len / 2))..cap { + create_vec_and_test_convert(cap, offset, len) + } + } + + // Now there's not (necessarily) space to straighten the ring with simple copies, + // the ring will use swapping when: + // (cap + 1 - offset) > (cap + 1 - len) && (len - (cap + 1 - offset)) > (cap + 1 - len)) + // right block size > free space && left block size > free space + for len in ((cap + 1) / 2)..cap { + // Test contiguous cases + for offset in 0..(cap - len) { + create_vec_and_test_convert(cap, offset, len) + } + + // Test cases where block at end of buffer is bigger than block at start + for offset in (cap - len)..(cap - (len / 2)) { + create_vec_and_test_convert(cap, offset, len) + } + + // Test cases where block at start of buffer is bigger than block at end + for offset in (cap - (len / 2))..cap { + create_vec_and_test_convert(cap, offset, len) + } + } + } +} + +#[test] +fn issue_53529() { + use crate::boxed::Box; + + let mut dst = VecDeque::new(); + dst.push_front(Box::new(1)); + dst.push_front(Box::new(2)); + assert_eq!(*dst.pop_back().unwrap(), 1); + + let mut src = VecDeque::new(); + src.push_front(Box::new(2)); + dst.append(&mut src); + for a in dst { + assert_eq!(*a, 2); + } +} diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs index 24336db6b25..0abab45e920 100644 --- a/src/liballoc/raw_vec.rs +++ b/src/liballoc/raw_vec.rs @@ -11,6 +11,9 @@ use crate::alloc::{Alloc, Layout, Global, handle_alloc_error}; use crate::collections::CollectionAllocErr::{self, *}; use crate::boxed::Box; +#[cfg(test)] +mod tests; + /// A low-level utility for more ergonomically allocating, reallocating, and deallocating /// a buffer of memory on the heap without having to worry about all the corner cases /// involved. This type is excellent for building your own data structures like Vec and VecDeque. @@ -748,82 +751,3 @@ fn alloc_guard(alloc_size: usize) -> Result<(), CollectionAllocErr> { fn capacity_overflow() -> ! { panic!("capacity overflow") } - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn allocator_param() { - use crate::alloc::AllocErr; - - // Writing a test of integration between third-party - // allocators and RawVec is a little tricky because the RawVec - // API does not expose fallible allocation methods, so we - // cannot check what happens when allocator is exhausted - // (beyond detecting a panic). - // - // Instead, this just checks that the RawVec methods do at - // least go through the Allocator API when it reserves - // storage. - - // A dumb allocator that consumes a fixed amount of fuel - // before allocation attempts start failing. - struct BoundedAlloc { fuel: usize } - unsafe impl Alloc for BoundedAlloc { - unsafe fn alloc(&mut self, layout: Layout) -> Result, AllocErr> { - let size = layout.size(); - if size > self.fuel { - return Err(AllocErr); - } - match Global.alloc(layout) { - ok @ Ok(_) => { self.fuel -= size; ok } - err @ Err(_) => err, - } - } - unsafe fn dealloc(&mut self, ptr: NonNull, layout: Layout) { - Global.dealloc(ptr, layout) - } - } - - let a = BoundedAlloc { fuel: 500 }; - let mut v: RawVec = RawVec::with_capacity_in(50, a); - assert_eq!(v.a.fuel, 450); - v.reserve(50, 150); // (causes a realloc, thus using 50 + 150 = 200 units of fuel) - assert_eq!(v.a.fuel, 250); - } - - #[test] - fn reserve_does_not_overallocate() { - { - let mut v: RawVec = RawVec::new(); - // First `reserve` allocates like `reserve_exact` - v.reserve(0, 9); - assert_eq!(9, v.capacity()); - } - - { - let mut v: RawVec = RawVec::new(); - v.reserve(0, 7); - assert_eq!(7, v.capacity()); - // 97 if more than double of 7, so `reserve` should work - // like `reserve_exact`. - v.reserve(7, 90); - assert_eq!(97, v.capacity()); - } - - { - let mut v: RawVec = RawVec::new(); - v.reserve(0, 12); - assert_eq!(12, v.capacity()); - v.reserve(12, 3); - // 3 is less than half of 12, so `reserve` must grow - // exponentially. At the time of writing this test grow - // factor is 2, so new capacity is 24, however, grow factor - // of 1.5 is OK too. Hence `>= 18` in assert. - assert!(v.capacity() >= 12 + 12 / 2); - } - } - - -} diff --git a/src/liballoc/raw_vec/tests.rs b/src/liballoc/raw_vec/tests.rs new file mode 100644 index 00000000000..c389898d1ef --- /dev/null +++ b/src/liballoc/raw_vec/tests.rs @@ -0,0 +1,73 @@ +use super::*; + +#[test] +fn allocator_param() { + use crate::alloc::AllocErr; + + // Writing a test of integration between third-party + // allocators and RawVec is a little tricky because the RawVec + // API does not expose fallible allocation methods, so we + // cannot check what happens when allocator is exhausted + // (beyond detecting a panic). + // + // Instead, this just checks that the RawVec methods do at + // least go through the Allocator API when it reserves + // storage. + + // A dumb allocator that consumes a fixed amount of fuel + // before allocation attempts start failing. + struct BoundedAlloc { fuel: usize } + unsafe impl Alloc for BoundedAlloc { + unsafe fn alloc(&mut self, layout: Layout) -> Result, AllocErr> { + let size = layout.size(); + if size > self.fuel { + return Err(AllocErr); + } + match Global.alloc(layout) { + ok @ Ok(_) => { self.fuel -= size; ok } + err @ Err(_) => err, + } + } + unsafe fn dealloc(&mut self, ptr: NonNull, layout: Layout) { + Global.dealloc(ptr, layout) + } + } + + let a = BoundedAlloc { fuel: 500 }; + let mut v: RawVec = RawVec::with_capacity_in(50, a); + assert_eq!(v.a.fuel, 450); + v.reserve(50, 150); // (causes a realloc, thus using 50 + 150 = 200 units of fuel) + assert_eq!(v.a.fuel, 250); +} + +#[test] +fn reserve_does_not_overallocate() { + { + let mut v: RawVec = RawVec::new(); + // First `reserve` allocates like `reserve_exact` + v.reserve(0, 9); + assert_eq!(9, v.capacity()); + } + + { + let mut v: RawVec = RawVec::new(); + v.reserve(0, 7); + assert_eq!(7, v.capacity()); + // 97 if more than double of 7, so `reserve` should work + // like `reserve_exact`. + v.reserve(7, 90); + assert_eq!(97, v.capacity()); + } + + { + let mut v: RawVec = RawVec::new(); + v.reserve(0, 12); + assert_eq!(12, v.capacity()); + v.reserve(12, 3); + // 3 is less than half of 12, so `reserve` must grow + // exponentially. At the time of writing this test grow + // factor is 2, so new capacity is 24, however, grow factor + // of 1.5 is OK too. Hence `>= 18` in assert. + assert!(v.capacity() >= 12 + 12 / 2); + } +} diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 0d0ff7c16f1..e33aac3af47 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -252,6 +252,9 @@ use crate::alloc::{Global, Alloc, Layout, box_free, handle_alloc_error}; use crate::string::String; use crate::vec::Vec; +#[cfg(test)] +mod tests; + struct RcBox { strong: Cell, weak: Cell, @@ -1851,436 +1854,6 @@ impl RcBoxPtr for RcBox { } } -#[cfg(test)] -mod tests { - use super::{Rc, Weak}; - use std::boxed::Box; - use std::cell::RefCell; - use std::option::Option::{self, None, Some}; - use std::result::Result::{Err, Ok}; - use std::mem::drop; - use std::clone::Clone; - use std::convert::From; - - #[test] - fn test_clone() { - let x = Rc::new(RefCell::new(5)); - let y = x.clone(); - *x.borrow_mut() = 20; - assert_eq!(*y.borrow(), 20); - } - - #[test] - fn test_simple() { - let x = Rc::new(5); - assert_eq!(*x, 5); - } - - #[test] - fn test_simple_clone() { - let x = Rc::new(5); - let y = x.clone(); - assert_eq!(*x, 5); - assert_eq!(*y, 5); - } - - #[test] - fn test_destructor() { - let x: Rc> = Rc::new(box 5); - assert_eq!(**x, 5); - } - - #[test] - fn test_live() { - let x = Rc::new(5); - let y = Rc::downgrade(&x); - assert!(y.upgrade().is_some()); - } - - #[test] - fn test_dead() { - let x = Rc::new(5); - let y = Rc::downgrade(&x); - drop(x); - assert!(y.upgrade().is_none()); - } - - #[test] - fn weak_self_cyclic() { - struct Cycle { - x: RefCell>>, - } - - let a = Rc::new(Cycle { x: RefCell::new(None) }); - let b = Rc::downgrade(&a.clone()); - *a.x.borrow_mut() = Some(b); - - // hopefully we don't double-free (or leak)... - } - - #[test] - fn is_unique() { - let x = Rc::new(3); - assert!(Rc::is_unique(&x)); - let y = x.clone(); - assert!(!Rc::is_unique(&x)); - drop(y); - assert!(Rc::is_unique(&x)); - let w = Rc::downgrade(&x); - assert!(!Rc::is_unique(&x)); - drop(w); - assert!(Rc::is_unique(&x)); - } - - #[test] - fn test_strong_count() { - let a = Rc::new(0); - assert!(Rc::strong_count(&a) == 1); - let w = Rc::downgrade(&a); - assert!(Rc::strong_count(&a) == 1); - let b = w.upgrade().expect("upgrade of live rc failed"); - assert!(Rc::strong_count(&b) == 2); - assert!(Rc::strong_count(&a) == 2); - drop(w); - drop(a); - assert!(Rc::strong_count(&b) == 1); - let c = b.clone(); - assert!(Rc::strong_count(&b) == 2); - assert!(Rc::strong_count(&c) == 2); - } - - #[test] - fn test_weak_count() { - let a = Rc::new(0); - assert!(Rc::strong_count(&a) == 1); - assert!(Rc::weak_count(&a) == 0); - let w = Rc::downgrade(&a); - assert!(Rc::strong_count(&a) == 1); - assert!(Rc::weak_count(&a) == 1); - drop(w); - assert!(Rc::strong_count(&a) == 1); - assert!(Rc::weak_count(&a) == 0); - let c = a.clone(); - assert!(Rc::strong_count(&a) == 2); - assert!(Rc::weak_count(&a) == 0); - drop(c); - } - - #[test] - fn weak_counts() { - assert_eq!(Weak::weak_count(&Weak::::new()), None); - assert_eq!(Weak::strong_count(&Weak::::new()), 0); - - let a = Rc::new(0); - let w = Rc::downgrade(&a); - assert_eq!(Weak::strong_count(&w), 1); - assert_eq!(Weak::weak_count(&w), Some(1)); - let w2 = w.clone(); - assert_eq!(Weak::strong_count(&w), 1); - assert_eq!(Weak::weak_count(&w), Some(2)); - assert_eq!(Weak::strong_count(&w2), 1); - assert_eq!(Weak::weak_count(&w2), Some(2)); - drop(w); - assert_eq!(Weak::strong_count(&w2), 1); - assert_eq!(Weak::weak_count(&w2), Some(1)); - let a2 = a.clone(); - assert_eq!(Weak::strong_count(&w2), 2); - assert_eq!(Weak::weak_count(&w2), Some(1)); - drop(a2); - drop(a); - assert_eq!(Weak::strong_count(&w2), 0); - assert_eq!(Weak::weak_count(&w2), Some(1)); - drop(w2); - } - - #[test] - fn try_unwrap() { - let x = Rc::new(3); - assert_eq!(Rc::try_unwrap(x), Ok(3)); - let x = Rc::new(4); - let _y = x.clone(); - assert_eq!(Rc::try_unwrap(x), Err(Rc::new(4))); - let x = Rc::new(5); - let _w = Rc::downgrade(&x); - assert_eq!(Rc::try_unwrap(x), Ok(5)); - } - - #[test] - fn into_from_raw() { - let x = Rc::new(box "hello"); - let y = x.clone(); - - let x_ptr = Rc::into_raw(x); - drop(y); - unsafe { - assert_eq!(**x_ptr, "hello"); - - let x = Rc::from_raw(x_ptr); - assert_eq!(**x, "hello"); - - assert_eq!(Rc::try_unwrap(x).map(|x| *x), Ok("hello")); - } - } - - #[test] - fn test_into_from_raw_unsized() { - use std::fmt::Display; - use std::string::ToString; - - let rc: Rc = Rc::from("foo"); - - let ptr = Rc::into_raw(rc.clone()); - let rc2 = unsafe { Rc::from_raw(ptr) }; - - assert_eq!(unsafe { &*ptr }, "foo"); - assert_eq!(rc, rc2); - - let rc: Rc = Rc::new(123); - - let ptr = Rc::into_raw(rc.clone()); - let rc2 = unsafe { Rc::from_raw(ptr) }; - - assert_eq!(unsafe { &*ptr }.to_string(), "123"); - assert_eq!(rc2.to_string(), "123"); - } - - #[test] - fn get_mut() { - let mut x = Rc::new(3); - *Rc::get_mut(&mut x).unwrap() = 4; - assert_eq!(*x, 4); - let y = x.clone(); - assert!(Rc::get_mut(&mut x).is_none()); - drop(y); - assert!(Rc::get_mut(&mut x).is_some()); - let _w = Rc::downgrade(&x); - assert!(Rc::get_mut(&mut x).is_none()); - } - - #[test] - fn test_cowrc_clone_make_unique() { - let mut cow0 = Rc::new(75); - let mut cow1 = cow0.clone(); - let mut cow2 = cow1.clone(); - - assert!(75 == *Rc::make_mut(&mut cow0)); - assert!(75 == *Rc::make_mut(&mut cow1)); - assert!(75 == *Rc::make_mut(&mut cow2)); - - *Rc::make_mut(&mut cow0) += 1; - *Rc::make_mut(&mut cow1) += 2; - *Rc::make_mut(&mut cow2) += 3; - - assert!(76 == *cow0); - assert!(77 == *cow1); - assert!(78 == *cow2); - - // none should point to the same backing memory - assert!(*cow0 != *cow1); - assert!(*cow0 != *cow2); - assert!(*cow1 != *cow2); - } - - #[test] - fn test_cowrc_clone_unique2() { - let mut cow0 = Rc::new(75); - let cow1 = cow0.clone(); - let cow2 = cow1.clone(); - - assert!(75 == *cow0); - assert!(75 == *cow1); - assert!(75 == *cow2); - - *Rc::make_mut(&mut cow0) += 1; - - assert!(76 == *cow0); - assert!(75 == *cow1); - assert!(75 == *cow2); - - // cow1 and cow2 should share the same contents - // cow0 should have a unique reference - assert!(*cow0 != *cow1); - assert!(*cow0 != *cow2); - assert!(*cow1 == *cow2); - } - - #[test] - fn test_cowrc_clone_weak() { - let mut cow0 = Rc::new(75); - let cow1_weak = Rc::downgrade(&cow0); - - assert!(75 == *cow0); - assert!(75 == *cow1_weak.upgrade().unwrap()); - - *Rc::make_mut(&mut cow0) += 1; - - assert!(76 == *cow0); - assert!(cow1_weak.upgrade().is_none()); - } - - #[test] - fn test_show() { - let foo = Rc::new(75); - assert_eq!(format!("{:?}", foo), "75"); - } - - #[test] - fn test_unsized() { - let foo: Rc<[i32]> = Rc::new([1, 2, 3]); - assert_eq!(foo, foo.clone()); - } - - #[test] - fn test_from_owned() { - let foo = 123; - let foo_rc = Rc::from(foo); - assert!(123 == *foo_rc); - } - - #[test] - fn test_new_weak() { - let foo: Weak = Weak::new(); - assert!(foo.upgrade().is_none()); - } - - #[test] - fn test_ptr_eq() { - let five = Rc::new(5); - let same_five = five.clone(); - let other_five = Rc::new(5); - - assert!(Rc::ptr_eq(&five, &same_five)); - assert!(!Rc::ptr_eq(&five, &other_five)); - } - - #[test] - fn test_from_str() { - let r: Rc = Rc::from("foo"); - - assert_eq!(&r[..], "foo"); - } - - #[test] - fn test_copy_from_slice() { - let s: &[u32] = &[1, 2, 3]; - let r: Rc<[u32]> = Rc::from(s); - - assert_eq!(&r[..], [1, 2, 3]); - } - - #[test] - fn test_clone_from_slice() { - #[derive(Clone, Debug, Eq, PartialEq)] - struct X(u32); - - let s: &[X] = &[X(1), X(2), X(3)]; - let r: Rc<[X]> = Rc::from(s); - - assert_eq!(&r[..], s); - } - - #[test] - #[should_panic] - fn test_clone_from_slice_panic() { - use std::string::{String, ToString}; - - struct Fail(u32, String); - - impl Clone for Fail { - fn clone(&self) -> Fail { - if self.0 == 2 { - panic!(); - } - Fail(self.0, self.1.clone()) - } - } - - let s: &[Fail] = &[ - Fail(0, "foo".to_string()), - Fail(1, "bar".to_string()), - Fail(2, "baz".to_string()), - ]; - - // Should panic, but not cause memory corruption - let _r: Rc<[Fail]> = Rc::from(s); - } - - #[test] - fn test_from_box() { - let b: Box = box 123; - let r: Rc = Rc::from(b); - - assert_eq!(*r, 123); - } - - #[test] - fn test_from_box_str() { - use std::string::String; - - let s = String::from("foo").into_boxed_str(); - let r: Rc = Rc::from(s); - - assert_eq!(&r[..], "foo"); - } - - #[test] - fn test_from_box_slice() { - let s = vec![1, 2, 3].into_boxed_slice(); - let r: Rc<[u32]> = Rc::from(s); - - assert_eq!(&r[..], [1, 2, 3]); - } - - #[test] - fn test_from_box_trait() { - use std::fmt::Display; - use std::string::ToString; - - let b: Box = box 123; - let r: Rc = Rc::from(b); - - assert_eq!(r.to_string(), "123"); - } - - #[test] - fn test_from_box_trait_zero_sized() { - use std::fmt::Debug; - - let b: Box = box (); - let r: Rc = Rc::from(b); - - assert_eq!(format!("{:?}", r), "()"); - } - - #[test] - fn test_from_vec() { - let v = vec![1, 2, 3]; - let r: Rc<[u32]> = Rc::from(v); - - assert_eq!(&r[..], [1, 2, 3]); - } - - #[test] - fn test_downcast() { - use std::any::Any; - - let r1: Rc = Rc::new(i32::max_value()); - let r2: Rc = Rc::new("abc"); - - assert!(r1.clone().downcast::().is_err()); - - let r1i32 = r1.downcast::(); - assert!(r1i32.is_ok()); - assert_eq!(r1i32.unwrap(), Rc::new(i32::max_value())); - - assert!(r2.clone().downcast::().is_err()); - - let r2str = r2.downcast::<&'static str>(); - assert!(r2str.is_ok()); - assert_eq!(r2str.unwrap(), Rc::new("abc")); - } -} - #[stable(feature = "rust1", since = "1.0.0")] impl borrow::Borrow for Rc { fn borrow(&self) -> &T { diff --git a/src/liballoc/rc/tests.rs b/src/liballoc/rc/tests.rs new file mode 100644 index 00000000000..72816a5c120 --- /dev/null +++ b/src/liballoc/rc/tests.rs @@ -0,0 +1,427 @@ +use super::*; + +use std::boxed::Box; +use std::cell::RefCell; +use std::option::Option::{self, None, Some}; +use std::result::Result::{Err, Ok}; +use std::mem::drop; +use std::clone::Clone; +use std::convert::From; + +#[test] +fn test_clone() { + let x = Rc::new(RefCell::new(5)); + let y = x.clone(); + *x.borrow_mut() = 20; + assert_eq!(*y.borrow(), 20); +} + +#[test] +fn test_simple() { + let x = Rc::new(5); + assert_eq!(*x, 5); +} + +#[test] +fn test_simple_clone() { + let x = Rc::new(5); + let y = x.clone(); + assert_eq!(*x, 5); + assert_eq!(*y, 5); +} + +#[test] +fn test_destructor() { + let x: Rc> = Rc::new(box 5); + assert_eq!(**x, 5); +} + +#[test] +fn test_live() { + let x = Rc::new(5); + let y = Rc::downgrade(&x); + assert!(y.upgrade().is_some()); +} + +#[test] +fn test_dead() { + let x = Rc::new(5); + let y = Rc::downgrade(&x); + drop(x); + assert!(y.upgrade().is_none()); +} + +#[test] +fn weak_self_cyclic() { + struct Cycle { + x: RefCell>>, + } + + let a = Rc::new(Cycle { x: RefCell::new(None) }); + let b = Rc::downgrade(&a.clone()); + *a.x.borrow_mut() = Some(b); + + // hopefully we don't double-free (or leak)... +} + +#[test] +fn is_unique() { + let x = Rc::new(3); + assert!(Rc::is_unique(&x)); + let y = x.clone(); + assert!(!Rc::is_unique(&x)); + drop(y); + assert!(Rc::is_unique(&x)); + let w = Rc::downgrade(&x); + assert!(!Rc::is_unique(&x)); + drop(w); + assert!(Rc::is_unique(&x)); +} + +#[test] +fn test_strong_count() { + let a = Rc::new(0); + assert!(Rc::strong_count(&a) == 1); + let w = Rc::downgrade(&a); + assert!(Rc::strong_count(&a) == 1); + let b = w.upgrade().expect("upgrade of live rc failed"); + assert!(Rc::strong_count(&b) == 2); + assert!(Rc::strong_count(&a) == 2); + drop(w); + drop(a); + assert!(Rc::strong_count(&b) == 1); + let c = b.clone(); + assert!(Rc::strong_count(&b) == 2); + assert!(Rc::strong_count(&c) == 2); +} + +#[test] +fn test_weak_count() { + let a = Rc::new(0); + assert!(Rc::strong_count(&a) == 1); + assert!(Rc::weak_count(&a) == 0); + let w = Rc::downgrade(&a); + assert!(Rc::strong_count(&a) == 1); + assert!(Rc::weak_count(&a) == 1); + drop(w); + assert!(Rc::strong_count(&a) == 1); + assert!(Rc::weak_count(&a) == 0); + let c = a.clone(); + assert!(Rc::strong_count(&a) == 2); + assert!(Rc::weak_count(&a) == 0); + drop(c); +} + +#[test] +fn weak_counts() { + assert_eq!(Weak::weak_count(&Weak::::new()), None); + assert_eq!(Weak::strong_count(&Weak::::new()), 0); + + let a = Rc::new(0); + let w = Rc::downgrade(&a); + assert_eq!(Weak::strong_count(&w), 1); + assert_eq!(Weak::weak_count(&w), Some(1)); + let w2 = w.clone(); + assert_eq!(Weak::strong_count(&w), 1); + assert_eq!(Weak::weak_count(&w), Some(2)); + assert_eq!(Weak::strong_count(&w2), 1); + assert_eq!(Weak::weak_count(&w2), Some(2)); + drop(w); + assert_eq!(Weak::strong_count(&w2), 1); + assert_eq!(Weak::weak_count(&w2), Some(1)); + let a2 = a.clone(); + assert_eq!(Weak::strong_count(&w2), 2); + assert_eq!(Weak::weak_count(&w2), Some(1)); + drop(a2); + drop(a); + assert_eq!(Weak::strong_count(&w2), 0); + assert_eq!(Weak::weak_count(&w2), Some(1)); + drop(w2); +} + +#[test] +fn try_unwrap() { + let x = Rc::new(3); + assert_eq!(Rc::try_unwrap(x), Ok(3)); + let x = Rc::new(4); + let _y = x.clone(); + assert_eq!(Rc::try_unwrap(x), Err(Rc::new(4))); + let x = Rc::new(5); + let _w = Rc::downgrade(&x); + assert_eq!(Rc::try_unwrap(x), Ok(5)); +} + +#[test] +fn into_from_raw() { + let x = Rc::new(box "hello"); + let y = x.clone(); + + let x_ptr = Rc::into_raw(x); + drop(y); + unsafe { + assert_eq!(**x_ptr, "hello"); + + let x = Rc::from_raw(x_ptr); + assert_eq!(**x, "hello"); + + assert_eq!(Rc::try_unwrap(x).map(|x| *x), Ok("hello")); + } +} + +#[test] +fn test_into_from_raw_unsized() { + use std::fmt::Display; + use std::string::ToString; + + let rc: Rc = Rc::from("foo"); + + let ptr = Rc::into_raw(rc.clone()); + let rc2 = unsafe { Rc::from_raw(ptr) }; + + assert_eq!(unsafe { &*ptr }, "foo"); + assert_eq!(rc, rc2); + + let rc: Rc = Rc::new(123); + + let ptr = Rc::into_raw(rc.clone()); + let rc2 = unsafe { Rc::from_raw(ptr) }; + + assert_eq!(unsafe { &*ptr }.to_string(), "123"); + assert_eq!(rc2.to_string(), "123"); +} + +#[test] +fn get_mut() { + let mut x = Rc::new(3); + *Rc::get_mut(&mut x).unwrap() = 4; + assert_eq!(*x, 4); + let y = x.clone(); + assert!(Rc::get_mut(&mut x).is_none()); + drop(y); + assert!(Rc::get_mut(&mut x).is_some()); + let _w = Rc::downgrade(&x); + assert!(Rc::get_mut(&mut x).is_none()); +} + +#[test] +fn test_cowrc_clone_make_unique() { + let mut cow0 = Rc::new(75); + let mut cow1 = cow0.clone(); + let mut cow2 = cow1.clone(); + + assert!(75 == *Rc::make_mut(&mut cow0)); + assert!(75 == *Rc::make_mut(&mut cow1)); + assert!(75 == *Rc::make_mut(&mut cow2)); + + *Rc::make_mut(&mut cow0) += 1; + *Rc::make_mut(&mut cow1) += 2; + *Rc::make_mut(&mut cow2) += 3; + + assert!(76 == *cow0); + assert!(77 == *cow1); + assert!(78 == *cow2); + + // none should point to the same backing memory + assert!(*cow0 != *cow1); + assert!(*cow0 != *cow2); + assert!(*cow1 != *cow2); +} + +#[test] +fn test_cowrc_clone_unique2() { + let mut cow0 = Rc::new(75); + let cow1 = cow0.clone(); + let cow2 = cow1.clone(); + + assert!(75 == *cow0); + assert!(75 == *cow1); + assert!(75 == *cow2); + + *Rc::make_mut(&mut cow0) += 1; + + assert!(76 == *cow0); + assert!(75 == *cow1); + assert!(75 == *cow2); + + // cow1 and cow2 should share the same contents + // cow0 should have a unique reference + assert!(*cow0 != *cow1); + assert!(*cow0 != *cow2); + assert!(*cow1 == *cow2); +} + +#[test] +fn test_cowrc_clone_weak() { + let mut cow0 = Rc::new(75); + let cow1_weak = Rc::downgrade(&cow0); + + assert!(75 == *cow0); + assert!(75 == *cow1_weak.upgrade().unwrap()); + + *Rc::make_mut(&mut cow0) += 1; + + assert!(76 == *cow0); + assert!(cow1_weak.upgrade().is_none()); +} + +#[test] +fn test_show() { + let foo = Rc::new(75); + assert_eq!(format!("{:?}", foo), "75"); +} + +#[test] +fn test_unsized() { + let foo: Rc<[i32]> = Rc::new([1, 2, 3]); + assert_eq!(foo, foo.clone()); +} + +#[test] +fn test_from_owned() { + let foo = 123; + let foo_rc = Rc::from(foo); + assert!(123 == *foo_rc); +} + +#[test] +fn test_new_weak() { + let foo: Weak = Weak::new(); + assert!(foo.upgrade().is_none()); +} + +#[test] +fn test_ptr_eq() { + let five = Rc::new(5); + let same_five = five.clone(); + let other_five = Rc::new(5); + + assert!(Rc::ptr_eq(&five, &same_five)); + assert!(!Rc::ptr_eq(&five, &other_five)); +} + +#[test] +fn test_from_str() { + let r: Rc = Rc::from("foo"); + + assert_eq!(&r[..], "foo"); +} + +#[test] +fn test_copy_from_slice() { + let s: &[u32] = &[1, 2, 3]; + let r: Rc<[u32]> = Rc::from(s); + + assert_eq!(&r[..], [1, 2, 3]); +} + +#[test] +fn test_clone_from_slice() { + #[derive(Clone, Debug, Eq, PartialEq)] + struct X(u32); + + let s: &[X] = &[X(1), X(2), X(3)]; + let r: Rc<[X]> = Rc::from(s); + + assert_eq!(&r[..], s); +} + +#[test] +#[should_panic] +fn test_clone_from_slice_panic() { + use std::string::{String, ToString}; + + struct Fail(u32, String); + + impl Clone for Fail { + fn clone(&self) -> Fail { + if self.0 == 2 { + panic!(); + } + Fail(self.0, self.1.clone()) + } + } + + let s: &[Fail] = &[ + Fail(0, "foo".to_string()), + Fail(1, "bar".to_string()), + Fail(2, "baz".to_string()), + ]; + + // Should panic, but not cause memory corruption + let _r: Rc<[Fail]> = Rc::from(s); +} + +#[test] +fn test_from_box() { + let b: Box = box 123; + let r: Rc = Rc::from(b); + + assert_eq!(*r, 123); +} + +#[test] +fn test_from_box_str() { + use std::string::String; + + let s = String::from("foo").into_boxed_str(); + let r: Rc = Rc::from(s); + + assert_eq!(&r[..], "foo"); +} + +#[test] +fn test_from_box_slice() { + let s = vec![1, 2, 3].into_boxed_slice(); + let r: Rc<[u32]> = Rc::from(s); + + assert_eq!(&r[..], [1, 2, 3]); +} + +#[test] +fn test_from_box_trait() { + use std::fmt::Display; + use std::string::ToString; + + let b: Box = box 123; + let r: Rc = Rc::from(b); + + assert_eq!(r.to_string(), "123"); +} + +#[test] +fn test_from_box_trait_zero_sized() { + use std::fmt::Debug; + + let b: Box = box (); + let r: Rc = Rc::from(b); + + assert_eq!(format!("{:?}", r), "()"); +} + +#[test] +fn test_from_vec() { + let v = vec![1, 2, 3]; + let r: Rc<[u32]> = Rc::from(v); + + assert_eq!(&r[..], [1, 2, 3]); +} + +#[test] +fn test_downcast() { + use std::any::Any; + + let r1: Rc = Rc::new(i32::max_value()); + let r2: Rc = Rc::new("abc"); + + assert!(r1.clone().downcast::().is_err()); + + let r1i32 = r1.downcast::(); + assert!(r1i32.is_ok()); + assert_eq!(r1i32.unwrap(), Rc::new(i32::max_value())); + + assert!(r2.clone().downcast::().is_err()); + + let r2str = r2.downcast::<&'static str>(); + assert!(r2str.is_ok()); + assert_eq!(r2str.unwrap(), Rc::new("abc")); +} diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index 93aff733724..e11873218e8 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -30,6 +30,9 @@ use crate::rc::is_dangling; use crate::string::String; use crate::vec::Vec; +#[cfg(test)] +mod tests; + /// A soft limit on the amount of references that may be made to an `Arc`. /// /// Going above this limit will abort your program (although not @@ -1915,489 +1918,6 @@ impl<'a, T: 'a + Clone> ArcFromIter<&'a T, slice::Iter<'a, T>> for Arc<[T]> { } } -#[cfg(test)] -mod tests { - use std::boxed::Box; - use std::clone::Clone; - use std::sync::mpsc::channel; - use std::mem::drop; - use std::ops::Drop; - use std::option::Option::{self, None, Some}; - use std::sync::atomic::{self, Ordering::{Acquire, SeqCst}}; - use std::thread; - use std::sync::Mutex; - use std::convert::From; - - use super::{Arc, Weak}; - use crate::vec::Vec; - - struct Canary(*mut atomic::AtomicUsize); - - impl Drop for Canary { - fn drop(&mut self) { - unsafe { - match *self { - Canary(c) => { - (*c).fetch_add(1, SeqCst); - } - } - } - } - } - - #[test] - #[cfg_attr(target_os = "emscripten", ignore)] - #[cfg(not(miri))] // Miri does not support threads - fn manually_share_arc() { - let v = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; - let arc_v = Arc::new(v); - - let (tx, rx) = channel(); - - let _t = thread::spawn(move || { - let arc_v: Arc> = rx.recv().unwrap(); - assert_eq!((*arc_v)[3], 4); - }); - - tx.send(arc_v.clone()).unwrap(); - - assert_eq!((*arc_v)[2], 3); - assert_eq!((*arc_v)[4], 5); - } - - #[test] - fn test_arc_get_mut() { - let mut x = Arc::new(3); - *Arc::get_mut(&mut x).unwrap() = 4; - assert_eq!(*x, 4); - let y = x.clone(); - assert!(Arc::get_mut(&mut x).is_none()); - drop(y); - assert!(Arc::get_mut(&mut x).is_some()); - let _w = Arc::downgrade(&x); - assert!(Arc::get_mut(&mut x).is_none()); - } - - #[test] - fn weak_counts() { - assert_eq!(Weak::weak_count(&Weak::::new()), None); - assert_eq!(Weak::strong_count(&Weak::::new()), 0); - - let a = Arc::new(0); - let w = Arc::downgrade(&a); - assert_eq!(Weak::strong_count(&w), 1); - assert_eq!(Weak::weak_count(&w), Some(1)); - let w2 = w.clone(); - assert_eq!(Weak::strong_count(&w), 1); - assert_eq!(Weak::weak_count(&w), Some(2)); - assert_eq!(Weak::strong_count(&w2), 1); - assert_eq!(Weak::weak_count(&w2), Some(2)); - drop(w); - assert_eq!(Weak::strong_count(&w2), 1); - assert_eq!(Weak::weak_count(&w2), Some(1)); - let a2 = a.clone(); - assert_eq!(Weak::strong_count(&w2), 2); - assert_eq!(Weak::weak_count(&w2), Some(1)); - drop(a2); - drop(a); - assert_eq!(Weak::strong_count(&w2), 0); - assert_eq!(Weak::weak_count(&w2), Some(1)); - drop(w2); - } - - #[test] - fn try_unwrap() { - let x = Arc::new(3); - assert_eq!(Arc::try_unwrap(x), Ok(3)); - let x = Arc::new(4); - let _y = x.clone(); - assert_eq!(Arc::try_unwrap(x), Err(Arc::new(4))); - let x = Arc::new(5); - let _w = Arc::downgrade(&x); - assert_eq!(Arc::try_unwrap(x), Ok(5)); - } - - #[test] - fn into_from_raw() { - let x = Arc::new(box "hello"); - let y = x.clone(); - - let x_ptr = Arc::into_raw(x); - drop(y); - unsafe { - assert_eq!(**x_ptr, "hello"); - - let x = Arc::from_raw(x_ptr); - assert_eq!(**x, "hello"); - - assert_eq!(Arc::try_unwrap(x).map(|x| *x), Ok("hello")); - } - } - - #[test] - fn test_into_from_raw_unsized() { - use std::fmt::Display; - use std::string::ToString; - - let arc: Arc = Arc::from("foo"); - - let ptr = Arc::into_raw(arc.clone()); - let arc2 = unsafe { Arc::from_raw(ptr) }; - - assert_eq!(unsafe { &*ptr }, "foo"); - assert_eq!(arc, arc2); - - let arc: Arc = Arc::new(123); - - let ptr = Arc::into_raw(arc.clone()); - let arc2 = unsafe { Arc::from_raw(ptr) }; - - assert_eq!(unsafe { &*ptr }.to_string(), "123"); - assert_eq!(arc2.to_string(), "123"); - } - - #[test] - fn test_cowarc_clone_make_mut() { - let mut cow0 = Arc::new(75); - let mut cow1 = cow0.clone(); - let mut cow2 = cow1.clone(); - - assert!(75 == *Arc::make_mut(&mut cow0)); - assert!(75 == *Arc::make_mut(&mut cow1)); - assert!(75 == *Arc::make_mut(&mut cow2)); - - *Arc::make_mut(&mut cow0) += 1; - *Arc::make_mut(&mut cow1) += 2; - *Arc::make_mut(&mut cow2) += 3; - - assert!(76 == *cow0); - assert!(77 == *cow1); - assert!(78 == *cow2); - - // none should point to the same backing memory - assert!(*cow0 != *cow1); - assert!(*cow0 != *cow2); - assert!(*cow1 != *cow2); - } - - #[test] - fn test_cowarc_clone_unique2() { - let mut cow0 = Arc::new(75); - let cow1 = cow0.clone(); - let cow2 = cow1.clone(); - - assert!(75 == *cow0); - assert!(75 == *cow1); - assert!(75 == *cow2); - - *Arc::make_mut(&mut cow0) += 1; - assert!(76 == *cow0); - assert!(75 == *cow1); - assert!(75 == *cow2); - - // cow1 and cow2 should share the same contents - // cow0 should have a unique reference - assert!(*cow0 != *cow1); - assert!(*cow0 != *cow2); - assert!(*cow1 == *cow2); - } - - #[test] - fn test_cowarc_clone_weak() { - let mut cow0 = Arc::new(75); - let cow1_weak = Arc::downgrade(&cow0); - - assert!(75 == *cow0); - assert!(75 == *cow1_weak.upgrade().unwrap()); - - *Arc::make_mut(&mut cow0) += 1; - - assert!(76 == *cow0); - assert!(cow1_weak.upgrade().is_none()); - } - - #[test] - fn test_live() { - let x = Arc::new(5); - let y = Arc::downgrade(&x); - assert!(y.upgrade().is_some()); - } - - #[test] - fn test_dead() { - let x = Arc::new(5); - let y = Arc::downgrade(&x); - drop(x); - assert!(y.upgrade().is_none()); - } - - #[test] - fn weak_self_cyclic() { - struct Cycle { - x: Mutex>>, - } - - let a = Arc::new(Cycle { x: Mutex::new(None) }); - let b = Arc::downgrade(&a.clone()); - *a.x.lock().unwrap() = Some(b); - - // hopefully we don't double-free (or leak)... - } - - #[test] - fn drop_arc() { - let mut canary = atomic::AtomicUsize::new(0); - let x = Arc::new(Canary(&mut canary as *mut atomic::AtomicUsize)); - drop(x); - assert!(canary.load(Acquire) == 1); - } - - #[test] - fn drop_arc_weak() { - let mut canary = atomic::AtomicUsize::new(0); - let arc = Arc::new(Canary(&mut canary as *mut atomic::AtomicUsize)); - let arc_weak = Arc::downgrade(&arc); - assert!(canary.load(Acquire) == 0); - drop(arc); - assert!(canary.load(Acquire) == 1); - drop(arc_weak); - } - - #[test] - fn test_strong_count() { - let a = Arc::new(0); - assert!(Arc::strong_count(&a) == 1); - let w = Arc::downgrade(&a); - assert!(Arc::strong_count(&a) == 1); - let b = w.upgrade().expect(""); - assert!(Arc::strong_count(&b) == 2); - assert!(Arc::strong_count(&a) == 2); - drop(w); - drop(a); - assert!(Arc::strong_count(&b) == 1); - let c = b.clone(); - assert!(Arc::strong_count(&b) == 2); - assert!(Arc::strong_count(&c) == 2); - } - - #[test] - fn test_weak_count() { - let a = Arc::new(0); - assert!(Arc::strong_count(&a) == 1); - assert!(Arc::weak_count(&a) == 0); - let w = Arc::downgrade(&a); - assert!(Arc::strong_count(&a) == 1); - assert!(Arc::weak_count(&a) == 1); - let x = w.clone(); - assert!(Arc::weak_count(&a) == 2); - drop(w); - drop(x); - assert!(Arc::strong_count(&a) == 1); - assert!(Arc::weak_count(&a) == 0); - let c = a.clone(); - assert!(Arc::strong_count(&a) == 2); - assert!(Arc::weak_count(&a) == 0); - let d = Arc::downgrade(&c); - assert!(Arc::weak_count(&c) == 1); - assert!(Arc::strong_count(&c) == 2); - - drop(a); - drop(c); - drop(d); - } - - #[test] - fn show_arc() { - let a = Arc::new(5); - assert_eq!(format!("{:?}", a), "5"); - } - - // Make sure deriving works with Arc - #[derive(Eq, Ord, PartialEq, PartialOrd, Clone, Debug, Default)] - struct Foo { - inner: Arc, - } - - #[test] - fn test_unsized() { - let x: Arc<[i32]> = Arc::new([1, 2, 3]); - assert_eq!(format!("{:?}", x), "[1, 2, 3]"); - let y = Arc::downgrade(&x.clone()); - drop(x); - assert!(y.upgrade().is_none()); - } - - #[test] - fn test_from_owned() { - let foo = 123; - let foo_arc = Arc::from(foo); - assert!(123 == *foo_arc); - } - - #[test] - fn test_new_weak() { - let foo: Weak = Weak::new(); - assert!(foo.upgrade().is_none()); - } - - #[test] - fn test_ptr_eq() { - let five = Arc::new(5); - let same_five = five.clone(); - let other_five = Arc::new(5); - - assert!(Arc::ptr_eq(&five, &same_five)); - assert!(!Arc::ptr_eq(&five, &other_five)); - } - - #[test] - #[cfg_attr(target_os = "emscripten", ignore)] - #[cfg(not(miri))] // Miri does not support threads - fn test_weak_count_locked() { - let mut a = Arc::new(atomic::AtomicBool::new(false)); - let a2 = a.clone(); - let t = thread::spawn(move || { - for _i in 0..1000000 { - Arc::get_mut(&mut a); - } - a.store(true, SeqCst); - }); - - while !a2.load(SeqCst) { - let n = Arc::weak_count(&a2); - assert!(n < 2, "bad weak count: {}", n); - } - t.join().unwrap(); - } - - #[test] - fn test_from_str() { - let r: Arc = Arc::from("foo"); - - assert_eq!(&r[..], "foo"); - } - - #[test] - fn test_copy_from_slice() { - let s: &[u32] = &[1, 2, 3]; - let r: Arc<[u32]> = Arc::from(s); - - assert_eq!(&r[..], [1, 2, 3]); - } - - #[test] - fn test_clone_from_slice() { - #[derive(Clone, Debug, Eq, PartialEq)] - struct X(u32); - - let s: &[X] = &[X(1), X(2), X(3)]; - let r: Arc<[X]> = Arc::from(s); - - assert_eq!(&r[..], s); - } - - #[test] - #[should_panic] - fn test_clone_from_slice_panic() { - use std::string::{String, ToString}; - - struct Fail(u32, String); - - impl Clone for Fail { - fn clone(&self) -> Fail { - if self.0 == 2 { - panic!(); - } - Fail(self.0, self.1.clone()) - } - } - - let s: &[Fail] = &[ - Fail(0, "foo".to_string()), - Fail(1, "bar".to_string()), - Fail(2, "baz".to_string()), - ]; - - // Should panic, but not cause memory corruption - let _r: Arc<[Fail]> = Arc::from(s); - } - - #[test] - fn test_from_box() { - let b: Box = box 123; - let r: Arc = Arc::from(b); - - assert_eq!(*r, 123); - } - - #[test] - fn test_from_box_str() { - use std::string::String; - - let s = String::from("foo").into_boxed_str(); - let r: Arc = Arc::from(s); - - assert_eq!(&r[..], "foo"); - } - - #[test] - fn test_from_box_slice() { - let s = vec![1, 2, 3].into_boxed_slice(); - let r: Arc<[u32]> = Arc::from(s); - - assert_eq!(&r[..], [1, 2, 3]); - } - - #[test] - fn test_from_box_trait() { - use std::fmt::Display; - use std::string::ToString; - - let b: Box = box 123; - let r: Arc = Arc::from(b); - - assert_eq!(r.to_string(), "123"); - } - - #[test] - fn test_from_box_trait_zero_sized() { - use std::fmt::Debug; - - let b: Box = box (); - let r: Arc = Arc::from(b); - - assert_eq!(format!("{:?}", r), "()"); - } - - #[test] - fn test_from_vec() { - let v = vec![1, 2, 3]; - let r: Arc<[u32]> = Arc::from(v); - - assert_eq!(&r[..], [1, 2, 3]); - } - - #[test] - fn test_downcast() { - use std::any::Any; - - let r1: Arc = Arc::new(i32::max_value()); - let r2: Arc = Arc::new("abc"); - - assert!(r1.clone().downcast::().is_err()); - - let r1i32 = r1.downcast::(); - assert!(r1i32.is_ok()); - assert_eq!(r1i32.unwrap(), Arc::new(i32::max_value())); - - assert!(r2.clone().downcast::().is_err()); - - let r2str = r2.downcast::<&'static str>(); - assert!(r2str.is_ok()); - assert_eq!(r2str.unwrap(), Arc::new("abc")); - } -} - #[stable(feature = "rust1", since = "1.0.0")] impl borrow::Borrow for Arc { fn borrow(&self) -> &T { diff --git a/src/liballoc/sync/tests.rs b/src/liballoc/sync/tests.rs new file mode 100644 index 00000000000..2e0c62f50c1 --- /dev/null +++ b/src/liballoc/sync/tests.rs @@ -0,0 +1,480 @@ +use super::*; + +use std::boxed::Box; +use std::clone::Clone; +use std::sync::mpsc::channel; +use std::mem::drop; +use std::ops::Drop; +use std::option::Option::{self, None, Some}; +use std::sync::atomic::{self, Ordering::{Acquire, SeqCst}}; +use std::thread; +use std::sync::Mutex; +use std::convert::From; + +use crate::vec::Vec; + +struct Canary(*mut atomic::AtomicUsize); + +impl Drop for Canary { + fn drop(&mut self) { + unsafe { + match *self { + Canary(c) => { + (*c).fetch_add(1, SeqCst); + } + } + } + } +} + +#[test] +#[cfg_attr(target_os = "emscripten", ignore)] +#[cfg(not(miri))] // Miri does not support threads +fn manually_share_arc() { + let v = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + let arc_v = Arc::new(v); + + let (tx, rx) = channel(); + + let _t = thread::spawn(move || { + let arc_v: Arc> = rx.recv().unwrap(); + assert_eq!((*arc_v)[3], 4); + }); + + tx.send(arc_v.clone()).unwrap(); + + assert_eq!((*arc_v)[2], 3); + assert_eq!((*arc_v)[4], 5); +} + +#[test] +fn test_arc_get_mut() { + let mut x = Arc::new(3); + *Arc::get_mut(&mut x).unwrap() = 4; + assert_eq!(*x, 4); + let y = x.clone(); + assert!(Arc::get_mut(&mut x).is_none()); + drop(y); + assert!(Arc::get_mut(&mut x).is_some()); + let _w = Arc::downgrade(&x); + assert!(Arc::get_mut(&mut x).is_none()); +} + +#[test] +fn weak_counts() { + assert_eq!(Weak::weak_count(&Weak::::new()), None); + assert_eq!(Weak::strong_count(&Weak::::new()), 0); + + let a = Arc::new(0); + let w = Arc::downgrade(&a); + assert_eq!(Weak::strong_count(&w), 1); + assert_eq!(Weak::weak_count(&w), Some(1)); + let w2 = w.clone(); + assert_eq!(Weak::strong_count(&w), 1); + assert_eq!(Weak::weak_count(&w), Some(2)); + assert_eq!(Weak::strong_count(&w2), 1); + assert_eq!(Weak::weak_count(&w2), Some(2)); + drop(w); + assert_eq!(Weak::strong_count(&w2), 1); + assert_eq!(Weak::weak_count(&w2), Some(1)); + let a2 = a.clone(); + assert_eq!(Weak::strong_count(&w2), 2); + assert_eq!(Weak::weak_count(&w2), Some(1)); + drop(a2); + drop(a); + assert_eq!(Weak::strong_count(&w2), 0); + assert_eq!(Weak::weak_count(&w2), Some(1)); + drop(w2); +} + +#[test] +fn try_unwrap() { + let x = Arc::new(3); + assert_eq!(Arc::try_unwrap(x), Ok(3)); + let x = Arc::new(4); + let _y = x.clone(); + assert_eq!(Arc::try_unwrap(x), Err(Arc::new(4))); + let x = Arc::new(5); + let _w = Arc::downgrade(&x); + assert_eq!(Arc::try_unwrap(x), Ok(5)); +} + +#[test] +fn into_from_raw() { + let x = Arc::new(box "hello"); + let y = x.clone(); + + let x_ptr = Arc::into_raw(x); + drop(y); + unsafe { + assert_eq!(**x_ptr, "hello"); + + let x = Arc::from_raw(x_ptr); + assert_eq!(**x, "hello"); + + assert_eq!(Arc::try_unwrap(x).map(|x| *x), Ok("hello")); + } +} + +#[test] +fn test_into_from_raw_unsized() { + use std::fmt::Display; + use std::string::ToString; + + let arc: Arc = Arc::from("foo"); + + let ptr = Arc::into_raw(arc.clone()); + let arc2 = unsafe { Arc::from_raw(ptr) }; + + assert_eq!(unsafe { &*ptr }, "foo"); + assert_eq!(arc, arc2); + + let arc: Arc = Arc::new(123); + + let ptr = Arc::into_raw(arc.clone()); + let arc2 = unsafe { Arc::from_raw(ptr) }; + + assert_eq!(unsafe { &*ptr }.to_string(), "123"); + assert_eq!(arc2.to_string(), "123"); +} + +#[test] +fn test_cowarc_clone_make_mut() { + let mut cow0 = Arc::new(75); + let mut cow1 = cow0.clone(); + let mut cow2 = cow1.clone(); + + assert!(75 == *Arc::make_mut(&mut cow0)); + assert!(75 == *Arc::make_mut(&mut cow1)); + assert!(75 == *Arc::make_mut(&mut cow2)); + + *Arc::make_mut(&mut cow0) += 1; + *Arc::make_mut(&mut cow1) += 2; + *Arc::make_mut(&mut cow2) += 3; + + assert!(76 == *cow0); + assert!(77 == *cow1); + assert!(78 == *cow2); + + // none should point to the same backing memory + assert!(*cow0 != *cow1); + assert!(*cow0 != *cow2); + assert!(*cow1 != *cow2); +} + +#[test] +fn test_cowarc_clone_unique2() { + let mut cow0 = Arc::new(75); + let cow1 = cow0.clone(); + let cow2 = cow1.clone(); + + assert!(75 == *cow0); + assert!(75 == *cow1); + assert!(75 == *cow2); + + *Arc::make_mut(&mut cow0) += 1; + assert!(76 == *cow0); + assert!(75 == *cow1); + assert!(75 == *cow2); + + // cow1 and cow2 should share the same contents + // cow0 should have a unique reference + assert!(*cow0 != *cow1); + assert!(*cow0 != *cow2); + assert!(*cow1 == *cow2); +} + +#[test] +fn test_cowarc_clone_weak() { + let mut cow0 = Arc::new(75); + let cow1_weak = Arc::downgrade(&cow0); + + assert!(75 == *cow0); + assert!(75 == *cow1_weak.upgrade().unwrap()); + + *Arc::make_mut(&mut cow0) += 1; + + assert!(76 == *cow0); + assert!(cow1_weak.upgrade().is_none()); +} + +#[test] +fn test_live() { + let x = Arc::new(5); + let y = Arc::downgrade(&x); + assert!(y.upgrade().is_some()); +} + +#[test] +fn test_dead() { + let x = Arc::new(5); + let y = Arc::downgrade(&x); + drop(x); + assert!(y.upgrade().is_none()); +} + +#[test] +fn weak_self_cyclic() { + struct Cycle { + x: Mutex>>, + } + + let a = Arc::new(Cycle { x: Mutex::new(None) }); + let b = Arc::downgrade(&a.clone()); + *a.x.lock().unwrap() = Some(b); + + // hopefully we don't double-free (or leak)... +} + +#[test] +fn drop_arc() { + let mut canary = atomic::AtomicUsize::new(0); + let x = Arc::new(Canary(&mut canary as *mut atomic::AtomicUsize)); + drop(x); + assert!(canary.load(Acquire) == 1); +} + +#[test] +fn drop_arc_weak() { + let mut canary = atomic::AtomicUsize::new(0); + let arc = Arc::new(Canary(&mut canary as *mut atomic::AtomicUsize)); + let arc_weak = Arc::downgrade(&arc); + assert!(canary.load(Acquire) == 0); + drop(arc); + assert!(canary.load(Acquire) == 1); + drop(arc_weak); +} + +#[test] +fn test_strong_count() { + let a = Arc::new(0); + assert!(Arc::strong_count(&a) == 1); + let w = Arc::downgrade(&a); + assert!(Arc::strong_count(&a) == 1); + let b = w.upgrade().expect(""); + assert!(Arc::strong_count(&b) == 2); + assert!(Arc::strong_count(&a) == 2); + drop(w); + drop(a); + assert!(Arc::strong_count(&b) == 1); + let c = b.clone(); + assert!(Arc::strong_count(&b) == 2); + assert!(Arc::strong_count(&c) == 2); +} + +#[test] +fn test_weak_count() { + let a = Arc::new(0); + assert!(Arc::strong_count(&a) == 1); + assert!(Arc::weak_count(&a) == 0); + let w = Arc::downgrade(&a); + assert!(Arc::strong_count(&a) == 1); + assert!(Arc::weak_count(&a) == 1); + let x = w.clone(); + assert!(Arc::weak_count(&a) == 2); + drop(w); + drop(x); + assert!(Arc::strong_count(&a) == 1); + assert!(Arc::weak_count(&a) == 0); + let c = a.clone(); + assert!(Arc::strong_count(&a) == 2); + assert!(Arc::weak_count(&a) == 0); + let d = Arc::downgrade(&c); + assert!(Arc::weak_count(&c) == 1); + assert!(Arc::strong_count(&c) == 2); + + drop(a); + drop(c); + drop(d); +} + +#[test] +fn show_arc() { + let a = Arc::new(5); + assert_eq!(format!("{:?}", a), "5"); +} + +// Make sure deriving works with Arc +#[derive(Eq, Ord, PartialEq, PartialOrd, Clone, Debug, Default)] +struct Foo { + inner: Arc, +} + +#[test] +fn test_unsized() { + let x: Arc<[i32]> = Arc::new([1, 2, 3]); + assert_eq!(format!("{:?}", x), "[1, 2, 3]"); + let y = Arc::downgrade(&x.clone()); + drop(x); + assert!(y.upgrade().is_none()); +} + +#[test] +fn test_from_owned() { + let foo = 123; + let foo_arc = Arc::from(foo); + assert!(123 == *foo_arc); +} + +#[test] +fn test_new_weak() { + let foo: Weak = Weak::new(); + assert!(foo.upgrade().is_none()); +} + +#[test] +fn test_ptr_eq() { + let five = Arc::new(5); + let same_five = five.clone(); + let other_five = Arc::new(5); + + assert!(Arc::ptr_eq(&five, &same_five)); + assert!(!Arc::ptr_eq(&five, &other_five)); +} + +#[test] +#[cfg_attr(target_os = "emscripten", ignore)] +#[cfg(not(miri))] // Miri does not support threads +fn test_weak_count_locked() { + let mut a = Arc::new(atomic::AtomicBool::new(false)); + let a2 = a.clone(); + let t = thread::spawn(move || { + for _i in 0..1000000 { + Arc::get_mut(&mut a); + } + a.store(true, SeqCst); + }); + + while !a2.load(SeqCst) { + let n = Arc::weak_count(&a2); + assert!(n < 2, "bad weak count: {}", n); + } + t.join().unwrap(); +} + +#[test] +fn test_from_str() { + let r: Arc = Arc::from("foo"); + + assert_eq!(&r[..], "foo"); +} + +#[test] +fn test_copy_from_slice() { + let s: &[u32] = &[1, 2, 3]; + let r: Arc<[u32]> = Arc::from(s); + + assert_eq!(&r[..], [1, 2, 3]); +} + +#[test] +fn test_clone_from_slice() { + #[derive(Clone, Debug, Eq, PartialEq)] + struct X(u32); + + let s: &[X] = &[X(1), X(2), X(3)]; + let r: Arc<[X]> = Arc::from(s); + + assert_eq!(&r[..], s); +} + +#[test] +#[should_panic] +fn test_clone_from_slice_panic() { + use std::string::{String, ToString}; + + struct Fail(u32, String); + + impl Clone for Fail { + fn clone(&self) -> Fail { + if self.0 == 2 { + panic!(); + } + Fail(self.0, self.1.clone()) + } + } + + let s: &[Fail] = &[ + Fail(0, "foo".to_string()), + Fail(1, "bar".to_string()), + Fail(2, "baz".to_string()), + ]; + + // Should panic, but not cause memory corruption + let _r: Arc<[Fail]> = Arc::from(s); +} + +#[test] +fn test_from_box() { + let b: Box = box 123; + let r: Arc = Arc::from(b); + + assert_eq!(*r, 123); +} + +#[test] +fn test_from_box_str() { + use std::string::String; + + let s = String::from("foo").into_boxed_str(); + let r: Arc = Arc::from(s); + + assert_eq!(&r[..], "foo"); +} + +#[test] +fn test_from_box_slice() { + let s = vec![1, 2, 3].into_boxed_slice(); + let r: Arc<[u32]> = Arc::from(s); + + assert_eq!(&r[..], [1, 2, 3]); +} + +#[test] +fn test_from_box_trait() { + use std::fmt::Display; + use std::string::ToString; + + let b: Box = box 123; + let r: Arc = Arc::from(b); + + assert_eq!(r.to_string(), "123"); +} + +#[test] +fn test_from_box_trait_zero_sized() { + use std::fmt::Debug; + + let b: Box = box (); + let r: Arc = Arc::from(b); + + assert_eq!(format!("{:?}", r), "()"); +} + +#[test] +fn test_from_vec() { + let v = vec![1, 2, 3]; + let r: Arc<[u32]> = Arc::from(v); + + assert_eq!(&r[..], [1, 2, 3]); +} + +#[test] +fn test_downcast() { + use std::any::Any; + + let r1: Arc = Arc::new(i32::max_value()); + let r2: Arc = Arc::new("abc"); + + assert!(r1.clone().downcast::().is_err()); + + let r1i32 = r1.downcast::(); + assert!(r1i32.is_ok()); + assert_eq!(r1i32.unwrap(), Arc::new(i32::max_value())); + + assert!(r2.clone().downcast::().is_err()); + + let r2str = r2.downcast::<&'static str>(); + assert!(r2str.is_ok()); + assert_eq!(r2str.unwrap(), Arc::new("abc")); +} diff --git a/src/tools/tidy/src/unit_tests.rs b/src/tools/tidy/src/unit_tests.rs index d01069f4269..6286945ad26 100644 --- a/src/tools/tidy/src/unit_tests.rs +++ b/src/tools/tidy/src/unit_tests.rs @@ -1,11 +1,9 @@ -//! Tidy check to ensure `#[test]` and `#[bench]` are not used directly inside -//! `libcore` or `liballoc`. +//! Tidy check to ensure `#[test]` and `#[bench]` are not used directly inside `libcore`. //! -//! `#![no_std]` libraries cannot be tested directly due to duplicating lang -//! items. All tests and benchmarks must be written externally in `libcore/{tests,benches}` -//! or `liballoc/{tests,benches}`. +//! `#![no_core]` libraries cannot be tested directly due to duplicating lang +//! items. All tests and benchmarks must be written externally in `libcore/{tests,benches}`. //! -//! Outside of libcore and liballoc tests and benchmarks should be outlined into separate files +//! Outside of libcore tests and benchmarks should be outlined into separate files //! named `tests.rs` or `benches.rs`, or directories named `tests` or `benches` unconfigured //! during normal build. @@ -13,22 +11,12 @@ use std::path::Path; pub fn check(root_path: &Path, bad: &mut bool) { let libcore = &root_path.join("libcore"); - let liballoc = &root_path.join("liballoc"); let libcore_tests = &root_path.join("libcore/tests"); - let liballoc_tests = &root_path.join("liballoc/tests"); let libcore_benches = &root_path.join("libcore/benches"); - let liballoc_benches = &root_path.join("liballoc/benches"); - let is_core_or_alloc = |path: &Path| { - let is_core = path.starts_with(libcore) && - !(path.starts_with(libcore_tests) || path.starts_with(libcore_benches)); - let is_alloc = path.starts_with(liballoc) && - !(path.starts_with(liballoc_tests) || path.starts_with(liballoc_benches)); - is_core || is_alloc + let is_core = |path: &Path| { + path.starts_with(libcore) && + !(path.starts_with(libcore_tests) || path.starts_with(libcore_benches)) }; - let fixme = [ - "liballoc", - "libstd", - ]; let mut skip = |path: &Path| { let file_name = path.file_name().unwrap_or_default(); @@ -36,12 +24,12 @@ pub fn check(root_path: &Path, bad: &mut bool) { super::filter_dirs(path) || path.ends_with("src/test") || path.ends_with("src/doc") || - (file_name == "tests" || file_name == "benches") && !is_core_or_alloc(path) || - fixme.iter().any(|p| path.ends_with(p)) + path.ends_with("src/libstd") || // FIXME? + (file_name == "tests" || file_name == "benches") && !is_core(path) } else { let extension = path.extension().unwrap_or_default(); extension != "rs" || - (file_name == "tests.rs" || file_name == "benches.rs") && !is_core_or_alloc(path) + (file_name == "tests.rs" || file_name == "benches.rs") && !is_core(path) } }; @@ -51,7 +39,6 @@ pub fn check(root_path: &Path, bad: &mut bool) { &mut |entry, contents| { let path = entry.path(); let is_libcore = path.starts_with(libcore); - let is_liballoc = path.starts_with(liballoc); for (i, line) in contents.lines().enumerate() { let line = line.trim(); let is_test = || line.contains("#[test]") && !line.contains("`#[test]"); @@ -60,9 +47,6 @@ pub fn check(root_path: &Path, bad: &mut bool) { let explanation = if is_libcore { "libcore unit tests and benchmarks must be placed into \ `libcore/tests` or `libcore/benches`" - } else if is_liballoc { - "liballoc unit tests and benchmarks must be placed into \ - `liballoc/tests` or `liballoc/benches`" } else { "unit tests and benchmarks must be placed into \ separate files or directories named \ -- cgit 1.4.1-3-g733a5 From 62ec2cb7acb1b16d0abd8a2cf40da545a13d29f3 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 2 Aug 2019 01:58:40 +0300 Subject: Remove some more `cfg(test)`s --- src/bootstrap/cache.rs | 5 +++-- src/liballoc/collections/linked_list/tests.rs | 1 - src/liballoc/tests/linked_list.rs | 2 -- src/liballoc/tests/vec_deque.rs | 1 - .../graph/dominators/mod.rs | 5 ----- .../graph/dominators/tests.rs | 8 ++++---- .../obligation_forest/tests.rs | 4 +--- src/libsyntax/print/pprust.rs | 20 -------------------- src/libsyntax/print/pprust/tests.rs | 16 ++++++++++++++++ src/libtest/lib.rs | 22 ---------------------- src/libtest/tests.rs | 21 +++++++++++++++++++++ 11 files changed, 45 insertions(+), 60 deletions(-) (limited to 'src/liballoc') diff --git a/src/bootstrap/cache.rs b/src/bootstrap/cache.rs index f137a7b8cc2..53071df8552 100644 --- a/src/bootstrap/cache.rs +++ b/src/bootstrap/cache.rs @@ -266,8 +266,10 @@ impl Cache { .expect("invalid type mapped"); stepcache.get(step).cloned() } +} - #[cfg(test)] +#[cfg(test)] +impl Cache { pub fn all(&mut self) -> Vec<(S, S::Output)> { let cache = self.0.get_mut(); let type_id = TypeId::of::(); @@ -279,7 +281,6 @@ impl Cache { v } - #[cfg(test)] pub fn contains(&self) -> bool { self.0.borrow().contains_key(&TypeId::of::()) } diff --git a/src/liballoc/collections/linked_list/tests.rs b/src/liballoc/collections/linked_list/tests.rs index 953b0d4eb28..9a6c57d2869 100644 --- a/src/liballoc/collections/linked_list/tests.rs +++ b/src/liballoc/collections/linked_list/tests.rs @@ -201,7 +201,6 @@ fn test_split_off() { } } -#[cfg(test)] fn fuzz_test(sz: i32) { let mut m: LinkedList<_> = LinkedList::new(); let mut v = vec![]; diff --git a/src/liballoc/tests/linked_list.rs b/src/liballoc/tests/linked_list.rs index 0fbfbdccd45..8a26454c389 100644 --- a/src/liballoc/tests/linked_list.rs +++ b/src/liballoc/tests/linked_list.rs @@ -40,12 +40,10 @@ fn test_basic() { assert_eq!(n.pop_front(), Some(1)); } -#[cfg(test)] fn generate_test() -> LinkedList { list_from(&[0, 1, 2, 3, 4, 5, 6]) } -#[cfg(test)] fn list_from(v: &[T]) -> LinkedList { v.iter().cloned().collect() } diff --git a/src/liballoc/tests/vec_deque.rs b/src/liballoc/tests/vec_deque.rs index e0fe10a55f5..1bbcca97b3c 100644 --- a/src/liballoc/tests/vec_deque.rs +++ b/src/liballoc/tests/vec_deque.rs @@ -44,7 +44,6 @@ fn test_simple() { assert_eq!(d[3], 4); } -#[cfg(test)] fn test_parameterized(a: T, b: T, c: T, d: T) { let mut deq = VecDeque::new(); assert_eq!(deq.len(), 0); diff --git a/src/librustc_data_structures/graph/dominators/mod.rs b/src/librustc_data_structures/graph/dominators/mod.rs index 04ddca7896a..41e6b72953e 100644 --- a/src/librustc_data_structures/graph/dominators/mod.rs +++ b/src/librustc_data_structures/graph/dominators/mod.rs @@ -127,11 +127,6 @@ impl Dominators { // FIXME -- could be optimized by using post-order-rank self.dominators(node).any(|n| n == dom) } - - #[cfg(test)] - fn all_immediate_dominators(&self) -> &IndexVec> { - &self.immediate_dominators - } } pub struct Iter<'dom, Node: Idx> { diff --git a/src/librustc_data_structures/graph/dominators/tests.rs b/src/librustc_data_structures/graph/dominators/tests.rs index 70408fb6df1..92301ff6526 100644 --- a/src/librustc_data_structures/graph/dominators/tests.rs +++ b/src/librustc_data_structures/graph/dominators/tests.rs @@ -1,13 +1,13 @@ -use super::super::tests::TestGraph; - use super::*; +use super::super::tests::TestGraph; + #[test] fn diamond() { let graph = TestGraph::new(0, &[(0, 1), (0, 2), (1, 3), (2, 3)]); let dominators = dominators(&graph); - let immediate_dominators = dominators.all_immediate_dominators(); + let immediate_dominators = &dominators.immediate_dominators; assert_eq!(immediate_dominators[0], Some(0)); assert_eq!(immediate_dominators[1], Some(0)); assert_eq!(immediate_dominators[2], Some(0)); @@ -22,7 +22,7 @@ fn paper() { (2, 1)]); let dominators = dominators(&graph); - let immediate_dominators = dominators.all_immediate_dominators(); + let immediate_dominators = &dominators.immediate_dominators; assert_eq!(immediate_dominators[0], None); // <-- note that 0 is not in graph assert_eq!(immediate_dominators[1], Some(6)); assert_eq!(immediate_dominators[2], Some(6)); diff --git a/src/librustc_data_structures/obligation_forest/tests.rs b/src/librustc_data_structures/obligation_forest/tests.rs index 27d4bf4959e..e20466572a2 100644 --- a/src/librustc_data_structures/obligation_forest/tests.rs +++ b/src/librustc_data_structures/obligation_forest/tests.rs @@ -1,6 +1,4 @@ -#![cfg(test)] - -use super::{Error, DoCompleted, ObligationForest, ObligationProcessor, Outcome, ProcessResult}; +use super::*; use std::fmt; use std::marker::PhantomData; diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index f6dd95a7f4f..3645ab88d55 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -384,21 +384,6 @@ pub fn vis_to_string(v: &ast::Visibility) -> String { to_string(|s| s.print_visibility(v)) } -#[cfg(test)] -fn fun_to_string(decl: &ast::FnDecl, - header: ast::FnHeader, - name: ast::Ident, - generics: &ast::Generics) - -> String { - to_string(|s| { - s.head(""); - s.print_fn(decl, header, Some(name), - generics, &source_map::dummy_spanned(ast::VisibilityKind::Inherited)); - s.end(); // Close the head box - s.end(); // Close the outer box - }) -} - fn block_to_string(blk: &ast::Block) -> String { to_string(|s| { // containing cbox, will be closed by print-block at } @@ -421,11 +406,6 @@ pub fn attribute_to_string(attr: &ast::Attribute) -> String { to_string(|s| s.print_attribute(attr)) } -#[cfg(test)] -fn variant_to_string(var: &ast::Variant) -> String { - to_string(|s| s.print_variant(var)) -} - pub fn arg_to_string(arg: &ast::Arg) -> String { to_string(|s| s.print_arg(arg, false)) } diff --git a/src/libsyntax/print/pprust/tests.rs b/src/libsyntax/print/pprust/tests.rs index 97df7e6dcbd..082a430e0ed 100644 --- a/src/libsyntax/print/pprust/tests.rs +++ b/src/libsyntax/print/pprust/tests.rs @@ -5,6 +5,22 @@ use crate::source_map; use crate::with_default_globals; use syntax_pos; +fn fun_to_string( + decl: &ast::FnDecl, header: ast::FnHeader, name: ast::Ident, generics: &ast::Generics +) -> String { + to_string(|s| { + s.head(""); + s.print_fn(decl, header, Some(name), + generics, &source_map::dummy_spanned(ast::VisibilityKind::Inherited)); + s.end(); // Close the head box + s.end(); // Close the outer box + }) +} + +fn variant_to_string(var: &ast::Variant) -> String { + to_string(|s| s.print_variant(var)) +} + #[test] fn test_fun_to_string() { with_default_globals(|| { diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index b36c5be4c07..ef66c4df99d 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -380,28 +380,6 @@ pub struct TestOpts { pub options: Options, } -impl TestOpts { - #[cfg(test)] - fn new() -> TestOpts { - TestOpts { - list: false, - filter: None, - filter_exact: false, - exclude_should_panic: false, - run_ignored: RunIgnored::No, - run_tests: false, - bench_benchmarks: false, - logfile: None, - nocapture: false, - color: AutoColor, - format: OutputFormat::Pretty, - test_threads: None, - skip: vec![], - options: Options::new(), - } - } -} - /// Result of parsing the options. pub type OptRes = Result; diff --git a/src/libtest/tests.rs b/src/libtest/tests.rs index 05b38f17e2b..f574743e4b6 100644 --- a/src/libtest/tests.rs +++ b/src/libtest/tests.rs @@ -7,6 +7,27 @@ use crate::test::{ }; use std::sync::mpsc::channel; +impl TestOpts { + fn new() -> TestOpts { + TestOpts { + list: false, + filter: None, + filter_exact: false, + exclude_should_panic: false, + run_ignored: RunIgnored::No, + run_tests: false, + bench_benchmarks: false, + logfile: None, + nocapture: false, + color: AutoColor, + format: OutputFormat::Pretty, + test_threads: None, + skip: vec![], + options: Options::new(), + } + } +} + fn one_ignored_one_unignored_test() -> Vec { vec![ TestDescAndFn { -- cgit 1.4.1-3-g733a5 From 5b78e98a372c323c2dfa5a19bc110f1c81415f8e Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 19 Apr 2019 09:37:33 +0200 Subject: bump rand to fix Miri failures --- Cargo.lock | 13 +++++++++++-- src/liballoc/Cargo.toml | 4 ++-- src/liballoc/benches/slice.rs | 8 ++++---- 3 files changed, 17 insertions(+), 8 deletions(-) (limited to 'src/liballoc') diff --git a/Cargo.lock b/Cargo.lock index 972276bb381..ac6849c7549 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,8 +19,8 @@ version = "0.0.0" dependencies = [ "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", - "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_xorshift 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_xorshift 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2343,6 +2343,14 @@ dependencies = [ "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rand_xorshift" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rayon" version = "1.1.0" @@ -4569,6 +4577,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" "checksum rand_pcg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "086bd09a33c7044e56bb44d5bdde5a60e7f119a9e95b0775f545de759a32fe05" "checksum rand_xorshift 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "effa3fcaa47e18db002bdde6060944b6d2f9cfd8db471c30e873448ad9187be3" +"checksum rand_xorshift 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "77d416b86801d23dde1aa643023b775c3a462efc0ed96443add11546cdf1dca8" "checksum rayon 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a4b0186e22767d5b9738a05eab7c6ac90b15db17e5b5f9bd87976dd7d89a10a4" "checksum rayon-core 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbe0df8435ac0c397d467b6cad6d25543d06e8a019ef3f6af3c384597515bd2" "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" diff --git a/src/liballoc/Cargo.toml b/src/liballoc/Cargo.toml index bcb27bb5161..d1119f7b7c0 100644 --- a/src/liballoc/Cargo.toml +++ b/src/liballoc/Cargo.toml @@ -15,8 +15,8 @@ core = { path = "../libcore" } compiler_builtins = { version = "0.1.10", features = ['rustc-dep-of-std'] } [dev-dependencies] -rand = "0.6" -rand_xorshift = "0.1" +rand = "0.7" +rand_xorshift = "0.2" [[test]] name = "collectionstests" diff --git a/src/liballoc/benches/slice.rs b/src/liballoc/benches/slice.rs index f17fb8212ce..ef91d801dc7 100644 --- a/src/liballoc/benches/slice.rs +++ b/src/liballoc/benches/slice.rs @@ -186,12 +186,12 @@ const SEED: [u8; 16] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]; fn gen_random(len: usize) -> Vec { let mut rng = XorShiftRng::from_seed(SEED); - rng.sample_iter(&Standard).take(len).collect() + (&mut rng).sample_iter(&Standard).take(len).collect() } fn gen_random_bytes(len: usize) -> Vec { let mut rng = XorShiftRng::from_seed(SEED); - rng.sample_iter(&Standard).take(len).collect() + (&mut rng).sample_iter(&Standard).take(len).collect() } fn gen_mostly_ascending(len: usize) -> Vec { @@ -221,14 +221,14 @@ fn gen_strings(len: usize) -> Vec { let mut v = vec![]; for _ in 0..len { let n = rng.gen::() % 20 + 1; - v.push(rng.sample_iter(&Alphanumeric).take(n).collect()); + v.push((&mut rng).sample_iter(&Alphanumeric).take(n).collect()); } v } fn gen_big_random(len: usize) -> Vec<[u64; 16]> { let mut rng = XorShiftRng::from_seed(SEED); - rng.sample_iter(&Standard).map(|x| [x; 16]).take(len).collect() + (&mut rng).sample_iter(&Standard).map(|x| [x; 16]).take(len).collect() } macro_rules! sort { -- cgit 1.4.1-3-g733a5 From 32324d22c33dda31eadf49c5f27d6e6ff38a3ef1 Mon Sep 17 00:00:00 2001 From: Jake Goulding Date: Tue, 4 Jun 2019 08:15:47 -0400 Subject: Add implementations for converting boxed slices into boxed arrays This mirrors the implementations of reference slices into arrays. --- src/liballoc/boxed.rs | 19 +++++- src/liballoc/lib.rs | 2 +- src/liballoc/rc.rs | 19 +++++- src/liballoc/rc/tests.rs | 14 +++- src/liballoc/sync.rs | 19 +++++- src/liballoc/sync/tests.rs | 14 +++- src/liballoc/tests.rs | 13 ++++ .../array-impls/alloc-types-no-impls-length-33.rs | 26 ++++++++ .../alloc-types-no-impls-length-33.stderr | 75 ++++++++++++++++++++++ 9 files changed, 195 insertions(+), 6 deletions(-) create mode 100644 src/test/ui/const-generics/array-impls/alloc-types-no-impls-length-33.rs create mode 100644 src/test/ui/const-generics/array-impls/alloc-types-no-impls-length-33.stderr (limited to 'src/liballoc') diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 488fda0b247..c92db517cad 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -76,9 +76,10 @@ #![stable(feature = "rust1", since = "1.0.0")] use core::any::Any; +use core::array::LengthAtMost32; use core::borrow; use core::cmp::Ordering; -use core::convert::From; +use core::convert::{From, TryFrom}; use core::fmt; use core::future::Future; use core::hash::{Hash, Hasher}; @@ -612,6 +613,22 @@ impl From> for Box<[u8]> { } } +#[unstable(feature = "boxed_slice_try_from", issue = "0")] +impl TryFrom> for Box<[T; N]> +where + [T; N]: LengthAtMost32, +{ + type Error = Box<[T]>; + + fn try_from(boxed_slice: Box<[T]>) -> Result { + if boxed_slice.len() == N { + Ok(unsafe { Box::from_raw(Box::into_raw(boxed_slice) as *mut [T; N]) }) + } else { + Err(boxed_slice) + } + } +} + impl Box { #[inline] #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 98fa754759a..deea74daa52 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -82,9 +82,9 @@ #![feature(box_syntax)] #![feature(cfg_target_has_atomic)] #![feature(coerce_unsized)] -#![cfg_attr(not(bootstrap), feature(const_in_array_repeat_expressions))] #![feature(const_generic_impls_guard)] #![feature(const_generics)] +#![cfg_attr(not(bootstrap), feature(const_in_array_repeat_expressions))] #![feature(dispatch_from_dyn)] #![feature(core_intrinsics)] #![feature(dropck_eyepatch)] diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index e33aac3af47..0c406a92029 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -232,6 +232,7 @@ use crate::boxed::Box; use std::boxed::Box; use core::any::Any; +use core::array::LengthAtMost32; use core::borrow; use core::cell::Cell; use core::cmp::Ordering; @@ -245,7 +246,7 @@ use core::ops::{Deref, Receiver, CoerceUnsized, DispatchFromDyn}; use core::pin::Pin; use core::ptr::{self, NonNull}; use core::slice::{self, from_raw_parts_mut}; -use core::convert::From; +use core::convert::{From, TryFrom}; use core::usize; use crate::alloc::{Global, Alloc, Layout, box_free, handle_alloc_error}; @@ -1257,6 +1258,22 @@ impl From> for Rc<[T]> { } } +#[unstable(feature = "boxed_slice_try_from", issue = "0")] +impl TryFrom> for Rc<[T; N]> +where + [T; N]: LengthAtMost32, +{ + type Error = Rc<[T]>; + + fn try_from(boxed_slice: Rc<[T]>) -> Result { + if boxed_slice.len() == N { + Ok(unsafe { Rc::from_raw(Rc::into_raw(boxed_slice) as *mut [T; N]) }) + } else { + Err(boxed_slice) + } + } +} + #[stable(feature = "shared_from_iter", since = "1.37.0")] impl iter::FromIterator for Rc<[T]> { /// Takes each element in the `Iterator` and collects it into an `Rc<[T]>`. diff --git a/src/liballoc/rc/tests.rs b/src/liballoc/rc/tests.rs index 72816a5c120..6fd3f909357 100644 --- a/src/liballoc/rc/tests.rs +++ b/src/liballoc/rc/tests.rs @@ -6,7 +6,7 @@ use std::option::Option::{self, None, Some}; use std::result::Result::{Err, Ok}; use std::mem::drop; use std::clone::Clone; -use std::convert::From; +use std::convert::{From, TryInto}; #[test] fn test_clone() { @@ -425,3 +425,15 @@ fn test_downcast() { assert!(r2str.is_ok()); assert_eq!(r2str.unwrap(), Rc::new("abc")); } + +#[test] +fn test_array_from_slice() { + let v = vec![1, 2, 3]; + let r: Rc<[u32]> = Rc::from(v); + + let a: Result, _> = r.clone().try_into(); + assert!(a.is_ok()); + + let a: Result, _> = r.clone().try_into(); + assert!(a.is_err()); +} diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index e11873218e8..7d3b2656a7b 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -7,6 +7,7 @@ //! [arc]: struct.Arc.html use core::any::Any; +use core::array::LengthAtMost32; use core::sync::atomic; use core::sync::atomic::Ordering::{Acquire, Relaxed, Release, SeqCst}; use core::borrow; @@ -21,7 +22,7 @@ use core::ptr::{self, NonNull}; use core::marker::{Unpin, Unsize, PhantomData}; use core::hash::{Hash, Hasher}; use core::{isize, usize}; -use core::convert::From; +use core::convert::{From, TryFrom}; use core::slice::{self, from_raw_parts_mut}; use crate::alloc::{Global, Alloc, Layout, box_free, handle_alloc_error}; @@ -1826,6 +1827,22 @@ impl From> for Arc<[T]> { } } +#[unstable(feature = "boxed_slice_try_from", issue = "0")] +impl TryFrom> for Arc<[T; N]> +where + [T; N]: LengthAtMost32, +{ + type Error = Arc<[T]>; + + fn try_from(boxed_slice: Arc<[T]>) -> Result { + if boxed_slice.len() == N { + Ok(unsafe { Arc::from_raw(Arc::into_raw(boxed_slice) as *mut [T; N]) }) + } else { + Err(boxed_slice) + } + } +} + #[stable(feature = "shared_from_iter", since = "1.37.0")] impl iter::FromIterator for Arc<[T]> { /// Takes each element in the `Iterator` and collects it into an `Arc<[T]>`. diff --git a/src/liballoc/sync/tests.rs b/src/liballoc/sync/tests.rs index 2e0c62f50c1..9220f5e0333 100644 --- a/src/liballoc/sync/tests.rs +++ b/src/liballoc/sync/tests.rs @@ -9,7 +9,7 @@ use std::option::Option::{self, None, Some}; use std::sync::atomic::{self, Ordering::{Acquire, SeqCst}}; use std::thread; use std::sync::Mutex; -use std::convert::From; +use std::convert::{From, TryInto}; use crate::vec::Vec; @@ -478,3 +478,15 @@ fn test_downcast() { assert!(r2str.is_ok()); assert_eq!(r2str.unwrap(), Arc::new("abc")); } + +#[test] +fn test_array_from_slice() { + let v = vec![1, 2, 3]; + let r: Arc<[u32]> = Arc::from(v); + + let a: Result, _> = r.clone().try_into(); + assert!(a.is_ok()); + + let a: Result, _> = r.clone().try_into(); + assert!(a.is_err()); +} diff --git a/src/liballoc/tests.rs b/src/liballoc/tests.rs index 654eabd0703..ed46ba8a1b9 100644 --- a/src/liballoc/tests.rs +++ b/src/liballoc/tests.rs @@ -1,6 +1,7 @@ //! Test for `boxed` mod. use core::any::Any; +use core::convert::TryInto; use core::ops::Deref; use core::result::Result::{Err, Ok}; use core::clone::Clone; @@ -138,3 +139,15 @@ fn boxed_slice_from_iter() { assert_eq!(boxed.len(), 100); assert_eq!(boxed[7], 7); } + +#[test] +fn test_array_from_slice() { + let v = vec![1, 2, 3]; + let r: Box<[u32]> = v.into_boxed_slice(); + + let a: Result, _> = r.clone().try_into(); + assert!(a.is_ok()); + + let a: Result, _> = r.clone().try_into(); + assert!(a.is_err()); +} diff --git a/src/test/ui/const-generics/array-impls/alloc-types-no-impls-length-33.rs b/src/test/ui/const-generics/array-impls/alloc-types-no-impls-length-33.rs new file mode 100644 index 00000000000..3a23b9b5832 --- /dev/null +++ b/src/test/ui/const-generics/array-impls/alloc-types-no-impls-length-33.rs @@ -0,0 +1,26 @@ +// ignore-tidy-linelength + +use std::{convert::TryFrom, rc::Rc, sync::Arc}; + +pub fn no_box() { + let boxed_slice = Box::new([0; 33]) as Box<[i32]>; + let boxed_array = >::try_from(boxed_slice); + //~^ ERROR the trait bound `std::boxed::Box<[i32; 33]>: std::convert::From>` is not satisfied + //~^^ ERROR the trait bound `std::boxed::Box<[i32; 33]>: std::convert::TryFrom>` is not satisfied +} + +pub fn no_rc() { + let boxed_slice = Rc::new([0; 33]) as Rc<[i32]>; + let boxed_array = >::try_from(boxed_slice); + //~^ ERROR the trait bound `std::rc::Rc<[i32; 33]>: std::convert::From>` is not satisfied + //~^^ ERROR the trait bound `std::rc::Rc<[i32; 33]>: std::convert::TryFrom>` is not satisfied +} + +pub fn no_arc() { + let boxed_slice = Arc::new([0; 33]) as Arc<[i32]>; + let boxed_array = >::try_from(boxed_slice); + //~^ ERROR the trait bound `std::sync::Arc<[i32; 33]>: std::convert::From>` is not satisfied + //~^^ ERROR the trait bound `std::sync::Arc<[i32; 33]>: std::convert::TryFrom>` is not satisfied +} + +fn main() {} diff --git a/src/test/ui/const-generics/array-impls/alloc-types-no-impls-length-33.stderr b/src/test/ui/const-generics/array-impls/alloc-types-no-impls-length-33.stderr new file mode 100644 index 00000000000..193fb4c4374 --- /dev/null +++ b/src/test/ui/const-generics/array-impls/alloc-types-no-impls-length-33.stderr @@ -0,0 +1,75 @@ +error[E0277]: the trait bound `std::boxed::Box<[i32; 33]>: std::convert::From>` is not satisfied + --> $DIR/alloc-types-no-impls-length-33.rs:7:23 + | +LL | let boxed_array = >::try_from(boxed_slice); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::From>` is not implemented for `std::boxed::Box<[i32; 33]>` + | + = help: the following implementations were found: + as std::convert::From> + as std::convert::From<&str>> + as std::convert::From>> + as std::convert::From> + and 16 others + = note: required because of the requirements on the impl of `std::convert::Into>` for `std::boxed::Box<[i32]>` + = note: required because of the requirements on the impl of `std::convert::TryFrom>` for `std::boxed::Box<[i32; 33]>` + +error[E0277]: the trait bound `std::boxed::Box<[i32; 33]>: std::convert::TryFrom>` is not satisfied + --> $DIR/alloc-types-no-impls-length-33.rs:7:23 + | +LL | let boxed_array = >::try_from(boxed_slice); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::TryFrom>` is not implemented for `std::boxed::Box<[i32; 33]>` + | + = help: the following implementations were found: + as std::convert::TryFrom>> + +error[E0277]: the trait bound `std::rc::Rc<[i32; 33]>: std::convert::From>` is not satisfied + --> $DIR/alloc-types-no-impls-length-33.rs:14:23 + | +LL | let boxed_array = >::try_from(boxed_slice); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::From>` is not implemented for `std::rc::Rc<[i32; 33]>` + | + = help: the following implementations were found: + as std::convert::From> + as std::convert::From>> + as std::convert::From<&[T]>> + as std::convert::From>> + and 8 others + = note: required because of the requirements on the impl of `std::convert::Into>` for `std::rc::Rc<[i32]>` + = note: required because of the requirements on the impl of `std::convert::TryFrom>` for `std::rc::Rc<[i32; 33]>` + +error[E0277]: the trait bound `std::rc::Rc<[i32; 33]>: std::convert::TryFrom>` is not satisfied + --> $DIR/alloc-types-no-impls-length-33.rs:14:23 + | +LL | let boxed_array = >::try_from(boxed_slice); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::TryFrom>` is not implemented for `std::rc::Rc<[i32; 33]>` + | + = help: the following implementations were found: + as std::convert::TryFrom>> + +error[E0277]: the trait bound `std::sync::Arc<[i32; 33]>: std::convert::From>` is not satisfied + --> $DIR/alloc-types-no-impls-length-33.rs:21:23 + | +LL | let boxed_array = >::try_from(boxed_slice); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::From>` is not implemented for `std::sync::Arc<[i32; 33]>` + | + = help: the following implementations were found: + as std::convert::From> + as std::convert::From>> + as std::convert::From<&[T]>> + as std::convert::From>> + and 8 others + = note: required because of the requirements on the impl of `std::convert::Into>` for `std::sync::Arc<[i32]>` + = note: required because of the requirements on the impl of `std::convert::TryFrom>` for `std::sync::Arc<[i32; 33]>` + +error[E0277]: the trait bound `std::sync::Arc<[i32; 33]>: std::convert::TryFrom>` is not satisfied + --> $DIR/alloc-types-no-impls-length-33.rs:21:23 + | +LL | let boxed_array = >::try_from(boxed_slice); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::TryFrom>` is not implemented for `std::sync::Arc<[i32; 33]>` + | + = help: the following implementations were found: + as std::convert::TryFrom>> + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0277`. -- cgit 1.4.1-3-g733a5