From 67c9ef2c2fd417875ae2231212f85edd12544ce3 Mon Sep 17 00:00:00 2001 From: Jendrik Date: Thu, 13 Jan 2022 14:18:28 +0100 Subject: [PATCH 01/11] add #[must_use] to functions of slice and its iterators. --- library/core/src/slice/ascii.rs | 1 + library/core/src/slice/index.rs | 1 + library/core/src/slice/iter.rs | 26 ++++++++++++++++++++ library/core/src/slice/mod.rs | 43 +++++++++++++++++++++++++++++++++ library/core/src/slice/raw.rs | 4 +++ library/core/tests/slice.rs | 8 +++--- 6 files changed, 79 insertions(+), 4 deletions(-) diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs index 080256f493f5f..f07c890f3bc49 100644 --- a/library/core/src/slice/ascii.rs +++ b/library/core/src/slice/ascii.rs @@ -95,6 +95,7 @@ impl_fn_for_zst! { /// documentation for more information. #[unstable(feature = "inherent_ascii_escape", issue = "77174")] #[derive(Clone)] +#[must_use = "iterators are lazy and do nothing unless consumed"] pub struct EscapeAscii<'a> { inner: iter::FlatMap, ascii::EscapeDefault, EscapeByte>, } diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs index 0298bba8d329e..33c7afd9e2e94 100644 --- a/library/core/src/slice/index.rs +++ b/library/core/src/slice/index.rs @@ -520,6 +520,7 @@ unsafe impl SliceIndex<[T]> for ops::RangeToInclusive { /// [`Index::index`]: ops::Index::index #[track_caller] #[unstable(feature = "slice_range", issue = "76393")] +#[must_use] pub fn range(range: R, bounds: ops::RangeTo) -> ops::Range where R: ops::RangeBounds, diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs index 176820efe398e..d548585873824 100644 --- a/library/core/src/slice/iter.rs +++ b/library/core/src/slice/iter.rs @@ -62,6 +62,7 @@ fn size_from_ptr(_: *const T) -> usize { /// [`iter`]: slice::iter /// [slices]: slice #[stable(feature = "rust1", since = "1.0.0")] +#[must_use = "iterators are lazy and do nothing unless consumed"] pub struct Iter<'a, T: 'a> { ptr: NonNull, end: *const T, // If T is a ZST, this is actually ptr+len. This encoding is picked so that @@ -182,6 +183,7 @@ impl AsRef<[T]> for Iter<'_, T> { /// [`iter_mut`]: slice::iter_mut /// [slices]: slice #[stable(feature = "rust1", since = "1.0.0")] +#[must_use = "iterators are lazy and do nothing unless consumed"] pub struct IterMut<'a, T: 'a> { ptr: NonNull, end: *mut T, // If T is a ZST, this is actually ptr+len. This encoding is picked so that @@ -339,6 +341,7 @@ pub(super) trait SplitIter: DoubleEndedIterator { /// [`split`]: slice::split /// [slices]: slice #[stable(feature = "rust1", since = "1.0.0")] +#[must_use = "iterators are lazy and do nothing unless consumed"] pub struct Split<'a, T: 'a, P> where P: FnMut(&T) -> bool, @@ -469,6 +472,7 @@ impl FusedIterator for Split<'_, T, P> where P: FnMut(&T) -> bool {} /// [`split_inclusive`]: slice::split_inclusive /// [slices]: slice #[stable(feature = "split_inclusive", since = "1.51.0")] +#[must_use = "iterators are lazy and do nothing unless consumed"] pub struct SplitInclusive<'a, T: 'a, P> where P: FnMut(&T) -> bool, @@ -589,6 +593,7 @@ impl FusedIterator for SplitInclusive<'_, T, P> where P: FnMut(&T) -> bool /// [`split_mut`]: slice::split_mut /// [slices]: slice #[stable(feature = "rust1", since = "1.0.0")] +#[must_use = "iterators are lazy and do nothing unless consumed"] pub struct SplitMut<'a, T: 'a, P> where P: FnMut(&T) -> bool, @@ -718,6 +723,7 @@ impl FusedIterator for SplitMut<'_, T, P> where P: FnMut(&T) -> bool {} /// [`split_inclusive_mut`]: slice::split_inclusive_mut /// [slices]: slice #[stable(feature = "split_inclusive", since = "1.51.0")] +#[must_use = "iterators are lazy and do nothing unless consumed"] pub struct SplitInclusiveMut<'a, T: 'a, P> where P: FnMut(&T) -> bool, @@ -841,6 +847,7 @@ impl FusedIterator for SplitInclusiveMut<'_, T, P> where P: FnMut(&T) -> b /// [`rsplit`]: slice::rsplit /// [slices]: slice #[stable(feature = "slice_rsplit", since = "1.27.0")] +#[must_use = "iterators are lazy and do nothing unless consumed"] pub struct RSplit<'a, T: 'a, P> where P: FnMut(&T) -> bool, @@ -937,6 +944,7 @@ impl FusedIterator for RSplit<'_, T, P> where P: FnMut(&T) -> bool {} /// [`rsplit_mut`]: slice::rsplit_mut /// [slices]: slice #[stable(feature = "slice_rsplit", since = "1.27.0")] +#[must_use = "iterators are lazy and do nothing unless consumed"] pub struct RSplitMut<'a, T: 'a, P> where P: FnMut(&T) -> bool, @@ -1059,6 +1067,7 @@ impl> Iterator for GenericSplitN { /// [`splitn`]: slice::splitn /// [slices]: slice #[stable(feature = "rust1", since = "1.0.0")] +#[must_use = "iterators are lazy and do nothing unless consumed"] pub struct SplitN<'a, T: 'a, P> where P: FnMut(&T) -> bool, @@ -1099,6 +1108,7 @@ where /// [`rsplitn`]: slice::rsplitn /// [slices]: slice #[stable(feature = "rust1", since = "1.0.0")] +#[must_use = "iterators are lazy and do nothing unless consumed"] pub struct RSplitN<'a, T: 'a, P> where P: FnMut(&T) -> bool, @@ -1138,6 +1148,7 @@ where /// [`splitn_mut`]: slice::splitn_mut /// [slices]: slice #[stable(feature = "rust1", since = "1.0.0")] +#[must_use = "iterators are lazy and do nothing unless consumed"] pub struct SplitNMut<'a, T: 'a, P> where P: FnMut(&T) -> bool, @@ -1178,6 +1189,7 @@ where /// [`rsplitn_mut`]: slice::rsplitn_mut /// [slices]: slice #[stable(feature = "rust1", since = "1.0.0")] +#[must_use = "iterators are lazy and do nothing unless consumed"] pub struct RSplitNMut<'a, T: 'a, P> where P: FnMut(&T) -> bool, @@ -1222,6 +1234,7 @@ forward_iterator! { RSplitNMut: T, &'a mut [T] } /// [slices]: slice #[derive(Debug)] #[stable(feature = "rust1", since = "1.0.0")] +#[must_use = "iterators are lazy and do nothing unless consumed"] pub struct Windows<'a, T: 'a> { v: &'a [T], size: NonZeroUsize, @@ -1370,6 +1383,7 @@ unsafe impl<'a, T> TrustedRandomAccessNoCoerce for Windows<'a, T> { /// [slices]: slice #[derive(Debug)] #[stable(feature = "rust1", since = "1.0.0")] +#[must_use = "iterators are lazy and do nothing unless consumed"] pub struct Chunks<'a, T: 'a> { v: &'a [T], chunk_size: usize, @@ -1539,6 +1553,7 @@ unsafe impl<'a, T> TrustedRandomAccessNoCoerce for Chunks<'a, T> { /// [slices]: slice #[derive(Debug)] #[stable(feature = "rust1", since = "1.0.0")] +#[must_use = "iterators are lazy and do nothing unless consumed"] pub struct ChunksMut<'a, T: 'a> { v: &'a mut [T], chunk_size: usize, @@ -1707,6 +1722,7 @@ unsafe impl<'a, T> TrustedRandomAccessNoCoerce for ChunksMut<'a, T> { /// [slices]: slice #[derive(Debug)] #[stable(feature = "chunks_exact", since = "1.31.0")] +#[must_use = "iterators are lazy and do nothing unless consumed"] pub struct ChunksExact<'a, T: 'a> { v: &'a [T], rem: &'a [T], @@ -1866,6 +1882,7 @@ unsafe impl<'a, T> TrustedRandomAccessNoCoerce for ChunksExact<'a, T> { /// [slices]: slice #[derive(Debug)] #[stable(feature = "chunks_exact", since = "1.31.0")] +#[must_use = "iterators are lazy and do nothing unless consumed"] pub struct ChunksExactMut<'a, T: 'a> { v: &'a mut [T], rem: &'a mut [T], @@ -2019,6 +2036,7 @@ unsafe impl<'a, T> TrustedRandomAccessNoCoerce for ChunksExactMut<'a, T> { /// [slices]: slice #[derive(Debug, Clone, Copy)] #[unstable(feature = "array_windows", issue = "75027")] +#[must_use = "iterators are lazy and do nothing unless consumed"] pub struct ArrayWindows<'a, T: 'a, const N: usize> { slice_head: *const T, num: usize, @@ -2141,6 +2159,7 @@ impl ExactSizeIterator for ArrayWindows<'_, T, N> { /// [slices]: slice #[derive(Debug)] #[unstable(feature = "array_chunks", issue = "74985")] +#[must_use = "iterators are lazy and do nothing unless consumed"] pub struct ArrayChunks<'a, T: 'a, const N: usize> { iter: Iter<'a, [T; N]>, rem: &'a [T], @@ -2267,6 +2286,7 @@ unsafe impl<'a, T, const N: usize> TrustedRandomAccessNoCoerce for ArrayChunks<' /// [slices]: slice #[derive(Debug)] #[unstable(feature = "array_chunks", issue = "74985")] +#[must_use = "iterators are lazy and do nothing unless consumed"] pub struct ArrayChunksMut<'a, T: 'a, const N: usize> { iter: IterMut<'a, [T; N]>, rem: &'a mut [T], @@ -2381,6 +2401,7 @@ unsafe impl<'a, T, const N: usize> TrustedRandomAccessNoCoerce for ArrayChunksMu /// [slices]: slice #[derive(Debug)] #[stable(feature = "rchunks", since = "1.31.0")] +#[must_use = "iterators are lazy and do nothing unless consumed"] pub struct RChunks<'a, T: 'a> { v: &'a [T], chunk_size: usize, @@ -2547,6 +2568,7 @@ unsafe impl<'a, T> TrustedRandomAccessNoCoerce for RChunks<'a, T> { /// [slices]: slice #[derive(Debug)] #[stable(feature = "rchunks", since = "1.31.0")] +#[must_use = "iterators are lazy and do nothing unless consumed"] pub struct RChunksMut<'a, T: 'a> { v: &'a mut [T], chunk_size: usize, @@ -2714,6 +2736,7 @@ unsafe impl<'a, T> TrustedRandomAccessNoCoerce for RChunksMut<'a, T> { /// [slices]: slice #[derive(Debug)] #[stable(feature = "rchunks", since = "1.31.0")] +#[must_use = "iterators are lazy and do nothing unless consumed"] pub struct RChunksExact<'a, T: 'a> { v: &'a [T], rem: &'a [T], @@ -2877,6 +2900,7 @@ unsafe impl<'a, T> TrustedRandomAccessNoCoerce for RChunksExact<'a, T> { /// [slices]: slice #[derive(Debug)] #[stable(feature = "rchunks", since = "1.31.0")] +#[must_use = "iterators are lazy and do nothing unless consumed"] pub struct RChunksExactMut<'a, T: 'a> { v: &'a mut [T], rem: &'a mut [T], @@ -3043,6 +3067,7 @@ unsafe impl<'a, T> TrustedRandomAccessNoCoerce for IterMut<'a, T> { /// [`group_by`]: slice::group_by /// [slices]: slice #[unstable(feature = "slice_group_by", issue = "80552")] +#[must_use = "iterators are lazy and do nothing unless consumed"] pub struct GroupBy<'a, T: 'a, P> { slice: &'a [T], predicate: P, @@ -3129,6 +3154,7 @@ impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for GroupBy<'a, T, P> { /// [`group_by_mut`]: slice::group_by_mut /// [slices]: slice #[unstable(feature = "slice_group_by", issue = "80552")] +#[must_use = "iterators are lazy and do nothing unless consumed"] pub struct GroupByMut<'a, T: 'a, P> { slice: &'a mut [T], predicate: P, diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 0599f27401394..31840b1943bc0 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -122,6 +122,7 @@ impl [T] { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_slice_len", since = "1.39.0")] #[inline] + #[must_use] // SAFETY: const sound because we transmute out the length field as a usize (which it must be) pub const fn len(&self) -> usize { // FIXME: Replace with `crate::ptr::metadata(self)` when that is const-stable. @@ -145,6 +146,7 @@ impl [T] { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_slice_is_empty", since = "1.39.0")] #[inline] + #[must_use] pub const fn is_empty(&self) -> bool { self.len() == 0 } @@ -163,6 +165,7 @@ impl [T] { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_slice_first_last_not_mut", since = "1.56.0")] #[inline] + #[must_use] pub const fn first(&self) -> Option<&T> { if let [first, ..] = self { Some(first) } else { None } } @@ -182,6 +185,7 @@ impl [T] { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_slice_first_last", issue = "83570")] #[inline] + #[must_use] pub const fn first_mut(&mut self) -> Option<&mut T> { if let [first, ..] = self { Some(first) } else { None } } @@ -201,6 +205,7 @@ impl [T] { #[stable(feature = "slice_splits", since = "1.5.0")] #[rustc_const_stable(feature = "const_slice_first_last_not_mut", since = "1.56.0")] #[inline] + #[must_use] pub const fn split_first(&self) -> Option<(&T, &[T])> { if let [first, tail @ ..] = self { Some((first, tail)) } else { None } } @@ -222,6 +227,7 @@ impl [T] { #[stable(feature = "slice_splits", since = "1.5.0")] #[rustc_const_unstable(feature = "const_slice_first_last", issue = "83570")] #[inline] + #[must_use] pub const fn split_first_mut(&mut self) -> Option<(&mut T, &mut [T])> { if let [first, tail @ ..] = self { Some((first, tail)) } else { None } } @@ -241,6 +247,7 @@ impl [T] { #[stable(feature = "slice_splits", since = "1.5.0")] #[rustc_const_stable(feature = "const_slice_first_last_not_mut", since = "1.56.0")] #[inline] + #[must_use] pub const fn split_last(&self) -> Option<(&T, &[T])> { if let [init @ .., last] = self { Some((last, init)) } else { None } } @@ -262,6 +269,7 @@ impl [T] { #[stable(feature = "slice_splits", since = "1.5.0")] #[rustc_const_unstable(feature = "const_slice_first_last", issue = "83570")] #[inline] + #[must_use] pub const fn split_last_mut(&mut self) -> Option<(&mut T, &mut [T])> { if let [init @ .., last] = self { Some((last, init)) } else { None } } @@ -280,6 +288,7 @@ impl [T] { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_slice_first_last_not_mut", since = "1.56.0")] #[inline] + #[must_use] pub const fn last(&self) -> Option<&T> { if let [.., last] = self { Some(last) } else { None } } @@ -299,6 +308,7 @@ impl [T] { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_slice_first_last", issue = "83570")] #[inline] + #[must_use] pub const fn last_mut(&mut self) -> Option<&mut T> { if let [.., last] = self { Some(last) } else { None } } @@ -322,6 +332,7 @@ impl [T] { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] + #[must_use] pub fn get(&self, index: I) -> Option<&I::Output> where I: SliceIndex, @@ -346,6 +357,7 @@ impl [T] { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] + #[must_use] pub fn get_mut(&mut self, index: I) -> Option<&mut I::Output> where I: SliceIndex, @@ -377,6 +389,7 @@ impl [T] { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] + #[must_use] pub unsafe fn get_unchecked(&self, index: I) -> &I::Output where I: SliceIndex, @@ -413,6 +426,7 @@ impl [T] { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] + #[must_use] pub unsafe fn get_unchecked_mut(&mut self, index: I) -> &mut I::Output where I: SliceIndex, @@ -452,6 +466,7 @@ impl [T] { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_slice_as_ptr", since = "1.32.0")] #[inline] + #[must_use] pub const fn as_ptr(&self) -> *const T { self as *const [T] as *const T } @@ -480,6 +495,7 @@ impl [T] { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_ptr_offset", issue = "71499")] #[inline] + #[must_use] pub const fn as_mut_ptr(&mut self) -> *mut T { self as *mut [T] as *mut T } @@ -515,6 +531,7 @@ impl [T] { #[stable(feature = "slice_ptr_range", since = "1.48.0")] #[rustc_const_unstable(feature = "const_ptr_offset", issue = "71499")] #[inline] + #[must_use] pub const fn as_ptr_range(&self) -> Range<*const T> { let start = self.as_ptr(); // SAFETY: The `add` here is safe, because: @@ -557,6 +574,7 @@ impl [T] { #[stable(feature = "slice_ptr_range", since = "1.48.0")] #[rustc_const_unstable(feature = "const_ptr_offset", issue = "71499")] #[inline] + #[must_use] pub const fn as_mut_ptr_range(&mut self) -> Range<*mut T> { let start = self.as_mut_ptr(); // SAFETY: See as_ptr_range() above for why `add` here is safe. @@ -936,6 +954,7 @@ impl [T] { /// ``` #[unstable(feature = "slice_as_chunks", issue = "74985")] #[inline] + #[must_use] pub unsafe fn as_chunks_unchecked(&self) -> &[[T; N]] { debug_assert_ne!(N, 0); debug_assert_eq!(self.len() % N, 0); @@ -967,6 +986,7 @@ impl [T] { /// ``` #[unstable(feature = "slice_as_chunks", issue = "74985")] #[inline] + #[must_use] pub fn as_chunks(&self) -> (&[[T; N]], &[T]) { assert_ne!(N, 0); let len = self.len() / N; @@ -997,6 +1017,7 @@ impl [T] { /// ``` #[unstable(feature = "slice_as_chunks", issue = "74985")] #[inline] + #[must_use] pub fn as_rchunks(&self) -> (&[T], &[[T; N]]) { assert_ne!(N, 0); let len = self.len() / N; @@ -1072,6 +1093,7 @@ impl [T] { /// ``` #[unstable(feature = "slice_as_chunks", issue = "74985")] #[inline] + #[must_use] pub unsafe fn as_chunks_unchecked_mut(&mut self) -> &mut [[T; N]] { debug_assert_ne!(N, 0); debug_assert_eq!(self.len() % N, 0); @@ -1109,6 +1131,7 @@ impl [T] { /// ``` #[unstable(feature = "slice_as_chunks", issue = "74985")] #[inline] + #[must_use] pub fn as_chunks_mut(&mut self) -> (&mut [[T; N]], &mut [T]) { assert_ne!(N, 0); let len = self.len() / N; @@ -1145,6 +1168,7 @@ impl [T] { /// ``` #[unstable(feature = "slice_as_chunks", issue = "74985")] #[inline] + #[must_use] pub fn as_rchunks_mut(&mut self) -> (&mut [T], &mut [[T; N]]) { assert_ne!(N, 0); let len = self.len() / N; @@ -1503,6 +1527,7 @@ impl [T] { #[stable(feature = "rust1", since = "1.0.0")] #[inline] #[track_caller] + #[must_use] pub fn split_at(&self, mid: usize) -> (&[T], &[T]) { assert!(mid <= self.len()); // SAFETY: `[ptr; mid]` and `[mid; len]` are inside `self`, which @@ -1534,6 +1559,7 @@ impl [T] { #[stable(feature = "rust1", since = "1.0.0")] #[inline] #[track_caller] + #[must_use] pub fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) { assert!(mid <= self.len()); // SAFETY: `[ptr; mid]` and `[mid; len]` are inside `self`, which @@ -1585,6 +1611,7 @@ impl [T] { /// ``` #[unstable(feature = "slice_split_at_unchecked", reason = "new API", issue = "76014")] #[inline] + #[must_use] pub unsafe fn split_at_unchecked(&self, mid: usize) -> (&[T], &[T]) { // SAFETY: Caller has to check that `0 <= mid <= self.len()` unsafe { (self.get_unchecked(..mid), self.get_unchecked(mid..)) } @@ -1625,6 +1652,7 @@ impl [T] { /// ``` #[unstable(feature = "slice_split_at_unchecked", reason = "new API", issue = "76014")] #[inline] + #[must_use] pub unsafe fn split_at_mut_unchecked(&mut self, mid: usize) -> (&mut [T], &mut [T]) { let len = self.len(); let ptr = self.as_mut_ptr(); @@ -1674,6 +1702,7 @@ impl [T] { #[unstable(feature = "split_array", reason = "new API", issue = "90091")] #[inline] #[track_caller] + #[must_use] pub fn split_array_ref(&self) -> (&[T; N], &[T]) { let (a, b) = self.split_at(N); // SAFETY: a points to [T; N]? Yes it's [T] of length N (checked by split_at) @@ -1706,6 +1735,7 @@ impl [T] { #[unstable(feature = "split_array", reason = "new API", issue = "90091")] #[inline] #[track_caller] + #[must_use] pub fn split_array_mut(&mut self) -> (&mut [T; N], &mut [T]) { let (a, b) = self.split_at_mut(N); // SAFETY: a points to [T; N]? Yes it's [T] of length N (checked by split_at_mut) @@ -1750,6 +1780,7 @@ impl [T] { /// ``` #[unstable(feature = "split_array", reason = "new API", issue = "90091")] #[inline] + #[must_use] pub fn rsplit_array_ref(&self) -> (&[T], &[T; N]) { assert!(N <= self.len()); let (a, b) = self.split_at(self.len() - N); @@ -1783,6 +1814,7 @@ impl [T] { /// ``` #[unstable(feature = "split_array", reason = "new API", issue = "90091")] #[inline] + #[must_use] pub fn rsplit_array_mut(&mut self) -> (&mut [T], &mut [T; N]) { assert!(N <= self.len()); let (a, b) = self.split_at_mut(self.len() - N); @@ -2114,6 +2146,7 @@ impl [T] { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] + #[must_use] pub fn contains(&self, x: &T) -> bool where T: PartialEq, @@ -2142,6 +2175,7 @@ impl [T] { /// assert!(v.starts_with(&[])); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[must_use] pub fn starts_with(&self, needle: &[T]) -> bool where T: PartialEq, @@ -2171,6 +2205,7 @@ impl [T] { /// assert!(v.ends_with(&[])); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[must_use] pub fn ends_with(&self, needle: &[T]) -> bool where T: PartialEq, @@ -3422,6 +3457,7 @@ impl [T] { /// } /// ``` #[stable(feature = "slice_align_to", since = "1.30.0")] + #[must_use] pub unsafe fn align_to(&self) -> (&[T], &[U], &[T]) { // Note that most of this function will be constant-evaluated, if mem::size_of::() == 0 || mem::size_of::() == 0 { @@ -3482,6 +3518,7 @@ impl [T] { /// } /// ``` #[stable(feature = "slice_align_to", since = "1.30.0")] + #[must_use] pub unsafe fn align_to_mut(&mut self) -> (&mut [T], &mut [U], &mut [T]) { // Note that most of this function will be constant-evaluated, if mem::size_of::() == 0 || mem::size_of::() == 0 { @@ -3576,6 +3613,7 @@ impl [T] { /// ``` #[unstable(feature = "portable_simd", issue = "86656")] #[cfg(not(miri))] // Miri does not support all SIMD intrinsics + #[must_use] pub fn as_simd(&self) -> (&[T], &[Simd], &[T]) where Simd: AsRef<[T; LANES]>, @@ -3620,6 +3658,7 @@ impl [T] { /// method for something like `LANES == 3`. #[unstable(feature = "portable_simd", issue = "86656")] #[cfg(not(miri))] // Miri does not support all SIMD intrinsics + #[must_use] pub fn as_simd_mut(&mut self) -> (&mut [T], &mut [Simd], &mut [T]) where Simd: AsMut<[T; LANES]>, @@ -3659,6 +3698,7 @@ impl [T] { /// ``` #[inline] #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")] + #[must_use] pub fn is_sorted(&self) -> bool where T: PartialOrd, @@ -3674,6 +3714,7 @@ impl [T] { /// /// [`is_sorted`]: slice::is_sorted #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")] + #[must_use] pub fn is_sorted_by(&self, mut compare: F) -> bool where F: FnMut(&T, &T) -> Option, @@ -3699,6 +3740,7 @@ impl [T] { /// ``` #[inline] #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")] + #[must_use] pub fn is_sorted_by_key(&self, f: F) -> bool where F: FnMut(&T) -> K, @@ -3736,6 +3778,7 @@ impl [T] { /// assert!(v[i..].iter().all(|&x| !(x < 5))); /// ``` #[stable(feature = "partition_point", since = "1.52.0")] + #[must_use] pub fn partition_point

(&self, mut pred: P) -> usize where P: FnMut(&T) -> bool, diff --git a/library/core/src/slice/raw.rs b/library/core/src/slice/raw.rs index e797283818481..25882167e0a2b 100644 --- a/library/core/src/slice/raw.rs +++ b/library/core/src/slice/raw.rs @@ -84,6 +84,7 @@ use crate::ptr; #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_slice_from_raw_parts", issue = "67456")] +#[must_use] pub const unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] { debug_check_data_len(data, len); @@ -123,6 +124,7 @@ pub const unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_slice_from_raw_parts", issue = "67456")] +#[must_use] pub const unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] { debug_check_data_len(data as _, len); @@ -167,6 +169,7 @@ const fn debug_check_data_len(_data: *const T, _len: usize) {} /// Converts a reference to T into a slice of length 1 (without copying). #[stable(feature = "from_ref", since = "1.28.0")] #[rustc_const_unstable(feature = "const_slice_from_ref", issue = "90206")] +#[must_use] pub const fn from_ref(s: &T) -> &[T] { array::from_ref(s) } @@ -174,6 +177,7 @@ pub const fn from_ref(s: &T) -> &[T] { /// Converts a reference to T into a slice of length 1 (without copying). #[stable(feature = "from_ref", since = "1.28.0")] #[rustc_const_unstable(feature = "const_slice_from_ref", issue = "90206")] +#[must_use] pub const fn from_mut(s: &mut T) -> &mut [T] { array::from_mut(s) } diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs index 20e2d8d47c0f5..72d5a4f9d9515 100644 --- a/library/core/tests/slice.rs +++ b/library/core/tests/slice.rs @@ -2241,7 +2241,7 @@ fn slice_rsplit_array_mut() { fn slice_split_array_ref_out_of_bounds() { let v = &[1, 2, 3, 4, 5, 6][..]; - v.split_array_ref::<7>(); + let _ = v.split_array_ref::<7>(); } #[should_panic] @@ -2249,7 +2249,7 @@ fn slice_split_array_ref_out_of_bounds() { fn slice_split_array_mut_out_of_bounds() { let v = &mut [1, 2, 3, 4, 5, 6][..]; - v.split_array_mut::<7>(); + let _ = v.split_array_mut::<7>(); } #[should_panic] @@ -2257,7 +2257,7 @@ fn slice_split_array_mut_out_of_bounds() { fn slice_rsplit_array_ref_out_of_bounds() { let v = &[1, 2, 3, 4, 5, 6][..]; - v.rsplit_array_ref::<7>(); + let _ = v.rsplit_array_ref::<7>(); } #[should_panic] @@ -2265,7 +2265,7 @@ fn slice_rsplit_array_ref_out_of_bounds() { fn slice_rsplit_array_mut_out_of_bounds() { let v = &mut [1, 2, 3, 4, 5, 6][..]; - v.rsplit_array_mut::<7>(); + let _ = v.rsplit_array_mut::<7>(); } macro_rules! take_tests { From cdf22c319e0553cf838f72aee4db05c5dda1a132 Mon Sep 17 00:00:00 2001 From: Jendrik Date: Thu, 13 Jan 2022 14:57:57 +0100 Subject: [PATCH 02/11] add #[must_use] to functions of slice and its iterators. --- library/core/src/slice/index.rs | 6 ++--- .../iterators/into-iter-on-arrays-lint.fixed | 1 + .../ui/iterators/into-iter-on-arrays-lint.rs | 1 + .../iterators/into-iter-on-arrays-lint.stderr | 24 +++++++++---------- 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs index 33c7afd9e2e94..3d781c9591977 100644 --- a/library/core/src/slice/index.rs +++ b/library/core/src/slice/index.rs @@ -498,7 +498,7 @@ unsafe impl SliceIndex<[T]> for ops::RangeToInclusive { /// /// use std::slice; /// -/// slice::range(2..1, ..3); +/// let _ = slice::range(2..1, ..3); /// ``` /// /// ```should_panic @@ -506,7 +506,7 @@ unsafe impl SliceIndex<[T]> for ops::RangeToInclusive { /// /// use std::slice; /// -/// slice::range(1..4, ..3); +/// let _ = slice::range(1..4, ..3); /// ``` /// /// ```should_panic @@ -514,7 +514,7 @@ unsafe impl SliceIndex<[T]> for ops::RangeToInclusive { /// /// use std::slice; /// -/// slice::range(1..=usize::MAX, ..3); +/// let _ = slice::range(1..=usize::MAX, ..3); /// ``` /// /// [`Index::index`]: ops::Index::index diff --git a/src/test/ui/iterators/into-iter-on-arrays-lint.fixed b/src/test/ui/iterators/into-iter-on-arrays-lint.fixed index 0055758a6a442..6e02a7024b949 100644 --- a/src/test/ui/iterators/into-iter-on-arrays-lint.fixed +++ b/src/test/ui/iterators/into-iter-on-arrays-lint.fixed @@ -2,6 +2,7 @@ // run-rustfix // rustfix-only-machine-applicable +#[allow(unused_must_use)] fn main() { let small = [1, 2]; let big = [0u8; 33]; diff --git a/src/test/ui/iterators/into-iter-on-arrays-lint.rs b/src/test/ui/iterators/into-iter-on-arrays-lint.rs index 01857c78a730c..582d5cadd0658 100644 --- a/src/test/ui/iterators/into-iter-on-arrays-lint.rs +++ b/src/test/ui/iterators/into-iter-on-arrays-lint.rs @@ -2,6 +2,7 @@ // run-rustfix // rustfix-only-machine-applicable +#[allow(unused_must_use)] fn main() { let small = [1, 2]; let big = [0u8; 33]; diff --git a/src/test/ui/iterators/into-iter-on-arrays-lint.stderr b/src/test/ui/iterators/into-iter-on-arrays-lint.stderr index 634728096ed69..e32d35d8638d7 100644 --- a/src/test/ui/iterators/into-iter-on-arrays-lint.stderr +++ b/src/test/ui/iterators/into-iter-on-arrays-lint.stderr @@ -1,5 +1,5 @@ warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021 - --> $DIR/into-iter-on-arrays-lint.rs:10:11 + --> $DIR/into-iter-on-arrays-lint.rs:11:11 | LL | small.into_iter(); | ^^^^^^^^^ @@ -17,7 +17,7 @@ LL | IntoIterator::into_iter(small); | ++++++++++++++++++++++++ ~ warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021 - --> $DIR/into-iter-on-arrays-lint.rs:13:12 + --> $DIR/into-iter-on-arrays-lint.rs:14:12 | LL | [1, 2].into_iter(); | ^^^^^^^^^ @@ -34,7 +34,7 @@ LL | IntoIterator::into_iter([1, 2]); | ++++++++++++++++++++++++ ~ warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021 - --> $DIR/into-iter-on-arrays-lint.rs:16:9 + --> $DIR/into-iter-on-arrays-lint.rs:17:9 | LL | big.into_iter(); | ^^^^^^^^^ @@ -51,7 +51,7 @@ LL | IntoIterator::into_iter(big); | ++++++++++++++++++++++++ ~ warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021 - --> $DIR/into-iter-on-arrays-lint.rs:19:15 + --> $DIR/into-iter-on-arrays-lint.rs:20:15 | LL | [0u8; 33].into_iter(); | ^^^^^^^^^ @@ -68,7 +68,7 @@ LL | IntoIterator::into_iter([0u8; 33]); | ++++++++++++++++++++++++ ~ warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021 - --> $DIR/into-iter-on-arrays-lint.rs:23:21 + --> $DIR/into-iter-on-arrays-lint.rs:24:21 | LL | Box::new(small).into_iter(); | ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter` @@ -77,7 +77,7 @@ LL | Box::new(small).into_iter(); = note: for more information, see warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021 - --> $DIR/into-iter-on-arrays-lint.rs:26:22 + --> $DIR/into-iter-on-arrays-lint.rs:27:22 | LL | Box::new([1, 2]).into_iter(); | ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter` @@ -86,7 +86,7 @@ LL | Box::new([1, 2]).into_iter(); = note: for more information, see warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021 - --> $DIR/into-iter-on-arrays-lint.rs:29:19 + --> $DIR/into-iter-on-arrays-lint.rs:30:19 | LL | Box::new(big).into_iter(); | ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter` @@ -95,7 +95,7 @@ LL | Box::new(big).into_iter(); = note: for more information, see warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021 - --> $DIR/into-iter-on-arrays-lint.rs:32:25 + --> $DIR/into-iter-on-arrays-lint.rs:33:25 | LL | Box::new([0u8; 33]).into_iter(); | ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter` @@ -104,7 +104,7 @@ LL | Box::new([0u8; 33]).into_iter(); = note: for more information, see warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021 - --> $DIR/into-iter-on-arrays-lint.rs:36:31 + --> $DIR/into-iter-on-arrays-lint.rs:37:31 | LL | Box::new(Box::new(small)).into_iter(); | ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter` @@ -113,7 +113,7 @@ LL | Box::new(Box::new(small)).into_iter(); = note: for more information, see warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021 - --> $DIR/into-iter-on-arrays-lint.rs:39:32 + --> $DIR/into-iter-on-arrays-lint.rs:40:32 | LL | Box::new(Box::new([1, 2])).into_iter(); | ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter` @@ -122,7 +122,7 @@ LL | Box::new(Box::new([1, 2])).into_iter(); = note: for more information, see warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021 - --> $DIR/into-iter-on-arrays-lint.rs:42:29 + --> $DIR/into-iter-on-arrays-lint.rs:43:29 | LL | Box::new(Box::new(big)).into_iter(); | ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter` @@ -131,7 +131,7 @@ LL | Box::new(Box::new(big)).into_iter(); = note: for more information, see warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021 - --> $DIR/into-iter-on-arrays-lint.rs:45:35 + --> $DIR/into-iter-on-arrays-lint.rs:46:35 | LL | Box::new(Box::new([0u8; 33])).into_iter(); | ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter` From b83a48d62a2db912d399a2485b146ffb20bd1667 Mon Sep 17 00:00:00 2001 From: Jon Gjengset Date: Tue, 1 Mar 2022 09:45:23 -0800 Subject: [PATCH 03/11] Bump autocfg to 1.1.0 autocfg 1.1.0 makes it so that rustflags from the build are correctly passed to the compiler probes, which in turn means those probes more accurately reflect the outer build conditions. This is particularly important if rustflags includes _required_ `-Clink-arg=` flags without which builds will fail, as older versions of `autocfg` will then fail the probe and erroneously report the probed feature as unavailable. See also https://github.com/rust-lang/rust/issues/94007#issuecomment-1040668261 --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f0c6e371c38be..d8b2a4468a5c5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -161,9 +161,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "bitflags" From 2d854f9c340df887e30896f49270ae81feb3e227 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Wed, 2 Mar 2022 15:22:32 +0100 Subject: [PATCH 04/11] Remove num_cpus dependency from bootstrap, build-manifest and rustc_session --- Cargo.lock | 3 --- compiler/rustc_session/Cargo.toml | 1 - compiler/rustc_session/src/options.rs | 2 +- src/bootstrap/Cargo.toml | 1 - src/bootstrap/config.rs | 2 +- src/bootstrap/flags.rs | 2 +- src/bootstrap/lib.rs | 4 +++- src/tools/build-manifest/Cargo.toml | 1 - src/tools/build-manifest/src/main.rs | 2 +- 9 files changed, 7 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f0c6e371c38be..716f4d7501467 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -221,7 +221,6 @@ dependencies = [ "getopts", "ignore", "libc", - "num_cpus", "once_cell", "opener", "pretty_assertions", @@ -249,7 +248,6 @@ dependencies = [ "anyhow", "flate2", "hex 0.4.2", - "num_cpus", "rayon", "serde", "serde_json", @@ -4241,7 +4239,6 @@ name = "rustc_session" version = "0.0.0" dependencies = [ "getopts", - "num_cpus", "rustc_ast", "rustc_data_structures", "rustc_errors", diff --git a/compiler/rustc_session/Cargo.toml b/compiler/rustc_session/Cargo.toml index 37cfc4a0dc3c2..6b1eaa4d399d9 100644 --- a/compiler/rustc_session/Cargo.toml +++ b/compiler/rustc_session/Cargo.toml @@ -15,6 +15,5 @@ rustc_serialize = { path = "../rustc_serialize" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_span = { path = "../rustc_span" } rustc_fs_util = { path = "../rustc_fs_util" } -num_cpus = "1.0" rustc_ast = { path = "../rustc_ast" } rustc_lint_defs = { path = "../rustc_lint_defs" } diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index c2b13346cd6c9..43123d30ad5c6 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -551,7 +551,7 @@ mod parse { crate fn parse_threads(slot: &mut usize, v: Option<&str>) -> bool { match v.and_then(|s| s.parse().ok()) { Some(0) => { - *slot = ::num_cpus::get(); + *slot = std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get); true } Some(i) => { diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index 592a137e379de..02efc08cc791f 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -37,7 +37,6 @@ test = false build_helper = { path = "../build_helper" } cmake = "0.1.38" filetime = "0.2" -num_cpus = "1.0" getopts = "0.2.19" cc = "1.0.69" libc = "0.2" diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index d6f77fe6cd6d0..ce76ccd57551d 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -1187,7 +1187,7 @@ fn set(field: &mut T, val: Option) { fn threads_from_config(v: u32) -> u32 { match v { - 0 => num_cpus::get() as u32, + 0 => std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get) as u32, n => n, } } diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index 9180c5f03af68..74528f2752f5f 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -208,7 +208,7 @@ To learn more about a subcommand, run `./x.py -h`", let j_msg = format!( "number of jobs to run in parallel; \ defaults to {} (this host's logical CPU count)", - num_cpus::get() + std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get) ); opts.optopt("j", "jobs", &j_msg, "JOBS"); opts.optflag("h", "help", "print this help message"); diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 86339c8d7f88d..6a58de40181c2 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -917,7 +917,9 @@ impl Build { /// Returns the number of parallel jobs that have been configured for this /// build. fn jobs(&self) -> u32 { - self.config.jobs.unwrap_or_else(|| num_cpus::get() as u32) + self.config.jobs.unwrap_or_else(|| { + std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get) as u32 + }) } fn debuginfo_map_to(&self, which: GitRepo) -> Option { diff --git a/src/tools/build-manifest/Cargo.toml b/src/tools/build-manifest/Cargo.toml index c022d3aa0acd7..c437bde5ae69a 100644 --- a/src/tools/build-manifest/Cargo.toml +++ b/src/tools/build-manifest/Cargo.toml @@ -13,4 +13,3 @@ tar = "0.4.29" sha2 = "0.10.1" rayon = "1.5.1" hex = "0.4.2" -num_cpus = "1.13.0" diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 8a62146abfc4e..378efeb644375 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -208,7 +208,7 @@ fn main() { let num_threads = if let Some(num) = env::var_os("BUILD_MANIFEST_NUM_THREADS") { num.to_str().unwrap().parse().expect("invalid number for BUILD_MANIFEST_NUM_THREADS") } else { - num_cpus::get() + std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get) }; rayon::ThreadPoolBuilder::new() .num_threads(num_threads) From dadf2adbe9bbb528d8d143405014c08341d87187 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Thu, 3 Mar 2022 11:19:50 +0100 Subject: [PATCH 05/11] Rename JoinHandle::is_running to is_finished and update docs. Co-authored-by: Josh Triplett --- library/std/src/thread/mod.rs | 13 +++++++++---- library/std/src/thread/scoped.rs | 13 +++++++++---- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index beb606099341e..712df02de7569 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -1443,13 +1443,18 @@ impl JoinHandle { self.0.join() } - /// Checks if the associated thread is still running its main function. + /// Checks if the associated thread has finished running its main function. /// - /// This might return `false` for a brief moment after the thread's main + /// This might return `true` for a brief moment after the thread's main /// function has returned, but before the thread itself has stopped running. + /// However, once this returns `true`, [`join`][Self::join] can be expected + /// to return quickly, without blocking for any significant amount of time. + /// + /// This function does not block. To block while waiting on the thread to finish, + /// use [`join`][Self::join]. #[unstable(feature = "thread_is_running", issue = "90470")] - pub fn is_running(&self) -> bool { - Arc::strong_count(&self.0.packet) > 1 + pub fn is_finished(&self) -> bool { + Arc::strong_count(&self.0.packet) == 1 } } diff --git a/library/std/src/thread/scoped.rs b/library/std/src/thread/scoped.rs index 9dd7c15fc5922..9b2cc4cbc6e43 100644 --- a/library/std/src/thread/scoped.rs +++ b/library/std/src/thread/scoped.rs @@ -289,13 +289,18 @@ impl<'scope, T> ScopedJoinHandle<'scope, T> { self.0.join() } - /// Checks if the associated thread is still running its main function. + /// Checks if the associated thread has finished running its main function. /// - /// This might return `false` for a brief moment after the thread's main + /// This might return `true` for a brief moment after the thread's main /// function has returned, but before the thread itself has stopped running. + /// However, once this returns `true`, [`join`][Self::join] can be expected + /// to return quickly, without blocking for any significant amount of time. + /// + /// This function does not block. To block while waiting on the thread to finish, + /// use [`join`][Self::join]. #[unstable(feature = "thread_is_running", issue = "90470")] - pub fn is_running(&self) -> bool { - Arc::strong_count(&self.0.packet) > 1 + pub fn is_finished(&self) -> bool { + Arc::strong_count(&self.0.packet) == 1 } } From c021ac35fa68d1d110c07ccf970a49e1f3a89607 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Thu, 3 Mar 2022 11:24:20 +0100 Subject: [PATCH 06/11] Update test. --- library/std/src/thread/tests.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/std/src/thread/tests.rs b/library/std/src/thread/tests.rs index 4f2c81731a335..3323ba36bf310 100644 --- a/library/std/src/thread/tests.rs +++ b/library/std/src/thread/tests.rs @@ -52,7 +52,7 @@ fn test_run_basic() { } #[test] -fn test_is_running() { +fn test_is_finished() { let b = Arc::new(Barrier::new(2)); let t = thread::spawn({ let b = b.clone(); @@ -63,14 +63,14 @@ fn test_is_running() { }); // Thread is definitely running here, since it's still waiting for the barrier. - assert_eq!(t.is_running(), true); + assert_eq!(t.is_finished(), false); // Unblock the barrier. b.wait(); - // Now check that t.is_running() becomes false within a reasonable time. + // Now check that t.is_finished() becomes true within a reasonable time. let start = Instant::now(); - while t.is_running() { + while !t.is_finished() { assert!(start.elapsed() < Duration::from_secs(2)); thread::sleep(Duration::from_millis(15)); } From af86b55735bac498756cddd837c3ebec68811122 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Thu, 3 Mar 2022 11:24:26 +0100 Subject: [PATCH 07/11] Remove unnecessary #![feature]s from doctest. --- library/std/src/thread/scoped.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/library/std/src/thread/scoped.rs b/library/std/src/thread/scoped.rs index 9b2cc4cbc6e43..ea9623be63bc7 100644 --- a/library/std/src/thread/scoped.rs +++ b/library/std/src/thread/scoped.rs @@ -240,7 +240,6 @@ impl<'scope, T> ScopedJoinHandle<'scope, T> { /// /// ``` /// #![feature(scoped_threads)] - /// #![feature(thread_is_running)] /// /// use std::thread; /// @@ -274,7 +273,6 @@ impl<'scope, T> ScopedJoinHandle<'scope, T> { /// /// ``` /// #![feature(scoped_threads)] - /// #![feature(thread_is_running)] /// /// use std::thread; /// From 42cb2ea296ca9ce4c2ec229bb0bb78cca13138dd Mon Sep 17 00:00:00 2001 From: JmPotato Date: Thu, 3 Mar 2022 14:24:47 +0800 Subject: [PATCH 08/11] Clean up the std library's #![feature]s Signed-off-by: JmPotato --- library/std/src/lib.rs | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 10fec8e115245..4df5f2a8df4a5 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -212,7 +212,6 @@ #![needs_panic_runtime] // std may use features in a platform-specific way #![allow(unused_features)] -#![feature(rustc_allow_const_fn_unstable)] #![cfg_attr(test, feature(internal_output_capture, print_internals, update_panic_count))] #![cfg_attr( all(target_vendor = "fortanix", target_env = "sgx"), @@ -222,22 +221,16 @@ // std is implemented with unstable features, many of which are internal // compiler details that will never be stable // NB: the following list is sorted to minimize merge conflicts. -#![feature(absolute_path)] #![feature(alloc_error_handler)] #![feature(alloc_layout_extra)] #![feature(allocator_api)] #![feature(allocator_internals)] #![feature(allow_internal_unsafe)] #![feature(allow_internal_unstable)] -#![feature(arbitrary_self_types)] #![feature(array_error_internals)] #![feature(assert_matches)] -#![feature(associated_type_bounds)] #![feature(async_iterator)] -#![feature(atomic_mut_ptr)] -#![feature(auto_traits)] #![feature(bench_black_box)] -#![feature(bool_to_option)] #![feature(box_syntax)] #![feature(c_unwind)] #![feature(c_variadic)] @@ -248,7 +241,6 @@ #![feature(char_internals)] #![feature(concat_bytes)] #![feature(concat_idents)] -#![feature(const_fn_floating_point_arithmetic)] #![feature(const_fn_fn_ptr_basics)] #![feature(const_fn_trait_bound)] #![feature(const_format_args)] @@ -257,10 +249,8 @@ #![feature(const_ipv4)] #![feature(const_ipv6)] #![feature(const_option)] -#![feature(const_mut_refs)] #![feature(const_socketaddr)] #![feature(const_trait_impl)] -#![feature(container_error_extra)] #![feature(c_size_t)] #![feature(core_ffi_c)] #![feature(core_intrinsics)] @@ -279,24 +269,17 @@ #![feature(exact_size_is_empty)] #![feature(exhaustive_patterns)] #![feature(extend_one)] -#![feature(fn_traits)] #![feature(float_minimum_maximum)] #![feature(format_args_nl)] -#![feature(gen_future)] -#![feature(generator_trait)] #![feature(get_mut_unchecked)] #![feature(hashmap_internals)] #![feature(int_error_internals)] -#![feature(integer_atomics)] -#![feature(int_log)] -#![feature(into_future)] #![feature(intra_doc_pointers)] #![feature(lang_items)] #![feature(linkage)] #![feature(log_syntax)] #![feature(map_try_insert)] #![feature(maybe_uninit_slice)] -#![feature(maybe_uninit_uninit_array)] #![feature(maybe_uninit_write_slice)] #![feature(min_specialization)] #![feature(mixed_integer_ops)] @@ -316,19 +299,14 @@ #![feature(portable_simd)] #![feature(prelude_import)] #![feature(ptr_as_uninit)] -#![feature(ptr_internals)] #![feature(raw_os_nonzero)] #![feature(rustc_attrs)] -#![feature(rustc_private)] #![feature(saturating_int_impl)] -#![feature(slice_concat_ext)] #![feature(slice_internals)] #![feature(slice_ptr_get)] -#![feature(slice_ptr_len)] #![feature(staged_api)] #![feature(std_internals)] #![feature(stdsimd)] -#![feature(stmt_expr_attributes)] #![feature(str_internals)] #![feature(test)] #![feature(thread_local)] @@ -338,8 +316,6 @@ #![feature(trace_macros)] #![feature(try_blocks)] #![feature(try_reserve_kind)] -#![feature(unboxed_closures)] -#![feature(unwrap_infallible)] #![feature(vec_into_raw_parts)] // NB: the above list is sorted to minimize merge conflicts. #![default_lib_allocator] From 004f2ed219378235c24a5d6bdb34337200e6eeed Mon Sep 17 00:00:00 2001 From: Esteban Kuber Date: Fri, 4 Mar 2022 02:03:55 +0000 Subject: [PATCH 09/11] Do not recover from `Ty?` in macro parsing Follow up to #92746. Address #94510. --- .../rustc_parse/src/parser/diagnostics.rs | 6 ++-- .../rustc_parse/src/parser/nonterminal.rs | 2 +- compiler/rustc_parse/src/parser/ty.rs | 34 +++++++++++++------ .../parser/trailing-question-in-macro-type.rs | 14 ++++++++ .../trailing-question-in-macro-type.stderr | 9 +++++ 5 files changed, 50 insertions(+), 15 deletions(-) create mode 100644 src/test/ui/parser/trailing-question-in-macro-type.rs create mode 100644 src/test/ui/parser/trailing-question-in-macro-type.stderr diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index c7aa9ffc7937d..40daf4eb28fc1 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -1,5 +1,5 @@ use super::pat::Expected; -use super::ty::{AllowPlus, IsAsCast}; +use super::ty::{AllowPlus, RecoverQuestionMark}; use super::{ BlockMode, CommaRecoveryMode, Parser, PathStyle, RecoverColon, RecoverComma, Restrictions, SemiColonMode, SeqSep, TokenExpectType, TokenType, @@ -1049,9 +1049,9 @@ impl<'a> Parser<'a> { pub(super) fn maybe_recover_from_question_mark( &mut self, ty: P, - is_as_cast: IsAsCast, + recover_question_mark: RecoverQuestionMark, ) -> P { - if let IsAsCast::Yes = is_as_cast { + if let RecoverQuestionMark::No = recover_question_mark { return ty; } if self.token == token::Question { diff --git a/compiler/rustc_parse/src/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs index 83e0a4997ad85..40902fa183313 100644 --- a/compiler/rustc_parse/src/parser/nonterminal.rs +++ b/compiler/rustc_parse/src/parser/nonterminal.rs @@ -140,7 +140,7 @@ impl<'a> Parser<'a> { } NonterminalKind::Ty => { - token::NtTy(self.collect_tokens_no_attrs(|this| this.parse_ty())?) + token::NtTy(self.collect_tokens_no_attrs(|this| this.parse_no_question_mark_recover())?) } // this could be handled like a token, since it is one NonterminalKind::Ident diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 0b01f9e927f33..436c5bd4fcac2 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -44,7 +44,7 @@ pub(super) enum RecoverQPath { No, } -pub(super) enum IsAsCast { +pub(super) enum RecoverQuestionMark { Yes, No, } @@ -105,7 +105,7 @@ impl<'a> Parser<'a> { RecoverQPath::Yes, RecoverReturnSign::Yes, None, - IsAsCast::No, + RecoverQuestionMark::Yes, ) } @@ -119,7 +119,7 @@ impl<'a> Parser<'a> { RecoverQPath::Yes, RecoverReturnSign::Yes, Some(ty_params), - IsAsCast::No, + RecoverQuestionMark::Yes, ) } @@ -133,7 +133,7 @@ impl<'a> Parser<'a> { RecoverQPath::Yes, RecoverReturnSign::Yes, None, - IsAsCast::No, + RecoverQuestionMark::Yes, ) } @@ -150,7 +150,7 @@ impl<'a> Parser<'a> { RecoverQPath::Yes, RecoverReturnSign::Yes, None, - IsAsCast::No, + RecoverQuestionMark::Yes, ) } @@ -163,9 +163,21 @@ impl<'a> Parser<'a> { RecoverQPath::Yes, RecoverReturnSign::Yes, None, - IsAsCast::Yes, + RecoverQuestionMark::No, ) } + + pub(super) fn parse_no_question_mark_recover(&mut self) -> PResult<'a, P> { + self.parse_ty_common( + AllowPlus::Yes, + AllowCVariadic::No, + RecoverQPath::Yes, + RecoverReturnSign::Yes, + None, + RecoverQuestionMark::No, + ) + } + /// Parse a type without recovering `:` as `->` to avoid breaking code such as `where fn() : for<'a>` pub(super) fn parse_ty_for_where_clause(&mut self) -> PResult<'a, P> { self.parse_ty_common( @@ -174,7 +186,7 @@ impl<'a> Parser<'a> { RecoverQPath::Yes, RecoverReturnSign::OnlyFatArrow, None, - IsAsCast::No, + RecoverQuestionMark::Yes, ) } @@ -193,7 +205,7 @@ impl<'a> Parser<'a> { recover_qpath, recover_return_sign, None, - IsAsCast::No, + RecoverQuestionMark::Yes, )?; FnRetTy::Ty(ty) } else if recover_return_sign.can_recover(&self.token.kind) { @@ -214,7 +226,7 @@ impl<'a> Parser<'a> { recover_qpath, recover_return_sign, None, - IsAsCast::No, + RecoverQuestionMark::Yes, )?; FnRetTy::Ty(ty) } else { @@ -229,7 +241,7 @@ impl<'a> Parser<'a> { recover_qpath: RecoverQPath, recover_return_sign: RecoverReturnSign, ty_generics: Option<&Generics>, - is_as_cast: IsAsCast, + recover_question_mark: RecoverQuestionMark, ) -> PResult<'a, P> { let allow_qpath_recovery = recover_qpath == RecoverQPath::Yes; maybe_recover_from_interpolated_ty_qpath!(self, allow_qpath_recovery); @@ -305,7 +317,7 @@ impl<'a> Parser<'a> { // Try to recover from use of `+` with incorrect priority. self.maybe_report_ambiguous_plus(allow_plus, impl_dyn_multi, &ty); self.maybe_recover_from_bad_type_plus(allow_plus, &ty)?; - let ty = self.maybe_recover_from_question_mark(ty, is_as_cast); + let ty = self.maybe_recover_from_question_mark(ty, recover_question_mark); self.maybe_recover_from_bad_qpath(ty, allow_qpath_recovery) } diff --git a/src/test/ui/parser/trailing-question-in-macro-type.rs b/src/test/ui/parser/trailing-question-in-macro-type.rs new file mode 100644 index 0000000000000..e2a681ddd1115 --- /dev/null +++ b/src/test/ui/parser/trailing-question-in-macro-type.rs @@ -0,0 +1,14 @@ +macro_rules! fn_expr { + ($return_type:ty : $body:expr) => { + (|| -> $return_type { $body })() + }; + ($body:expr) => { + (|| $body)() + }; +} + + +fn main() { + fn_expr!{ o?.when(|&i| i > 0)?.when(|&i| i%2 == 0) }; + //~^ ERROR cannot find value `o` in this scope +} diff --git a/src/test/ui/parser/trailing-question-in-macro-type.stderr b/src/test/ui/parser/trailing-question-in-macro-type.stderr new file mode 100644 index 0000000000000..c096ae04fbbb6 --- /dev/null +++ b/src/test/ui/parser/trailing-question-in-macro-type.stderr @@ -0,0 +1,9 @@ +error[E0425]: cannot find value `o` in this scope + --> $DIR/trailing-question-in-macro-type.rs:12:15 + | +LL | fn_expr!{ o?.when(|&i| i > 0)?.when(|&i| i%2 == 0) }; + | ^ not found in this scope + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0425`. From 8b85e7cf2b0566b3754121c151a208d57bda016d Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Thu, 24 Feb 2022 13:30:50 +0100 Subject: [PATCH 10/11] Remove build_helper The majority of the code is only used by either rustbuild or rustc_llvm's build script. Rust_build is compiled once for rustbuild and once for every stage. This means that the majority of the code in this crate is needlessly compiled multiple times. By moving only the code actually used by the respective crates to rustbuild and rustc_llvm's build script, this needless duplicate compilation is avoided. --- Cargo.lock | 6 -- compiler/rustc_llvm/Cargo.toml | 1 - compiler/rustc_llvm/build.rs | 71 +++++++++++++++++-- src/bootstrap/Cargo.toml | 1 - .../lib.rs => bootstrap/build_helper.rs} | 48 +------------ src/bootstrap/builder.rs | 3 +- src/bootstrap/cc_detect.rs | 3 +- src/bootstrap/channel.rs | 3 +- src/bootstrap/clean.rs | 3 +- src/bootstrap/compile.rs | 2 +- src/bootstrap/config.rs | 2 +- src/bootstrap/dist.rs | 3 +- src/bootstrap/doc.rs | 5 +- src/bootstrap/flags.rs | 2 +- src/bootstrap/format.rs | 2 +- src/bootstrap/install.rs | 2 +- src/bootstrap/lib.rs | 3 +- src/bootstrap/metadata.rs | 2 +- src/bootstrap/native.rs | 5 +- src/bootstrap/run.rs | 2 +- src/bootstrap/sanity.rs | 3 +- src/bootstrap/tarball.rs | 3 +- src/bootstrap/test.rs | 3 +- src/bootstrap/tool.rs | 3 +- src/bootstrap/toolstate.rs | 2 +- src/bootstrap/util.rs | 3 +- src/build_helper/Cargo.toml | 7 -- 27 files changed, 92 insertions(+), 101 deletions(-) rename src/{build_helper/lib.rs => bootstrap/build_helper.rs} (67%) delete mode 100644 src/build_helper/Cargo.toml diff --git a/Cargo.lock b/Cargo.lock index 8ca6f26e326d1..6ea78cbcde7df 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -214,7 +214,6 @@ dependencies = [ name = "bootstrap" version = "0.0.0" dependencies = [ - "build_helper", "cc", "cmake", "filetime", @@ -258,10 +257,6 @@ dependencies = [ "toml", ] -[[package]] -name = "build_helper" -version = "0.1.0" - [[package]] name = "bump-stage0" version = "0.1.0" @@ -3893,7 +3888,6 @@ dependencies = [ name = "rustc_llvm" version = "0.0.0" dependencies = [ - "build_helper", "cc", "libc", ] diff --git a/compiler/rustc_llvm/Cargo.toml b/compiler/rustc_llvm/Cargo.toml index d8dfcc84e68da..34556df3c6d79 100644 --- a/compiler/rustc_llvm/Cargo.toml +++ b/compiler/rustc_llvm/Cargo.toml @@ -11,5 +11,4 @@ emscripten = [] libc = "0.2.73" [build-dependencies] -build_helper = { path = "../../src/build_helper" } cc = "1.0.69" diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs index 3b6808d693f21..ac758c15cca78 100644 --- a/compiler/rustc_llvm/build.rs +++ b/compiler/rustc_llvm/build.rs @@ -1,8 +1,8 @@ use std::env; +use std::ffi::{OsStr, OsString}; +use std::fmt::Display; use std::path::{Path, PathBuf}; -use std::process::Command; - -use build_helper::{output, tracked_env_var_os}; +use std::process::{Command, Stdio}; fn detect_llvm_link() -> (&'static str, &'static str) { // Force the link mode we want, preferring static by default, but @@ -14,13 +14,74 @@ fn detect_llvm_link() -> (&'static str, &'static str) { } } +// Because Cargo adds the compiler's dylib path to our library search path, llvm-config may +// break: the dylib path for the compiler, as of this writing, contains a copy of the LLVM +// shared library, which means that when our freshly built llvm-config goes to load it's +// associated LLVM, it actually loads the compiler's LLVM. In particular when building the first +// compiler (i.e., in stage 0) that's a problem, as the compiler's LLVM is likely different from +// the one we want to use. As such, we restore the environment to what bootstrap saw. This isn't +// perfect -- we might actually want to see something from Cargo's added library paths -- but +// for now it works. +fn restore_library_path() { + let key = tracked_env_var_os("REAL_LIBRARY_PATH_VAR").expect("REAL_LIBRARY_PATH_VAR"); + if let Some(env) = tracked_env_var_os("REAL_LIBRARY_PATH") { + env::set_var(&key, &env); + } else { + env::remove_var(&key); + } +} + +/// Reads an environment variable and adds it to dependencies. +/// Supposed to be used for all variables except those set for build scripts by cargo +/// +fn tracked_env_var_os + Display>(key: K) -> Option { + println!("cargo:rerun-if-env-changed={}", key); + env::var_os(key) +} + +fn rerun_if_changed_anything_in_dir(dir: &Path) { + let mut stack = dir + .read_dir() + .unwrap() + .map(|e| e.unwrap()) + .filter(|e| &*e.file_name() != ".git") + .collect::>(); + while let Some(entry) = stack.pop() { + let path = entry.path(); + if entry.file_type().unwrap().is_dir() { + stack.extend(path.read_dir().unwrap().map(|e| e.unwrap())); + } else { + println!("cargo:rerun-if-changed={}", path.display()); + } + } +} + +#[track_caller] +fn output(cmd: &mut Command) -> String { + let output = match cmd.stderr(Stdio::inherit()).output() { + Ok(status) => status, + Err(e) => { + println!("\n\nfailed to execute command: {:?}\nerror: {}\n\n", cmd, e); + std::process::exit(1); + } + }; + if !output.status.success() { + panic!( + "command did not execute successfully: {:?}\n\ + expected success, got: {}", + cmd, output.status + ); + } + String::from_utf8(output.stdout).unwrap() +} + fn main() { if tracked_env_var_os("RUST_CHECK").is_some() { // If we're just running `check`, there's no need for LLVM to be built. return; } - build_helper::restore_library_path(); + restore_library_path(); let target = env::var("TARGET").expect("TARGET was not set"); let llvm_config = @@ -160,7 +221,7 @@ fn main() { cfg.debug(false); } - build_helper::rerun_if_changed_anything_in_dir(Path::new("llvm-wrapper")); + rerun_if_changed_anything_in_dir(Path::new("llvm-wrapper")); cfg.file("llvm-wrapper/PassWrapper.cpp") .file("llvm-wrapper/RustWrapper.cpp") .file("llvm-wrapper/ArchiveWrapper.cpp") diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index 592a137e379de..28b5a5f5374ec 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -34,7 +34,6 @@ path = "bin/llvm-config-wrapper.rs" test = false [dependencies] -build_helper = { path = "../build_helper" } cmake = "0.1.38" filetime = "0.2" num_cpus = "1.0" diff --git a/src/build_helper/lib.rs b/src/bootstrap/build_helper.rs similarity index 67% rename from src/build_helper/lib.rs rename to src/bootstrap/build_helper.rs index 24aded547315e..320099102fc38 100644 --- a/src/build_helper/lib.rs +++ b/src/bootstrap/build_helper.rs @@ -1,9 +1,7 @@ -use std::ffi::{OsStr, OsString}; -use std::fmt::Display; +use std::fs; use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; use std::time::{SystemTime, UNIX_EPOCH}; -use std::{env, fs}; /// A helper macro to `unwrap` a result except also print out details like: /// @@ -13,7 +11,6 @@ use std::{env, fs}; /// /// This is currently used judiciously throughout the build system rather than /// using a `Result` with `try!`, but this may change one day... -#[macro_export] macro_rules! t { ($e:expr) => { match $e { @@ -29,31 +26,7 @@ macro_rules! t { } }; } - -/// Reads an environment variable and adds it to dependencies. -/// Supposed to be used for all variables except those set for build scripts by cargo -/// -pub fn tracked_env_var_os + Display>(key: K) -> Option { - println!("cargo:rerun-if-env-changed={}", key); - env::var_os(key) -} - -// Because Cargo adds the compiler's dylib path to our library search path, llvm-config may -// break: the dylib path for the compiler, as of this writing, contains a copy of the LLVM -// shared library, which means that when our freshly built llvm-config goes to load it's -// associated LLVM, it actually loads the compiler's LLVM. In particular when building the first -// compiler (i.e., in stage 0) that's a problem, as the compiler's LLVM is likely different from -// the one we want to use. As such, we restore the environment to what bootstrap saw. This isn't -// perfect -- we might actually want to see something from Cargo's added library paths -- but -// for now it works. -pub fn restore_library_path() { - let key = tracked_env_var_os("REAL_LIBRARY_PATH_VAR").expect("REAL_LIBRARY_PATH_VAR"); - if let Some(env) = tracked_env_var_os("REAL_LIBRARY_PATH") { - env::set_var(&key, &env); - } else { - env::remove_var(&key); - } -} +pub(crate) use t; pub fn run(cmd: &mut Command, print_cmd_on_fail: bool) { if !try_run(cmd, print_cmd_on_fail) { @@ -130,23 +103,6 @@ pub fn output(cmd: &mut Command) -> String { String::from_utf8(output.stdout).unwrap() } -pub fn rerun_if_changed_anything_in_dir(dir: &Path) { - let mut stack = dir - .read_dir() - .unwrap() - .map(|e| e.unwrap()) - .filter(|e| &*e.file_name() != ".git") - .collect::>(); - while let Some(entry) = stack.pop() { - let path = entry.path(); - if entry.file_type().unwrap().is_dir() { - stack.extend(path.read_dir().unwrap().map(|e| e.unwrap())); - } else { - println!("cargo:rerun-if-changed={}", path.display()); - } - } -} - /// Returns the last-modified time for `path`, or zero if it doesn't exist. pub fn mtime(path: &Path) -> SystemTime { fs::metadata(path).and_then(|f| f.modified()).unwrap_or(UNIX_EPOCH) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 0d387ff1e37c2..9ea1f1950751b 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -11,8 +11,7 @@ use std::path::{Component, Path, PathBuf}; use std::process::Command; use std::time::{Duration, Instant}; -use build_helper::{output, t}; - +use crate::build_helper::{output, t}; use crate::cache::{Cache, Interned, INTERNER}; use crate::check; use crate::compile; diff --git a/src/bootstrap/cc_detect.rs b/src/bootstrap/cc_detect.rs index 8c47f625d732b..9b19e22e0d01e 100644 --- a/src/bootstrap/cc_detect.rs +++ b/src/bootstrap/cc_detect.rs @@ -26,8 +26,7 @@ use std::path::{Path, PathBuf}; use std::process::Command; use std::{env, iter}; -use build_helper::output; - +use crate::build_helper::output; use crate::config::{Target, TargetSelection}; use crate::{Build, CLang, GitRepo}; diff --git a/src/bootstrap/channel.rs b/src/bootstrap/channel.rs index 6478578c3c402..af5c2e1bcd616 100644 --- a/src/bootstrap/channel.rs +++ b/src/bootstrap/channel.rs @@ -8,8 +8,7 @@ use std::path::Path; use std::process::Command; -use build_helper::output; - +use crate::build_helper::output; use crate::Build; pub enum GitInfo { diff --git a/src/bootstrap/clean.rs b/src/bootstrap/clean.rs index 3b73dc1c7df74..249ddf9c731ca 100644 --- a/src/bootstrap/clean.rs +++ b/src/bootstrap/clean.rs @@ -9,8 +9,7 @@ use std::fs; use std::io::{self, ErrorKind}; use std::path::Path; -use build_helper::t; - +use crate::build_helper::t; use crate::Build; pub fn clean(build: &Build, all: bool) { diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 9971778034601..b9a80ce2d11ec 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -16,9 +16,9 @@ use std::path::{Path, PathBuf}; use std::process::{exit, Command, Stdio}; use std::str; -use build_helper::{output, t, up_to_date}; use serde::Deserialize; +use crate::build_helper::{output, t, up_to_date}; use crate::builder::Cargo; use crate::builder::{Builder, Kind, RunConfig, ShouldRun, Step}; use crate::cache::{Interned, INTERNER}; diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index d6f77fe6cd6d0..39fae82128dd5 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -12,13 +12,13 @@ use std::fs; use std::path::{Path, PathBuf}; use std::str::FromStr; +use crate::build_helper::t; use crate::builder::TaskPath; use crate::cache::{Interned, INTERNER}; use crate::channel::GitInfo; pub use crate::flags::Subcommand; use crate::flags::{Color, Flags}; use crate::util::exe; -use build_helper::t; use serde::Deserialize; macro_rules! check_ci_llvm { diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 8693e85e4742f..f6b7478208478 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -14,8 +14,7 @@ use std::fs; use std::path::{Path, PathBuf}; use std::process::Command; -use build_helper::{output, t}; - +use crate::build_helper::{output, t}; use crate::builder::{Builder, Kind, RunConfig, ShouldRun, Step}; use crate::cache::{Interned, INTERNER}; use crate::compile; diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 23b5ddcd47a0e..710bf2493ec24 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -12,15 +12,14 @@ use std::fs; use std::io; use std::path::{Path, PathBuf}; -use crate::Mode; -use build_helper::{t, up_to_date}; - +use crate::build_helper::{t, up_to_date}; use crate::builder::{Builder, Compiler, Kind, RunConfig, ShouldRun, Step}; use crate::cache::{Interned, INTERNER}; use crate::compile; use crate::config::{Config, TargetSelection}; use crate::tool::{self, prepare_tool_cargo, SourceType, Tool}; use crate::util::symlink_dir; +use crate::Mode; macro_rules! submodule_helper { ($path:expr, submodule) => { diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index 9180c5f03af68..b1c245f23164b 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -7,9 +7,9 @@ use std::env; use std::path::PathBuf; use std::process; -use build_helper::t; use getopts::Options; +use crate::build_helper::t; use crate::builder::Builder; use crate::config::{Config, TargetSelection}; use crate::setup::Profile; diff --git a/src/bootstrap/format.rs b/src/bootstrap/format.rs index 530cc829320d1..5774a8ecf0916 100644 --- a/src/bootstrap/format.rs +++ b/src/bootstrap/format.rs @@ -1,7 +1,7 @@ //! Runs rustfmt on the repository. +use crate::build_helper::{output, t}; use crate::Build; -use build_helper::{output, t}; use ignore::WalkBuilder; use std::collections::VecDeque; use std::path::{Path, PathBuf}; diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs index 06acf1a9a0083..5aa634ea3a75f 100644 --- a/src/bootstrap/install.rs +++ b/src/bootstrap/install.rs @@ -8,7 +8,7 @@ use std::fs; use std::path::{Component, PathBuf}; use std::process::Command; -use build_helper::t; +use crate::build_helper::t; use crate::dist::{self, sanitize_sh}; use crate::tarball::GeneratedTarball; diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index abfac2a589793..624f560c1fa98 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -116,13 +116,14 @@ use std::os::unix::fs::symlink as symlink_file; #[cfg(windows)] use std::os::windows::fs::symlink_file; -use build_helper::{mtime, output, run, run_suppressed, t, try_run, try_run_suppressed}; use filetime::FileTime; +use crate::build_helper::{mtime, output, run, run_suppressed, t, try_run, try_run_suppressed}; use crate::builder::Kind; use crate::config::{LlvmLibunwind, TargetSelection}; use crate::util::{exe, libdir, CiEnv}; +mod build_helper; mod builder; mod cache; mod cc_detect; diff --git a/src/bootstrap/metadata.rs b/src/bootstrap/metadata.rs index 65e229697dc87..08e2b22fc1bdc 100644 --- a/src/bootstrap/metadata.rs +++ b/src/bootstrap/metadata.rs @@ -1,9 +1,9 @@ use std::path::PathBuf; use std::process::Command; -use build_helper::output; use serde::Deserialize; +use crate::build_helper::output; use crate::cache::INTERNER; use crate::{Build, Crate}; diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index a751a6e3ece7f..2d7c1ebed6da3 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -16,13 +16,12 @@ use std::io; use std::path::{Path, PathBuf}; use std::process::Command; -use build_helper::{output, t}; - +use crate::build_helper::up_to_date; +use crate::build_helper::{output, t}; use crate::builder::{Builder, RunConfig, ShouldRun, Step}; use crate::config::TargetSelection; use crate::util::{self, exe}; use crate::{CLang, GitRepo}; -use build_helper::up_to_date; pub struct Meta { stamp: HashStamp, diff --git a/src/bootstrap/run.rs b/src/bootstrap/run.rs index 11b393857e74c..a9a784538b59a 100644 --- a/src/bootstrap/run.rs +++ b/src/bootstrap/run.rs @@ -1,7 +1,7 @@ +use crate::build_helper::output; use crate::builder::{Builder, RunConfig, ShouldRun, Step}; use crate::dist::distdir; use crate::tool::Tool; -use build_helper::output; use std::process::Command; #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs index d7db2cef24f2b..36c9ba011c427 100644 --- a/src/bootstrap/sanity.rs +++ b/src/bootstrap/sanity.rs @@ -15,8 +15,7 @@ use std::fs; use std::path::PathBuf; use std::process::Command; -use build_helper::output; - +use crate::build_helper::output; use crate::cache::INTERNER; use crate::config::Target; use crate::Build; diff --git a/src/bootstrap/tarball.rs b/src/bootstrap/tarball.rs index 9ff5c2327e0f7..923522b90be04 100644 --- a/src/bootstrap/tarball.rs +++ b/src/bootstrap/tarball.rs @@ -3,8 +3,7 @@ use std::{ process::Command, }; -use build_helper::t; - +use crate::build_helper::t; use crate::builder::Builder; #[derive(Copy, Clone)] diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 19d98df3ce902..714a2df34a741 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -11,8 +11,7 @@ use std::iter; use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; -use build_helper::{self, output, t}; - +use crate::build_helper::{self, output, t}; use crate::builder::{Builder, Compiler, Kind, RunConfig, ShouldRun, Step}; use crate::cache::Interned; use crate::compile; diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index 1317c3f983975..da2fbe4ef655a 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -4,8 +4,7 @@ use std::fs; use std::path::{Path, PathBuf}; use std::process::{exit, Command}; -use build_helper::t; - +use crate::build_helper::t; use crate::builder::{Builder, Cargo as CargoCommand, RunConfig, ShouldRun, Step}; use crate::channel::GitInfo; use crate::compile; diff --git a/src/bootstrap/toolstate.rs b/src/bootstrap/toolstate.rs index 2394c5e020d2b..bb6525d099bb2 100644 --- a/src/bootstrap/toolstate.rs +++ b/src/bootstrap/toolstate.rs @@ -1,5 +1,5 @@ +use crate::build_helper::t; use crate::builder::{Builder, RunConfig, ShouldRun, Step}; -use build_helper::t; use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::env; diff --git a/src/bootstrap/util.rs b/src/bootstrap/util.rs index 2c78ceb1e5bec..358bbd198106d 100644 --- a/src/bootstrap/util.rs +++ b/src/bootstrap/util.rs @@ -11,8 +11,7 @@ use std::process::Command; use std::str; use std::time::Instant; -use build_helper::t; - +use crate::build_helper::t; use crate::builder::Builder; use crate::config::{Config, TargetSelection}; diff --git a/src/build_helper/Cargo.toml b/src/build_helper/Cargo.toml deleted file mode 100644 index d88df0e08fab3..0000000000000 --- a/src/build_helper/Cargo.toml +++ /dev/null @@ -1,7 +0,0 @@ -[package] -name = "build_helper" -version = "0.1.0" -edition = "2021" - -[lib] -path = "lib.rs" From 3b26b917f0f67aff64d867da70671e41e23704fb Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Thu, 3 Mar 2022 18:15:01 +0100 Subject: [PATCH 11/11] Merge build_helper into util --- src/bootstrap/build_helper.rs | 145 --------------------------------- src/bootstrap/builder.rs | 3 +- src/bootstrap/cc_detect.rs | 2 +- src/bootstrap/channel.rs | 2 +- src/bootstrap/clean.rs | 2 +- src/bootstrap/compile.rs | 3 +- src/bootstrap/config.rs | 3 +- src/bootstrap/dist.rs | 3 +- src/bootstrap/doc.rs | 3 +- src/bootstrap/flags.rs | 2 +- src/bootstrap/format.rs | 2 +- src/bootstrap/install.rs | 2 +- src/bootstrap/lib.rs | 6 +- src/bootstrap/metadata.rs | 2 +- src/bootstrap/native.rs | 4 +- src/bootstrap/run.rs | 2 +- src/bootstrap/sanity.rs | 2 +- src/bootstrap/tarball.rs | 2 +- src/bootstrap/test.rs | 7 +- src/bootstrap/tool.rs | 3 +- src/bootstrap/toolstate.rs | 2 +- src/bootstrap/util.rs | 146 +++++++++++++++++++++++++++++++++- 22 files changed, 166 insertions(+), 182 deletions(-) delete mode 100644 src/bootstrap/build_helper.rs diff --git a/src/bootstrap/build_helper.rs b/src/bootstrap/build_helper.rs deleted file mode 100644 index 320099102fc38..0000000000000 --- a/src/bootstrap/build_helper.rs +++ /dev/null @@ -1,145 +0,0 @@ -use std::fs; -use std::path::{Path, PathBuf}; -use std::process::{Command, Stdio}; -use std::time::{SystemTime, UNIX_EPOCH}; - -/// A helper macro to `unwrap` a result except also print out details like: -/// -/// * The file/line of the panic -/// * The expression that failed -/// * The error itself -/// -/// This is currently used judiciously throughout the build system rather than -/// using a `Result` with `try!`, but this may change one day... -macro_rules! t { - ($e:expr) => { - match $e { - Ok(e) => e, - Err(e) => panic!("{} failed with {}", stringify!($e), e), - } - }; - // it can show extra info in the second parameter - ($e:expr, $extra:expr) => { - match $e { - Ok(e) => e, - Err(e) => panic!("{} failed with {} ({:?})", stringify!($e), e, $extra), - } - }; -} -pub(crate) use t; - -pub fn run(cmd: &mut Command, print_cmd_on_fail: bool) { - if !try_run(cmd, print_cmd_on_fail) { - std::process::exit(1); - } -} - -pub fn try_run(cmd: &mut Command, print_cmd_on_fail: bool) -> bool { - let status = match cmd.status() { - Ok(status) => status, - Err(e) => fail(&format!("failed to execute command: {:?}\nerror: {}", cmd, e)), - }; - if !status.success() && print_cmd_on_fail { - println!( - "\n\ncommand did not execute successfully: {:?}\n\ - expected success, got: {}\n\n", - cmd, status - ); - } - status.success() -} - -pub fn run_suppressed(cmd: &mut Command) { - if !try_run_suppressed(cmd) { - std::process::exit(1); - } -} - -pub fn try_run_suppressed(cmd: &mut Command) -> bool { - let output = match cmd.output() { - Ok(status) => status, - Err(e) => fail(&format!("failed to execute command: {:?}\nerror: {}", cmd, e)), - }; - if !output.status.success() { - println!( - "\n\ncommand did not execute successfully: {:?}\n\ - expected success, got: {}\n\n\ - stdout ----\n{}\n\ - stderr ----\n{}\n\n", - cmd, - output.status, - String::from_utf8_lossy(&output.stdout), - String::from_utf8_lossy(&output.stderr) - ); - } - output.status.success() -} - -pub fn make(host: &str) -> PathBuf { - if host.contains("dragonfly") - || host.contains("freebsd") - || host.contains("netbsd") - || host.contains("openbsd") - { - PathBuf::from("gmake") - } else { - PathBuf::from("make") - } -} - -#[track_caller] -pub fn output(cmd: &mut Command) -> String { - let output = match cmd.stderr(Stdio::inherit()).output() { - Ok(status) => status, - Err(e) => fail(&format!("failed to execute command: {:?}\nerror: {}", cmd, e)), - }; - if !output.status.success() { - panic!( - "command did not execute successfully: {:?}\n\ - expected success, got: {}", - cmd, output.status - ); - } - String::from_utf8(output.stdout).unwrap() -} - -/// Returns the last-modified time for `path`, or zero if it doesn't exist. -pub fn mtime(path: &Path) -> SystemTime { - fs::metadata(path).and_then(|f| f.modified()).unwrap_or(UNIX_EPOCH) -} - -/// Returns `true` if `dst` is up to date given that the file or files in `src` -/// are used to generate it. -/// -/// Uses last-modified time checks to verify this. -pub fn up_to_date(src: &Path, dst: &Path) -> bool { - if !dst.exists() { - return false; - } - let threshold = mtime(dst); - let meta = match fs::metadata(src) { - Ok(meta) => meta, - Err(e) => panic!("source {:?} failed to get metadata: {}", src, e), - }; - if meta.is_dir() { - dir_up_to_date(src, threshold) - } else { - meta.modified().unwrap_or(UNIX_EPOCH) <= threshold - } -} - -fn dir_up_to_date(src: &Path, threshold: SystemTime) -> bool { - t!(fs::read_dir(src)).map(|e| t!(e)).all(|e| { - let meta = t!(e.metadata()); - if meta.is_dir() { - dir_up_to_date(&e.path(), threshold) - } else { - meta.modified().unwrap_or(UNIX_EPOCH) < threshold - } - }) -} - -fn fail(s: &str) -> ! { - println!("\n\n{}\n\n", s); - std::process::exit(1); -} diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 9ea1f1950751b..4c49ed2d6a297 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -11,7 +11,6 @@ use std::path::{Component, Path, PathBuf}; use std::process::Command; use std::time::{Duration, Instant}; -use crate::build_helper::{output, t}; use crate::cache::{Cache, Interned, INTERNER}; use crate::check; use crate::compile; @@ -24,7 +23,7 @@ use crate::native; use crate::run; use crate::test; use crate::tool::{self, SourceType}; -use crate::util::{self, add_dylib_path, add_link_lib_path, exe, libdir}; +use crate::util::{self, add_dylib_path, add_link_lib_path, exe, libdir, output, t}; use crate::{Build, CLang, DocTests, GitRepo, Mode}; pub use crate::Compiler; diff --git a/src/bootstrap/cc_detect.rs b/src/bootstrap/cc_detect.rs index 9b19e22e0d01e..7ce446876118a 100644 --- a/src/bootstrap/cc_detect.rs +++ b/src/bootstrap/cc_detect.rs @@ -26,8 +26,8 @@ use std::path::{Path, PathBuf}; use std::process::Command; use std::{env, iter}; -use crate::build_helper::output; use crate::config::{Target, TargetSelection}; +use crate::util::output; use crate::{Build, CLang, GitRepo}; // The `cc` crate doesn't provide a way to obtain a path to the detected archiver, diff --git a/src/bootstrap/channel.rs b/src/bootstrap/channel.rs index af5c2e1bcd616..1932a0017ee25 100644 --- a/src/bootstrap/channel.rs +++ b/src/bootstrap/channel.rs @@ -8,7 +8,7 @@ use std::path::Path; use std::process::Command; -use crate::build_helper::output; +use crate::util::output; use crate::Build; pub enum GitInfo { diff --git a/src/bootstrap/clean.rs b/src/bootstrap/clean.rs index 249ddf9c731ca..069f3d6acf158 100644 --- a/src/bootstrap/clean.rs +++ b/src/bootstrap/clean.rs @@ -9,7 +9,7 @@ use std::fs; use std::io::{self, ErrorKind}; use std::path::Path; -use crate::build_helper::t; +use crate::util::t; use crate::Build; pub fn clean(build: &Build, all: bool) { diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index b9a80ce2d11ec..9cfd9f92aa7cd 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -18,7 +18,6 @@ use std::str; use serde::Deserialize; -use crate::build_helper::{output, t, up_to_date}; use crate::builder::Cargo; use crate::builder::{Builder, Kind, RunConfig, ShouldRun, Step}; use crate::cache::{Interned, INTERNER}; @@ -26,7 +25,7 @@ use crate::config::{LlvmLibunwind, TargetSelection}; use crate::dist; use crate::native; use crate::tool::SourceType; -use crate::util::{exe, is_debug_info, is_dylib, symlink_dir}; +use crate::util::{exe, is_debug_info, is_dylib, output, symlink_dir, t, up_to_date}; use crate::LLVM_TOOLS; use crate::{CLang, Compiler, DependencyType, GitRepo, Mode}; diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 39fae82128dd5..2053537bcd6a6 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -12,13 +12,12 @@ use std::fs; use std::path::{Path, PathBuf}; use std::str::FromStr; -use crate::build_helper::t; use crate::builder::TaskPath; use crate::cache::{Interned, INTERNER}; use crate::channel::GitInfo; pub use crate::flags::Subcommand; use crate::flags::{Color, Flags}; -use crate::util::exe; +use crate::util::{exe, t}; use serde::Deserialize; macro_rules! check_ci_llvm { diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index f6b7478208478..45c924ce93c55 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -14,14 +14,13 @@ use std::fs; use std::path::{Path, PathBuf}; use std::process::Command; -use crate::build_helper::{output, t}; use crate::builder::{Builder, Kind, RunConfig, ShouldRun, Step}; use crate::cache::{Interned, INTERNER}; use crate::compile; use crate::config::TargetSelection; use crate::tarball::{GeneratedTarball, OverlayKind, Tarball}; use crate::tool::{self, Tool}; -use crate::util::{exe, is_dylib, timeit}; +use crate::util::{exe, is_dylib, output, t, timeit}; use crate::{Compiler, DependencyType, Mode, LLVM_TOOLS}; pub fn pkgname(builder: &Builder<'_>, component: &str) -> String { diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 710bf2493ec24..be55871b56a28 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -12,13 +12,12 @@ use std::fs; use std::io; use std::path::{Path, PathBuf}; -use crate::build_helper::{t, up_to_date}; use crate::builder::{Builder, Compiler, Kind, RunConfig, ShouldRun, Step}; use crate::cache::{Interned, INTERNER}; use crate::compile; use crate::config::{Config, TargetSelection}; use crate::tool::{self, prepare_tool_cargo, SourceType, Tool}; -use crate::util::symlink_dir; +use crate::util::{symlink_dir, t, up_to_date}; use crate::Mode; macro_rules! submodule_helper { diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index b1c245f23164b..f72af579d9ad4 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -9,10 +9,10 @@ use std::process; use getopts::Options; -use crate::build_helper::t; use crate::builder::Builder; use crate::config::{Config, TargetSelection}; use crate::setup::Profile; +use crate::util::t; use crate::{Build, DocTests}; pub enum Color { diff --git a/src/bootstrap/format.rs b/src/bootstrap/format.rs index 5774a8ecf0916..10b846e6db208 100644 --- a/src/bootstrap/format.rs +++ b/src/bootstrap/format.rs @@ -1,6 +1,6 @@ //! Runs rustfmt on the repository. -use crate::build_helper::{output, t}; +use crate::util::{output, t}; use crate::Build; use ignore::WalkBuilder; use std::collections::VecDeque; diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs index 5aa634ea3a75f..27b9196d9868e 100644 --- a/src/bootstrap/install.rs +++ b/src/bootstrap/install.rs @@ -8,7 +8,7 @@ use std::fs; use std::path::{Component, PathBuf}; use std::process::Command; -use crate::build_helper::t; +use crate::util::t; use crate::dist::{self, sanitize_sh}; use crate::tarball::GeneratedTarball; diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 624f560c1fa98..b58439bf71d2a 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -118,12 +118,12 @@ use std::os::windows::fs::symlink_file; use filetime::FileTime; -use crate::build_helper::{mtime, output, run, run_suppressed, t, try_run, try_run_suppressed}; use crate::builder::Kind; use crate::config::{LlvmLibunwind, TargetSelection}; -use crate::util::{exe, libdir, CiEnv}; +use crate::util::{ + exe, libdir, mtime, output, run, run_suppressed, t, try_run, try_run_suppressed, CiEnv, +}; -mod build_helper; mod builder; mod cache; mod cc_detect; diff --git a/src/bootstrap/metadata.rs b/src/bootstrap/metadata.rs index 08e2b22fc1bdc..59dc50be47f06 100644 --- a/src/bootstrap/metadata.rs +++ b/src/bootstrap/metadata.rs @@ -3,8 +3,8 @@ use std::process::Command; use serde::Deserialize; -use crate::build_helper::output; use crate::cache::INTERNER; +use crate::util::output; use crate::{Build, Crate}; #[derive(Deserialize)] diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 2d7c1ebed6da3..d27ad9644b56c 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -16,11 +16,9 @@ use std::io; use std::path::{Path, PathBuf}; use std::process::Command; -use crate::build_helper::up_to_date; -use crate::build_helper::{output, t}; use crate::builder::{Builder, RunConfig, ShouldRun, Step}; use crate::config::TargetSelection; -use crate::util::{self, exe}; +use crate::util::{self, exe, output, t, up_to_date}; use crate::{CLang, GitRepo}; pub struct Meta { diff --git a/src/bootstrap/run.rs b/src/bootstrap/run.rs index a9a784538b59a..25abe7a72fdc8 100644 --- a/src/bootstrap/run.rs +++ b/src/bootstrap/run.rs @@ -1,7 +1,7 @@ -use crate::build_helper::output; use crate::builder::{Builder, RunConfig, ShouldRun, Step}; use crate::dist::distdir; use crate::tool::Tool; +use crate::util::output; use std::process::Command; #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs index 36c9ba011c427..8c2899c1ac01e 100644 --- a/src/bootstrap/sanity.rs +++ b/src/bootstrap/sanity.rs @@ -15,9 +15,9 @@ use std::fs; use std::path::PathBuf; use std::process::Command; -use crate::build_helper::output; use crate::cache::INTERNER; use crate::config::Target; +use crate::util::output; use crate::Build; pub struct Finder { diff --git a/src/bootstrap/tarball.rs b/src/bootstrap/tarball.rs index 923522b90be04..c743c5188e754 100644 --- a/src/bootstrap/tarball.rs +++ b/src/bootstrap/tarball.rs @@ -3,8 +3,8 @@ use std::{ process::Command, }; -use crate::build_helper::t; use crate::builder::Builder; +use crate::util::t; #[derive(Copy, Clone)] pub(crate) enum OverlayKind { diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 714a2df34a741..e4fcb287f1228 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -11,7 +11,6 @@ use std::iter; use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; -use crate::build_helper::{self, output, t}; use crate::builder::{Builder, Compiler, Kind, RunConfig, ShouldRun, Step}; use crate::cache::Interned; use crate::compile; @@ -21,7 +20,7 @@ use crate::flags::Subcommand; use crate::native; use crate::tool::{self, SourceType, Tool}; use crate::toolstate::ToolState; -use crate::util::{self, add_link_lib_path, dylib_path, dylib_path_var}; +use crate::util::{self, add_link_lib_path, dylib_path, dylib_path_var, output, t}; use crate::Crate as CargoCrate; use crate::{envify, CLang, DocTests, GitRepo, Mode}; @@ -2305,9 +2304,7 @@ impl Step for Distcheck { .current_dir(&dir), ); builder.run( - Command::new(build_helper::make(&builder.config.build.triple)) - .arg("check") - .current_dir(&dir), + Command::new(util::make(&builder.config.build.triple)).arg("check").current_dir(&dir), ); // Now make sure that rust-src has all of libstd's dependencies diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index da2fbe4ef655a..2ae4d830721e8 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -4,13 +4,12 @@ use std::fs; use std::path::{Path, PathBuf}; use std::process::{exit, Command}; -use crate::build_helper::t; use crate::builder::{Builder, Cargo as CargoCommand, RunConfig, ShouldRun, Step}; use crate::channel::GitInfo; use crate::compile; use crate::config::TargetSelection; use crate::toolstate::ToolState; -use crate::util::{add_dylib_path, exe}; +use crate::util::{add_dylib_path, exe, t}; use crate::Compiler; use crate::Mode; diff --git a/src/bootstrap/toolstate.rs b/src/bootstrap/toolstate.rs index bb6525d099bb2..cf4725253522d 100644 --- a/src/bootstrap/toolstate.rs +++ b/src/bootstrap/toolstate.rs @@ -1,5 +1,5 @@ -use crate::build_helper::t; use crate::builder::{Builder, RunConfig, ShouldRun, Step}; +use crate::util::t; use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::env; diff --git a/src/bootstrap/util.rs b/src/bootstrap/util.rs index 358bbd198106d..8e770d4d57fa6 100644 --- a/src/bootstrap/util.rs +++ b/src/bootstrap/util.rs @@ -7,14 +7,38 @@ use std::env; use std::fs; use std::io; use std::path::{Path, PathBuf}; -use std::process::Command; +use std::process::{Command, Stdio}; use std::str; -use std::time::Instant; +use std::time::{Instant, SystemTime, UNIX_EPOCH}; -use crate::build_helper::t; use crate::builder::Builder; use crate::config::{Config, TargetSelection}; +/// A helper macro to `unwrap` a result except also print out details like: +/// +/// * The file/line of the panic +/// * The expression that failed +/// * The error itself +/// +/// This is currently used judiciously throughout the build system rather than +/// using a `Result` with `try!`, but this may change one day... +macro_rules! t { + ($e:expr) => { + match $e { + Ok(e) => e, + Err(e) => panic!("{} failed with {}", stringify!($e), e), + } + }; + // it can show extra info in the second parameter + ($e:expr, $extra:expr) => { + match $e { + Ok(e) => e, + Err(e) => panic!("{} failed with {} ({:?})", stringify!($e), e, $extra), + } + }; +} +pub(crate) use t; + /// Given an executable called `name`, return the filename for the /// executable for a particular target. pub fn exe(name: &str, target: TargetSelection) -> String { @@ -300,3 +324,119 @@ pub fn is_valid_test_suite_arg<'a, P: AsRef>( _ => None, } } + +pub fn run(cmd: &mut Command, print_cmd_on_fail: bool) { + if !try_run(cmd, print_cmd_on_fail) { + std::process::exit(1); + } +} + +pub fn try_run(cmd: &mut Command, print_cmd_on_fail: bool) -> bool { + let status = match cmd.status() { + Ok(status) => status, + Err(e) => fail(&format!("failed to execute command: {:?}\nerror: {}", cmd, e)), + }; + if !status.success() && print_cmd_on_fail { + println!( + "\n\ncommand did not execute successfully: {:?}\n\ + expected success, got: {}\n\n", + cmd, status + ); + } + status.success() +} + +pub fn run_suppressed(cmd: &mut Command) { + if !try_run_suppressed(cmd) { + std::process::exit(1); + } +} + +pub fn try_run_suppressed(cmd: &mut Command) -> bool { + let output = match cmd.output() { + Ok(status) => status, + Err(e) => fail(&format!("failed to execute command: {:?}\nerror: {}", cmd, e)), + }; + if !output.status.success() { + println!( + "\n\ncommand did not execute successfully: {:?}\n\ + expected success, got: {}\n\n\ + stdout ----\n{}\n\ + stderr ----\n{}\n\n", + cmd, + output.status, + String::from_utf8_lossy(&output.stdout), + String::from_utf8_lossy(&output.stderr) + ); + } + output.status.success() +} + +pub fn make(host: &str) -> PathBuf { + if host.contains("dragonfly") + || host.contains("freebsd") + || host.contains("netbsd") + || host.contains("openbsd") + { + PathBuf::from("gmake") + } else { + PathBuf::from("make") + } +} + +#[track_caller] +pub fn output(cmd: &mut Command) -> String { + let output = match cmd.stderr(Stdio::inherit()).output() { + Ok(status) => status, + Err(e) => fail(&format!("failed to execute command: {:?}\nerror: {}", cmd, e)), + }; + if !output.status.success() { + panic!( + "command did not execute successfully: {:?}\n\ + expected success, got: {}", + cmd, output.status + ); + } + String::from_utf8(output.stdout).unwrap() +} + +/// Returns the last-modified time for `path`, or zero if it doesn't exist. +pub fn mtime(path: &Path) -> SystemTime { + fs::metadata(path).and_then(|f| f.modified()).unwrap_or(UNIX_EPOCH) +} + +/// Returns `true` if `dst` is up to date given that the file or files in `src` +/// are used to generate it. +/// +/// Uses last-modified time checks to verify this. +pub fn up_to_date(src: &Path, dst: &Path) -> bool { + if !dst.exists() { + return false; + } + let threshold = mtime(dst); + let meta = match fs::metadata(src) { + Ok(meta) => meta, + Err(e) => panic!("source {:?} failed to get metadata: {}", src, e), + }; + if meta.is_dir() { + dir_up_to_date(src, threshold) + } else { + meta.modified().unwrap_or(UNIX_EPOCH) <= threshold + } +} + +fn dir_up_to_date(src: &Path, threshold: SystemTime) -> bool { + t!(fs::read_dir(src)).map(|e| t!(e)).all(|e| { + let meta = t!(e.metadata()); + if meta.is_dir() { + dir_up_to_date(&e.path(), threshold) + } else { + meta.modified().unwrap_or(UNIX_EPOCH) < threshold + } + }) +} + +fn fail(s: &str) -> ! { + println!("\n\n{}\n\n", s); + std::process::exit(1); +}