From 8f9cd3d1e820eb114c32627cc34f3897cda7903e Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Tue, 3 Oct 2023 15:17:52 +0200 Subject: [PATCH 01/50] Rework range splitting api --- .../src/thir/pattern/deconstruct_pat.rs | 202 ++++++++---------- 1 file changed, 90 insertions(+), 112 deletions(-) diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs index 3ee4befa1218..d63190985a31 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs @@ -39,7 +39,7 @@ //! //! Splitting is implemented in the [`Constructor::split`] function. We don't do splitting for //! or-patterns; instead we just try the alternatives one-by-one. For details on splitting -//! wildcards, see [`SplitWildcard`]; for integer ranges, see [`SplitIntRange`]; for slices, see +//! wildcards, see [`SplitWildcard`]; for integer ranges, see [`IntRange::split`]; for slices, see //! [`SplitVarLenSlice`]. use std::cell::Cell; @@ -186,6 +186,93 @@ impl IntRange { (lo == other_hi || hi == other_lo) && !self.is_singleton() && !other.is_singleton() } + /// See `Constructor::is_covered_by` + fn is_covered_by(&self, other: &Self) -> bool { + if self.intersection(other).is_some() { + // Constructor splitting should ensure that all intersections we encounter are actually + // inclusions. + assert!(self.is_subrange(other)); + true + } else { + false + } + } + + /// Partition a range of integers into disjoint subranges. This does constructor splitting for + /// integer ranges as explained at the top of the file. + /// + /// This returns an output that covers `self`. The output is split so that the only + /// intersections between an output range and a column range are inclusions. No output range + /// straddles the boundary of one of the inputs. + /// + /// The following input: + /// ```text + /// |-------------------------| // `self` + /// |------| |----------| |----| + /// |-------| |-------| + /// ``` + /// would be iterated over as follows: + /// ```text + /// ||---|--||-|---|---|---|--| + /// ``` + fn split( + &self, + column_ranges: impl Iterator, + ) -> impl Iterator { + /// Represents a boundary between 2 integers. Because the intervals spanning boundaries must be + /// able to cover every integer, we need to be able to represent 2^128 + 1 such boundaries. + #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] + enum IntBoundary { + JustBefore(u128), + AfterMax, + } + + fn unpack_intrange(range: IntRange) -> [IntBoundary; 2] { + use IntBoundary::*; + let (lo, hi) = range.boundaries(); + let lo = JustBefore(lo); + let hi = match hi.checked_add(1) { + Some(m) => JustBefore(m), + None => AfterMax, + }; + [lo, hi] + } + + // The boundaries of ranges in `column_ranges` intersected with `self`. + let mut boundaries: Vec = column_ranges + .filter_map(|r| self.intersection(&r)) + .map(unpack_intrange) + .flat_map(|[lo, hi]| [lo, hi]) + .collect(); + boundaries.sort_unstable(); + + let [self_start, self_end] = unpack_intrange(self.clone()); + // Gather pairs of adjacent boundaries. + let mut prev_bdy = self_start; + boundaries + .into_iter() + // End with the end of the range. + .chain(once(self_end)) + // List pairs of adjacent boundaries. + .map(move |bdy| { + let ret = (prev_bdy, bdy); + prev_bdy = bdy; + ret + }) + // Skip duplicates. + .filter(|&(prev_bdy, bdy)| prev_bdy != bdy) + // Convert back to ranges. + .map(move |(prev_bdy, bdy)| { + use IntBoundary::*; + let range = match (prev_bdy, bdy) { + (JustBefore(n), JustBefore(m)) if n < m => n..=(m - 1), + (JustBefore(n), AfterMax) => n..=u128::MAX, + _ => unreachable!(), // Ruled out by the sorting and filtering we did + }; + IntRange { range } + }) + } + /// Only used for displaying the range properly. fn to_pat<'tcx>(&self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Pat<'tcx> { let (lo, hi) = self.boundaries(); @@ -254,18 +341,6 @@ impl IntRange { ); } } - - /// See `Constructor::is_covered_by` - fn is_covered_by(&self, other: &Self) -> bool { - if self.intersection(other).is_some() { - // Constructor splitting should ensure that all intersections we encounter are actually - // inclusions. - assert!(self.is_subrange(other)); - true - } else { - false - } - } } /// Note: this is often not what we want: e.g. `false` is converted into the range `0..=0` and @@ -279,101 +354,6 @@ impl fmt::Debug for IntRange { } } -/// Represents a border between 2 integers. Because the intervals spanning borders must be able to -/// cover every integer, we need to be able to represent 2^128 + 1 such borders. -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] -enum IntBorder { - JustBefore(u128), - AfterMax, -} - -/// A range of integers that is partitioned into disjoint subranges. This does constructor -/// splitting for integer ranges as explained at the top of the file. -/// -/// This is fed multiple ranges, and returns an output that covers the input, but is split so that -/// the only intersections between an output range and a seen range are inclusions. No output range -/// straddles the boundary of one of the inputs. -/// -/// The following input: -/// ```text -/// |-------------------------| // `self` -/// |------| |----------| |----| -/// |-------| |-------| -/// ``` -/// would be iterated over as follows: -/// ```text -/// ||---|--||-|---|---|---|--| -/// ``` -#[derive(Debug, Clone)] -struct SplitIntRange { - /// The range we are splitting - range: IntRange, - /// The borders of ranges we have seen. They are all contained within `range`. This is kept - /// sorted. - borders: Vec, -} - -impl SplitIntRange { - fn new(range: IntRange) -> Self { - SplitIntRange { range, borders: Vec::new() } - } - - /// Internal use - fn to_borders(r: IntRange) -> [IntBorder; 2] { - use IntBorder::*; - let (lo, hi) = r.boundaries(); - let lo = JustBefore(lo); - let hi = match hi.checked_add(1) { - Some(m) => JustBefore(m), - None => AfterMax, - }; - [lo, hi] - } - - /// Add ranges relative to which we split. - fn split(&mut self, ranges: impl Iterator) { - let this_range = &self.range; - let included_ranges = ranges.filter_map(|r| this_range.intersection(&r)); - let included_borders = included_ranges.flat_map(|r| { - let borders = Self::to_borders(r); - once(borders[0]).chain(once(borders[1])) - }); - self.borders.extend(included_borders); - self.borders.sort_unstable(); - } - - /// Iterate over the contained ranges. - fn iter(&self) -> impl Iterator + Captures<'_> { - use IntBorder::*; - - let self_range = Self::to_borders(self.range.clone()); - // Start with the start of the range. - let mut prev_border = self_range[0]; - self.borders - .iter() - .copied() - // End with the end of the range. - .chain(once(self_range[1])) - // List pairs of adjacent borders. - .map(move |border| { - let ret = (prev_border, border); - prev_border = border; - ret - }) - // Skip duplicates. - .filter(|(prev_border, border)| prev_border != border) - // Finally, convert to ranges. - .map(move |(prev_border, border)| { - let range = match (prev_border, border) { - (JustBefore(n), JustBefore(m)) if n < m => n..=(m - 1), - (JustBefore(n), AfterMax) => n..=u128::MAX, - _ => unreachable!(), // Ruled out by the sorting and filtering we did - }; - IntRange { range } - }) - } -} - #[derive(Copy, Clone, Debug, PartialEq, Eq)] enum SliceKind { /// Patterns of length `n` (`[x, y]`). @@ -733,10 +713,8 @@ impl<'tcx> Constructor<'tcx> { // Fast-track if the range is trivial. In particular, we don't do the overlapping // ranges check. IntRange(ctor_range) if !ctor_range.is_singleton() => { - let mut split_range = SplitIntRange::new(ctor_range.clone()); - let int_ranges = ctors.filter_map(|ctor| ctor.as_int_range()); - split_range.split(int_ranges.cloned()); - split_range.iter().map(IntRange).collect() + let int_ranges = ctors.filter_map(|ctor| ctor.as_int_range()).cloned(); + ctor_range.split(int_ranges).map(IntRange).collect() } &Slice(Slice { kind: VarLen(self_prefix, self_suffix), array_len }) => { let mut split_self = SplitVarLenSlice::new(self_prefix, self_suffix, array_len); From 590edee3209906b3906f09bad029586b0a15e29f Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Tue, 3 Oct 2023 14:38:40 +0200 Subject: [PATCH 02/50] Rework slice splitting api --- .../src/thir/pattern/deconstruct_pat.rs | 253 +++++++++--------- 1 file changed, 120 insertions(+), 133 deletions(-) diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs index d63190985a31..6755e665bba1 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs @@ -40,7 +40,7 @@ //! Splitting is implemented in the [`Constructor::split`] function. We don't do splitting for //! or-patterns; instead we just try the alternatives one-by-one. For details on splitting //! wildcards, see [`SplitWildcard`]; for integer ranges, see [`IntRange::split`]; for slices, see -//! [`SplitVarLenSlice`]. +//! [`Slice::split`]. use std::cell::Cell; use std::cmp::{self, max, min, Ordering}; @@ -410,141 +410,130 @@ impl Slice { fn is_covered_by(self, other: Self) -> bool { other.kind.covers_length(self.arity()) } -} -/// This computes constructor splitting for variable-length slices, as explained at the top of the -/// file. -/// -/// A slice pattern `[x, .., y]` behaves like the infinite or-pattern `[x, y] | [x, _, y] | [x, _, -/// _, y] | ...`. The corresponding value constructors are fixed-length array constructors above a -/// given minimum length. We obviously can't list this infinitude of constructors. Thankfully, -/// it turns out that for each finite set of slice patterns, all sufficiently large array lengths -/// are equivalent. -/// -/// Let's look at an example, where we are trying to split the last pattern: -/// ``` -/// # fn foo(x: &[bool]) { -/// match x { -/// [true, true, ..] => {} -/// [.., false, false] => {} -/// [..] => {} -/// } -/// # } -/// ``` -/// Here are the results of specialization for the first few lengths: -/// ``` -/// # fn foo(x: &[bool]) { match x { -/// // length 0 -/// [] => {} -/// // length 1 -/// [_] => {} -/// // length 2 -/// [true, true] => {} -/// [false, false] => {} -/// [_, _] => {} -/// // length 3 -/// [true, true, _ ] => {} -/// [_, false, false] => {} -/// [_, _, _ ] => {} -/// // length 4 -/// [true, true, _, _ ] => {} -/// [_, _, false, false] => {} -/// [_, _, _, _ ] => {} -/// // length 5 -/// [true, true, _, _, _ ] => {} -/// [_, _, _, false, false] => {} -/// [_, _, _, _, _ ] => {} -/// # _ => {} -/// # }} -/// ``` -/// -/// If we went above length 5, we would simply be inserting more columns full of wildcards in the -/// middle. This means that the set of witnesses for length `l >= 5` if equivalent to the set for -/// any other `l' >= 5`: simply add or remove wildcards in the middle to convert between them. -/// -/// This applies to any set of slice patterns: there will be a length `L` above which all lengths -/// behave the same. This is exactly what we need for constructor splitting. Therefore a -/// variable-length slice can be split into a variable-length slice of minimal length `L`, and many -/// fixed-length slices of lengths `< L`. -/// -/// For each variable-length pattern `p` with a prefix of length `plₚ` and suffix of length `slₚ`, -/// only the first `plₚ` and the last `slₚ` elements are examined. Therefore, as long as `L` is -/// positive (to avoid concerns about empty types), all elements after the maximum prefix length -/// and before the maximum suffix length are not examined by any variable-length pattern, and -/// therefore can be added/removed without affecting them - creating equivalent patterns from any -/// sufficiently-large length. -/// -/// Of course, if fixed-length patterns exist, we must be sure that our length is large enough to -/// miss them all, so we can pick `L = max(max(FIXED_LEN)+1, max(PREFIX_LEN) + max(SUFFIX_LEN))` -/// -/// `max_slice` below will be made to have arity `L`. -#[derive(Debug)] -struct SplitVarLenSlice { - /// If the type is an array, this is its size. - array_len: Option, - /// The arity of the input slice. - arity: usize, - /// The smallest slice bigger than any slice seen. `max_slice.arity()` is the length `L` - /// described above. - max_slice: SliceKind, -} - -impl SplitVarLenSlice { - fn new(prefix: usize, suffix: usize, array_len: Option) -> Self { - SplitVarLenSlice { array_len, arity: prefix + suffix, max_slice: VarLen(prefix, suffix) } - } - - /// Pass a set of slices relative to which to split this one. - fn split(&mut self, slices: impl Iterator) { - let VarLen(max_prefix_len, max_suffix_len) = &mut self.max_slice else { - // No need to split - return; - }; - // We grow `self.max_slice` to be larger than all slices encountered, as described above. - // For diagnostics, we keep the prefix and suffix lengths separate, but grow them so that - // `L = max_prefix_len + max_suffix_len`. - let mut max_fixed_len = 0; - for slice in slices { - match slice { - FixedLen(len) => { - max_fixed_len = cmp::max(max_fixed_len, len); + /// This computes constructor splitting for variable-length slices, as explained at the top of + /// the file. + /// + /// A slice pattern `[x, .., y]` behaves like the infinite or-pattern `[x, y] | [x, _, y] | [x, + /// _, _, y] | etc`. The corresponding value constructors are fixed-length array constructors of + /// corresponding lengths. We obviously can't list this infinitude of constructors. + /// Thankfully, it turns out that for each finite set of slice patterns, all sufficiently large + /// array lengths are equivalent. + /// + /// Let's look at an example, where we are trying to split the last pattern: + /// ``` + /// # fn foo(x: &[bool]) { + /// match x { + /// [true, true, ..] => {} + /// [.., false, false] => {} + /// [..] => {} // `self` + /// } + /// # } + /// ``` + /// Here are the results of specialization for the first few lengths: + /// ``` + /// # fn foo(x: &[bool]) { match x { + /// // length 0 + /// [] => {} + /// // length 1 + /// [_] => {} + /// // length 2 + /// [true, true] => {} + /// [false, false] => {} + /// [_, _] => {} + /// // length 3 + /// [true, true, _ ] => {} + /// [_, false, false] => {} + /// [_, _, _ ] => {} + /// // length 4 + /// [true, true, _, _ ] => {} + /// [_, _, false, false] => {} + /// [_, _, _, _ ] => {} + /// // length 5 + /// [true, true, _, _, _ ] => {} + /// [_, _, _, false, false] => {} + /// [_, _, _, _, _ ] => {} + /// # _ => {} + /// # }} + /// ``` + /// + /// We see that above length 4, we are simply inserting columns full of wildcards in the middle. + /// This means that specialization and witness computation with slices of length `l >= 4` will + /// give equivalent results independently of `l`. This applies to any set of slice patterns: + /// there will be a length `L` above which all lengths behave the same. This is exactly what we + /// need for constructor splitting. + /// + /// A variable-length slice pattern covers all lengths from its arity up to infinity. As we just + /// saw, we can split this in two: lengths below `L` are treated individually with a + /// fixed-length slice each; lengths above `L` are grouped into a single variable-length slice + /// constructor. + /// + /// For each variable-length slice pattern `p` with a prefix of length `plₚ` and suffix of + /// length `slₚ`, only the first `plₚ` and the last `slₚ` elements are examined. Therefore, as + /// long as `L` is positive (to avoid concerns about empty types), all elements after the + /// maximum prefix length and before the maximum suffix length are not examined by any + /// variable-length pattern, and therefore can be ignored. This gives us a way to compute `L`. + /// + /// Additionally, if fixed-length patterns exist, we must pick an `L` large enough to miss them, + /// so we can pick `L = max(max(FIXED_LEN)+1, max(PREFIX_LEN) + max(SUFFIX_LEN))`. + /// `max_slice` below will be made to have this arity `L`. + /// + /// If `self` is fixed-length, it is returned as-is. + fn split(self, column_slices: impl Iterator) -> impl Iterator { + // Range of lengths below `L`. + let smaller_lengths; + let mut max_slice = self.kind; + match &mut max_slice { + VarLen(max_prefix_len, max_suffix_len) => { + // We grow `max_slice` to be larger than all slices encountered, as described above. + // For diagnostics, we keep the prefix and suffix lengths separate, but grow them so that + // `L = max_prefix_len + max_suffix_len`. + let mut max_fixed_len = 0; + for slice in column_slices { + match slice.kind { + FixedLen(len) => { + max_fixed_len = cmp::max(max_fixed_len, len); + } + VarLen(prefix, suffix) => { + *max_prefix_len = cmp::max(*max_prefix_len, prefix); + *max_suffix_len = cmp::max(*max_suffix_len, suffix); + } + } } - VarLen(prefix, suffix) => { - *max_prefix_len = cmp::max(*max_prefix_len, prefix); - *max_suffix_len = cmp::max(*max_suffix_len, suffix); + // We want `L = max(L, max_fixed_len + 1)`, modulo the fact that we keep prefix and + // suffix separate. + if max_fixed_len + 1 >= *max_prefix_len + *max_suffix_len { + // The subtraction can't overflow thanks to the above check. + // The new `max_prefix_len` is larger than its previous value. + *max_prefix_len = max_fixed_len + 1 - *max_suffix_len; } - } - } - // We want `L = max(L, max_fixed_len + 1)`, modulo the fact that we keep prefix and - // suffix separate. - if max_fixed_len + 1 >= *max_prefix_len + *max_suffix_len { - // The subtraction can't overflow thanks to the above check. - // The new `max_prefix_len` is larger than its previous value. - *max_prefix_len = max_fixed_len + 1 - *max_suffix_len; - } - // We cap the arity of `max_slice` at the array size. - match self.array_len { - Some(len) if self.max_slice.arity() >= len => self.max_slice = FixedLen(len), - _ => {} - } - } + // We cap the arity of `max_slice` at the array size. + match self.array_len { + Some(len) if max_slice.arity() >= len => max_slice = FixedLen(len), + _ => {} + } - /// Iterate over the partition of this slice. - fn iter(&self) -> impl Iterator + Captures<'_> { - let smaller_lengths = match self.array_len { - // The only admissible fixed-length slice is one of the array size. Whether `max_slice` - // is fixed-length or variable-length, it will be the only relevant slice to output - // here. - Some(_) => 0..0, // empty range - // We cover all arities in the range `(self.arity..infinity)`. We split that range into - // two: lengths smaller than `max_slice.arity()` are treated independently as - // fixed-lengths slices, and lengths above are captured by `max_slice`. - None => self.arity..self.max_slice.arity(), + smaller_lengths = match self.array_len { + // The only admissible fixed-length slice is one of the array size. Whether `max_slice` + // is fixed-length or variable-length, it will be the only relevant slice to output + // here. + Some(_) => 0..0, // empty range + // We need to cover all arities in the range `(arity..infinity)`. We split that + // range into two: lengths smaller than `max_slice.arity()` are treated + // independently as fixed-lengths slices, and lengths above are captured by + // `max_slice`. + None => self.arity()..max_slice.arity(), + }; + } + FixedLen(_) => { + // No need to split. + smaller_lengths = 0..0; + } }; smaller_lengths .map(FixedLen) - .chain(once(self.max_slice)) + .chain(once(max_slice)) .map(move |kind| Slice::new(self.array_len, kind)) } } @@ -716,11 +705,9 @@ impl<'tcx> Constructor<'tcx> { let int_ranges = ctors.filter_map(|ctor| ctor.as_int_range()).cloned(); ctor_range.split(int_ranges).map(IntRange).collect() } - &Slice(Slice { kind: VarLen(self_prefix, self_suffix), array_len }) => { - let mut split_self = SplitVarLenSlice::new(self_prefix, self_suffix, array_len); - let slices = ctors.filter_map(|c| c.as_slice()).map(|s| s.kind); - split_self.split(slices); - split_self.iter().map(Slice).collect() + &Slice(slice @ Slice { kind: VarLen(..), .. }) => { + let slices = ctors.filter_map(|c| c.as_slice()); + slice.split(slices).map(Slice).collect() } // Any other constructor can be used unchanged. _ => smallvec![self.clone()], From 429770a48eb7dcb11831d4670a25a01c698f704c Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Tue, 3 Oct 2023 16:21:40 +0200 Subject: [PATCH 03/50] Splitting ensures subrange comparison is all we need --- .../src/thir/pattern/deconstruct_pat.rs | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs index 6755e665bba1..b4bc45698788 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs @@ -186,18 +186,6 @@ impl IntRange { (lo == other_hi || hi == other_lo) && !self.is_singleton() && !other.is_singleton() } - /// See `Constructor::is_covered_by` - fn is_covered_by(&self, other: &Self) -> bool { - if self.intersection(other).is_some() { - // Constructor splitting should ensure that all intersections we encounter are actually - // inclusions. - assert!(self.is_subrange(other)); - true - } else { - false - } - } - /// Partition a range of integers into disjoint subranges. This does constructor splitting for /// integer ranges as explained at the top of the file. /// @@ -730,7 +718,7 @@ impl<'tcx> Constructor<'tcx> { (Single, Single) => true, (Variant(self_id), Variant(other_id)) => self_id == other_id, - (IntRange(self_range), IntRange(other_range)) => self_range.is_covered_by(other_range), + (IntRange(self_range), IntRange(other_range)) => self_range.is_subrange(other_range), (F32Range(self_from, self_to, self_end), F32Range(other_from, other_to, other_end)) => { self_from.ge(other_from) && match self_to.partial_cmp(other_to) { From c1800ef93fa44ac583c213632a315956b5b2f31b Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Tue, 3 Oct 2023 15:30:05 +0200 Subject: [PATCH 04/50] Replace SplitWildcard with a cleaner ConstructorSet abstraction --- .../src/thir/pattern/deconstruct_pat.rs | 622 +++++++++++------- .../src/thir/pattern/usefulness.rs | 130 ++-- 2 files changed, 434 insertions(+), 318 deletions(-) diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs index b4bc45698788..ab30f5109c77 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs @@ -39,8 +39,8 @@ //! //! Splitting is implemented in the [`Constructor::split`] function. We don't do splitting for //! or-patterns; instead we just try the alternatives one-by-one. For details on splitting -//! wildcards, see [`SplitWildcard`]; for integer ranges, see [`IntRange::split`]; for slices, see -//! [`Slice::split`]. +//! wildcards, see [`Constructor::split`]; for integer ranges, see +//! [`IntRange::split`]; for slices, see [`Slice::split`]. use std::cell::Cell; use std::cmp::{self, max, min, Ordering}; @@ -52,6 +52,7 @@ use smallvec::{smallvec, SmallVec}; use rustc_apfloat::ieee::{DoubleS, IeeeFloat, SingleS}; use rustc_data_structures::captures::Captures; +use rustc_data_structures::fx::FxHashSet; use rustc_hir::{HirId, RangeEnd}; use rustc_index::Idx; use rustc_middle::middle::stability::EvalResult; @@ -86,6 +87,13 @@ fn expand_or_pat<'p, 'tcx>(pat: &'p Pat<'tcx>) -> Vec<&'p Pat<'tcx>> { pats } +/// Whether we have seen a constructor in the column or not. +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +enum Presence { + Unseen, + Seen, +} + /// An inclusive interval, used for precise integer exhaustiveness checking. /// `IntRange`s always store a contiguous range. This means that values are /// encoded such that `0` encodes the minimum value for the integer, @@ -203,10 +211,12 @@ impl IntRange { /// ```text /// ||---|--||-|---|---|---|--| /// ``` + /// + /// Additionally, we track for each output range whether it is covered by one of the column ranges or not. fn split( &self, column_ranges: impl Iterator, - ) -> impl Iterator { + ) -> impl Iterator { /// Represents a boundary between 2 integers. Because the intervals spanning boundaries must be /// able to cover every integer, we need to be able to represent 2^128 + 1 such boundaries. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] @@ -227,41 +237,57 @@ impl IntRange { } // The boundaries of ranges in `column_ranges` intersected with `self`. - let mut boundaries: Vec = column_ranges + // We do parenthesis matching for input ranges. A boundary counts as +1 if it starts + // a range and -1 if it ends it. When the count is > 0 between two boundaries, we + // are within an input range. + let mut boundaries: Vec<(IntBoundary, isize)> = column_ranges .filter_map(|r| self.intersection(&r)) .map(unpack_intrange) - .flat_map(|[lo, hi]| [lo, hi]) + .flat_map(|[lo, hi]| [(lo, 1), (hi, -1)]) .collect(); boundaries.sort_unstable(); + // Counter for parenthesis matching. + let mut paren_counter = 0isize; + let boundaries_with_paren_counts = boundaries + .into_iter() + // Accumulate parenthesis counts. + .map(move |(bdy, delta)| { + paren_counter += delta; + (bdy, paren_counter) + }); + let [self_start, self_end] = unpack_intrange(self.clone()); // Gather pairs of adjacent boundaries. let mut prev_bdy = self_start; - boundaries - .into_iter() - // End with the end of the range. - .chain(once(self_end)) + let mut prev_paren_count = 0; + boundaries_with_paren_counts + // End with the end of the range. The count is irrelevant. + .chain(once((self_end, 0))) // List pairs of adjacent boundaries. - .map(move |bdy| { - let ret = (prev_bdy, bdy); + .map(move |(bdy, paren_count)| { + let ret = (prev_bdy, prev_paren_count, bdy); prev_bdy = bdy; + prev_paren_count = paren_count; ret }) // Skip duplicates. - .filter(|&(prev_bdy, bdy)| prev_bdy != bdy) + .filter(|&(prev_bdy, _, bdy)| prev_bdy != bdy) // Convert back to ranges. - .map(move |(prev_bdy, bdy)| { + .map(move |(prev_bdy, paren_count, bdy)| { use IntBoundary::*; + use Presence::*; + let presence = if paren_count > 0 { Seen } else { Unseen }; let range = match (prev_bdy, bdy) { (JustBefore(n), JustBefore(m)) if n < m => n..=(m - 1), (JustBefore(n), AfterMax) => n..=u128::MAX, _ => unreachable!(), // Ruled out by the sorting and filtering we did }; - IntRange { range } + (presence, IntRange { range }) }) } - /// Only used for displaying the range properly. + /// Only used for displaying the range. fn to_pat<'tcx>(&self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Pat<'tcx> { let (lo, hi) = self.boundaries(); @@ -414,7 +440,7 @@ impl Slice { /// match x { /// [true, true, ..] => {} /// [.., false, false] => {} - /// [..] => {} // `self` + /// [..] => {} /// } /// # } /// ``` @@ -447,9 +473,9 @@ impl Slice { /// /// We see that above length 4, we are simply inserting columns full of wildcards in the middle. /// This means that specialization and witness computation with slices of length `l >= 4` will - /// give equivalent results independently of `l`. This applies to any set of slice patterns: - /// there will be a length `L` above which all lengths behave the same. This is exactly what we - /// need for constructor splitting. + /// give equivalent results regardless of `l`. This applies to any set of slice patterns: there + /// will be a length `L` above which all lengths behave the same. This is exactly what we need + /// for constructor splitting. /// /// A variable-length slice pattern covers all lengths from its arity up to infinity. As we just /// saw, we can split this in two: lengths below `L` are treated individually with a @@ -467,10 +493,18 @@ impl Slice { /// `max_slice` below will be made to have this arity `L`. /// /// If `self` is fixed-length, it is returned as-is. - fn split(self, column_slices: impl Iterator) -> impl Iterator { + /// + /// Additionally, we track for each output slice whether it is covered by one of the column slices or not. + fn split( + self, + column_slices: impl Iterator, + ) -> impl Iterator { // Range of lengths below `L`. let smaller_lengths; + let arity = self.arity(); let mut max_slice = self.kind; + let mut min_var_len = usize::MAX; + let mut seen_fixed_lens = FxHashSet::default(); match &mut max_slice { VarLen(max_prefix_len, max_suffix_len) => { // We grow `max_slice` to be larger than all slices encountered, as described above. @@ -481,10 +515,14 @@ impl Slice { match slice.kind { FixedLen(len) => { max_fixed_len = cmp::max(max_fixed_len, len); + if arity <= len { + seen_fixed_lens.insert(len); + } } VarLen(prefix, suffix) => { *max_prefix_len = cmp::max(*max_prefix_len, prefix); *max_suffix_len = cmp::max(*max_suffix_len, suffix); + min_var_len = cmp::min(min_var_len, prefix + suffix); } } } @@ -515,14 +553,32 @@ impl Slice { }; } FixedLen(_) => { - // No need to split. + // No need to split here. We only track presence. + for slice in column_slices { + match slice.kind { + FixedLen(len) => { + if len == arity { + seen_fixed_lens.insert(len); + } + } + VarLen(prefix, suffix) => { + min_var_len = cmp::min(min_var_len, prefix + suffix); + } + } + } smaller_lengths = 0..0; } }; - smaller_lengths - .map(FixedLen) - .chain(once(max_slice)) - .map(move |kind| Slice::new(self.array_len, kind)) + + smaller_lengths.map(FixedLen).chain(once(max_slice)).map(move |kind| { + let arity = kind.arity(); + let seen = if min_var_len <= arity || seen_fixed_lens.contains(&arity) { + Presence::Seen + } else { + Presence::Unseen + }; + (seen, Slice::new(self.array_len, kind)) + }) } } @@ -556,8 +612,8 @@ pub(super) enum Constructor<'tcx> { /// Fake extra constructor for enums that aren't allowed to be matched exhaustively. Also used /// for those types for which we cannot list constructors explicitly, like `f64` and `str`. NonExhaustive, - /// Stands for constructors that are not seen in the matrix, as explained in the documentation - /// for [`SplitWildcard`]. The carried `bool` is used for the `non_exhaustive_omitted_patterns` + /// Stands for constructors that are not seen in the matrix, as explained in the code for + /// [`Constructor::split`]. The carried `bool` is used for the `non_exhaustive_omitted_patterns` /// lint. Missing { nonexhaustive_enum_missing_real_variants: bool, @@ -577,13 +633,18 @@ impl<'tcx> Constructor<'tcx> { matches!(self, NonExhaustive) } + pub(super) fn as_variant(&self) -> Option { + match self { + Variant(i) => Some(*i), + _ => None, + } + } fn as_int_range(&self) -> Option<&IntRange> { match self { IntRange(range) => Some(range), _ => None, } } - fn as_slice(&self) -> Option { match self { Slice(slice) => Some(*slice), @@ -660,19 +721,19 @@ impl<'tcx> Constructor<'tcx> { } } - /// Some constructors (namely `Wildcard`, `IntRange` and `Slice`) actually stand for a set of actual - /// constructors (like variants, integers or fixed-sized slices). When specializing for these - /// constructors, we want to be specialising for the actual underlying constructors. + /// Some constructors (namely `Wildcard`, `IntRange` and `Slice`) actually stand for a set of + /// actual constructors (like variants, integers or fixed-sized slices). When specializing for + /// these constructors, we want to be specialising for the actual underlying constructors. /// Naively, we would simply return the list of constructors they correspond to. We instead are - /// more clever: if there are constructors that we know will behave the same wrt the current - /// matrix, we keep them grouped. For example, all slices of a sufficiently large length - /// will either be all useful or all non-useful with a given matrix. + /// more clever: if there are constructors that we know will behave the same w.r.t. the current + /// matrix, we keep them grouped. For example, all slices of a sufficiently large length will + /// either be all useful or all non-useful with a given matrix. /// /// See the branches for details on how the splitting is done. /// - /// This function may discard some irrelevant constructors if this preserves behavior and - /// diagnostics. Eg. for the `_` case, we ignore the constructors already present in the - /// matrix, unless all of them are. + /// This function may discard some irrelevant constructors if this preserves behavior. Eg. for + /// the `_` case, we ignore the constructors already present in the column, unless all of them + /// are. pub(super) fn split<'a>( &self, pcx: &PatCtxt<'_, '_, 'tcx>, @@ -683,19 +744,74 @@ impl<'tcx> Constructor<'tcx> { { match self { Wildcard => { - let mut split_wildcard = SplitWildcard::new(pcx); - split_wildcard.split(pcx, ctors); - split_wildcard.into_ctors(pcx) + let split_set = ConstructorSet::for_ty(pcx.cx, pcx.ty).split(pcx, ctors); + if !split_set.missing.is_empty() { + // We are splitting a wildcard in order to compute its usefulness. Some constructors are + // not present in the column. The first thing we note is that specializing with any of + // the missing constructors would select exactly the rows with wildcards. Moreover, they + // would all return equivalent results. We can therefore group them all into a + // fictitious `Missing` constructor. + // + // As an important optimization, this function will skip all the present constructors. + // This is correct because specializing with any of the present constructors would + // select a strict superset of the wildcard rows, and thus would only find witnesses + // already found with the `Missing` constructor. + // This does mean that diagnostics are incomplete: in + // ``` + // match x { + // Some(true) => {} + // } + // ``` + // we report `None` as missing but not `Some(false)`. + // + // When all the constructors are missing we can equivalently return the `Wildcard` + // constructor on its own. The difference between `Wildcard` and `Missing` will then + // only be in diagnostics. + + // If some constructors are missing, we typically want to report those constructors, + // e.g.: + // ``` + // enum Direction { N, S, E, W } + // let Direction::N = ...; + // ``` + // we can report 3 witnesses: `S`, `E`, and `W`. + // + // However, if the user didn't actually specify a constructor + // in this arm, e.g., in + // ``` + // let x: (Direction, Direction, bool) = ...; + // let (_, _, false) = x; + // ``` + // we don't want to show all 16 possible witnesses `(, , + // true)` - we are satisfied with `(_, _, true)`. So if all constructors are missing we + // prefer to report just a wildcard `_`. + // + // The exception is: if we are at the top-level, for example in an empty match, we + // usually prefer to report the full list of constructors. + let all_missing = split_set.present.is_empty(); + let report_when_all_missing = + pcx.is_top_level && !IntRange::is_integral(pcx.ty); + let ctor = if all_missing && !report_when_all_missing { + Wildcard + } else { + Missing { + nonexhaustive_enum_missing_real_variants: split_set + .nonexhaustive_enum_missing_real_variants, + } + }; + smallvec![ctor] + } else { + split_set.present + } } - // Fast-track if the range is trivial. In particular, we don't do the overlapping - // ranges check. - IntRange(ctor_range) if !ctor_range.is_singleton() => { - let int_ranges = ctors.filter_map(|ctor| ctor.as_int_range()).cloned(); - ctor_range.split(int_ranges).map(IntRange).collect() + // Fast-track if the range is trivial. + IntRange(this_range) if !this_range.is_singleton() => { + let column_ranges = ctors.filter_map(|ctor| ctor.as_int_range()).cloned(); + this_range.split(column_ranges).map(|(_, range)| IntRange(range)).collect() } - &Slice(slice @ Slice { kind: VarLen(..), .. }) => { - let slices = ctors.filter_map(|c| c.as_slice()); - slice.split(slices).map(Slice).collect() + Slice(this_slice @ Slice { kind: VarLen(..), .. }) => { + let column_slices = ctors.filter_map(|c| c.as_slice()); + this_slice.split(column_slices).map(|(_, slice)| Slice(slice)).collect() } // Any other constructor can be used unchanged. _ => smallvec![self.clone()], @@ -755,96 +871,112 @@ impl<'tcx> Constructor<'tcx> { ), } } +} - /// Faster version of `is_covered_by` when applied to many constructors. `used_ctors` is - /// assumed to be built from `matrix.head_ctors()` with wildcards and opaques filtered out, - /// and `self` is assumed to have been split from a wildcard. - fn is_covered_by_any<'p>( - &self, - pcx: &PatCtxt<'_, 'p, 'tcx>, - used_ctors: &[Constructor<'tcx>], - ) -> bool { - if used_ctors.is_empty() { - return false; - } - - // This must be kept in sync with `is_covered_by`. - match self { - // If `self` is `Single`, `used_ctors` cannot contain anything else than `Single`s. - Single => !used_ctors.is_empty(), - Variant(vid) => used_ctors.iter().any(|c| matches!(c, Variant(i) if i == vid)), - IntRange(range) => used_ctors - .iter() - .filter_map(|c| c.as_int_range()) - .any(|other| range.is_covered_by(other)), - Slice(slice) => used_ctors - .iter() - .filter_map(|c| c.as_slice()) - .any(|other| slice.is_covered_by(other)), - // This constructor is never covered by anything else - NonExhaustive => false, - Str(..) | F32Range(..) | F64Range(..) | Opaque | Missing { .. } | Wildcard | Or => { - span_bug!(pcx.span, "found unexpected ctor in all_ctors: {:?}", self) - } - } - } +/// Describes the set of all constructors for a type. +pub(super) enum ConstructorSet { + /// The type has a single constructor, e.g. `&T` or a struct. + Single, + /// This type has the following list of constructors. + Variants { variants: Vec, non_exhaustive: bool }, + /// The type is spanned by integer values. The range or ranges give the set of allowed values. + /// The second range is only useful for `char`. + /// This is reused for bool. FIXME: don't. + /// `non_exhaustive` is used when the range is not allowed to be matched exhaustively (that's + /// for usize/isize). + Integers { range_1: IntRange, range_2: Option, non_exhaustive: bool }, + /// The type is matched by slices. The usize is the compile-time length of the array, if known. + Slice(Option), + /// The type is matched by slices whose elements are uninhabited. + SliceOfEmpty, + /// The constructors cannot be listed, and the type cannot be matched exhaustively. E.g. `str`, + /// floats. + Unlistable, + /// The type has no inhabitants. + Uninhabited, } -/// A wildcard constructor that we split relative to the constructors in the matrix, as explained -/// at the top of the file. +/// Describes the result of analyzing the constructors in a column of a match. /// -/// A constructor that is not present in the matrix rows will only be covered by the rows that have -/// wildcards. Thus we can group all of those constructors together; we call them "missing -/// constructors". Splitting a wildcard would therefore list all present constructors individually -/// (or grouped if they are integers or slices), and then all missing constructors together as a -/// group. +/// `present` is morally the set of constructors present in the column, and `missing` is the set of +/// constructors that exist in the type but are not present in the column. /// -/// However we can go further: since any constructor will match the wildcard rows, and having more -/// rows can only reduce the amount of usefulness witnesses, we can skip the present constructors -/// and only try the missing ones. -/// This will not preserve the whole list of witnesses, but will preserve whether the list is empty -/// or not. In fact this is quite natural from the point of view of diagnostics too. This is done -/// in `to_ctors`: in some cases we only return `Missing`. -#[derive(Debug)] -pub(super) struct SplitWildcard<'tcx> { - /// Constructors (other than wildcards and opaques) seen in the matrix. - matrix_ctors: Vec>, - /// All the constructors for this type - all_ctors: SmallVec<[Constructor<'tcx>; 1]>, +/// More formally, they respect the following constraints: +/// - the union of `present` and `missing` covers the whole type +/// - `present` and `missing` are disjoint +/// - neither contains wildcards +/// - each constructor in `present` is covered by some non-wildcard constructor in the column +/// - together, the constructors in `present` cover all the non-wildcard constructor in the column +/// - non-wildcards in the column do no cover anything in `missing` +/// - constructors in `present` and `missing` are split for the column; in other words, they are +/// either fully included in or disjoint from each constructor in the column. This avoids +/// non-trivial intersections like between `0..10` and `5..15`. +struct SplitConstructorSet<'tcx> { + present: SmallVec<[Constructor<'tcx>; 1]>, + missing: Vec>, + /// For the `non_exhaustive_omitted_patterns` lint. + nonexhaustive_enum_missing_real_variants: bool, } -impl<'tcx> SplitWildcard<'tcx> { - pub(super) fn new<'p>(pcx: &PatCtxt<'_, 'p, 'tcx>) -> Self { - debug!("SplitWildcard::new({:?})", pcx.ty); - let cx = pcx.cx; - let make_range = |start, end| { - IntRange( - // `unwrap()` is ok because we know the type is an integer. - IntRange::from_range(cx.tcx, start, end, pcx.ty, RangeEnd::Included), - ) - }; - // This determines the set of all possible constructors for the type `pcx.ty`. For numbers, +impl ConstructorSet { + pub(super) fn for_ty<'p, 'tcx>(cx: &MatchCheckCtxt<'p, 'tcx>, ty: Ty<'tcx>) -> Self { + debug!("ConstructorSet::for_ty({:?})", ty); + let make_range = + |start, end| IntRange::from_range(cx.tcx, start, end, ty, RangeEnd::Included); + // This determines the set of all possible constructors for the type `ty`. For numbers, // arrays and slices we use ranges and variable-length slices when appropriate. // // If the `exhaustive_patterns` feature is enabled, we make sure to omit constructors that // are statically impossible. E.g., for `Option`, we do not include `Some(_)` in the // returned list of constructors. - // Invariant: this is empty if and only if the type is uninhabited (as determined by + // Invariant: this is `Uninhabited` if and only if the type is uninhabited (as determined by // `cx.is_uninhabited()`). - let all_ctors = match pcx.ty.kind() { - ty::Bool => smallvec![make_range(0, 1)], + match ty.kind() { + ty::Bool => { + Self::Integers { range_1: make_range(0, 1), range_2: None, non_exhaustive: false } + } + ty::Char => { + // The valid Unicode Scalar Value ranges. + Self::Integers { + range_1: make_range('\u{0000}' as u128, '\u{D7FF}' as u128), + range_2: Some(make_range('\u{E000}' as u128, '\u{10FFFF}' as u128)), + non_exhaustive: false, + } + } + &ty::Int(ity) => { + // `usize`/`isize` are not allowed to be matched exhaustively unless the + // `precise_pointer_size_matching` feature is enabled. + let non_exhaustive = + ty.is_ptr_sized_integral() && !cx.tcx.features().precise_pointer_size_matching; + let bits = Integer::from_int_ty(&cx.tcx, ity).size().bits() as u128; + let min = 1u128 << (bits - 1); + let max = min - 1; + Self::Integers { range_1: make_range(min, max), non_exhaustive, range_2: None } + } + &ty::Uint(uty) => { + // `usize`/`isize` are not allowed to be matched exhaustively unless the + // `precise_pointer_size_matching` feature is enabled. + let non_exhaustive = + ty.is_ptr_sized_integral() && !cx.tcx.features().precise_pointer_size_matching; + let size = Integer::from_uint_ty(&cx.tcx, uty).size(); + let max = size.truncate(u128::MAX); + Self::Integers { range_1: make_range(0, max), non_exhaustive, range_2: None } + } ty::Array(sub_ty, len) if len.try_eval_target_usize(cx.tcx, cx.param_env).is_some() => { let len = len.eval_target_usize(cx.tcx, cx.param_env) as usize; if len != 0 && cx.is_uninhabited(*sub_ty) { - smallvec![] + Self::Uninhabited } else { - smallvec![Slice(Slice::new(Some(len), VarLen(0, 0)))] + Self::Slice(Some(len)) } } // Treat arrays of a constant but unknown length like slices. ty::Array(sub_ty, _) | ty::Slice(sub_ty) => { - let kind = if cx.is_uninhabited(*sub_ty) { FixedLen(0) } else { VarLen(0, 0) }; - smallvec![Slice(Slice::new(None, kind))] + if cx.is_uninhabited(*sub_ty) { + Self::SliceOfEmpty + } else { + Self::Slice(None) + } } ty::Adt(def, args) if def.is_enum() => { // If the enum is declared as `#[non_exhaustive]`, we treat it as if it had an @@ -863,19 +995,14 @@ impl<'tcx> SplitWildcard<'tcx> { // // we don't want to show every possible IO error, but instead have only `_` as the // witness. - let is_declared_nonexhaustive = cx.is_foreign_non_exhaustive_enum(pcx.ty); - - let is_exhaustive_pat_feature = cx.tcx.features().exhaustive_patterns; - - // If `exhaustive_patterns` is disabled and our scrutinee is an empty enum, we treat it - // as though it had an "unknown" constructor to avoid exposing its emptiness. The - // exception is if the pattern is at the top level, because we want empty matches to be - // considered exhaustive. - let is_secretly_empty = - def.variants().is_empty() && !is_exhaustive_pat_feature && !pcx.is_top_level; + let is_declared_nonexhaustive = cx.is_foreign_non_exhaustive_enum(ty); - let mut ctors: SmallVec<[_; 1]> = - def.variants() + if def.variants().is_empty() && !is_declared_nonexhaustive { + Self::Uninhabited + } else { + let is_exhaustive_pat_feature = cx.tcx.features().exhaustive_patterns; + let variants: Vec<_> = def + .variants() .iter_enumerated() .filter(|(_, v)| { // If `exhaustive_patterns` is enabled, we exclude variants known to be @@ -885,135 +1012,150 @@ impl<'tcx> SplitWildcard<'tcx> { .instantiate(cx.tcx, args) .apply(cx.tcx, cx.param_env, cx.module) }) - .map(|(idx, _)| Variant(idx)) + .map(|(idx, _)| idx) .collect(); - if is_secretly_empty || is_declared_nonexhaustive { - ctors.push(NonExhaustive); + Self::Variants { variants, non_exhaustive: is_declared_nonexhaustive } } - ctors - } - ty::Char => { - smallvec![ - // The valid Unicode Scalar Value ranges. - make_range('\u{0000}' as u128, '\u{D7FF}' as u128), - make_range('\u{E000}' as u128, '\u{10FFFF}' as u128), - ] - } - ty::Int(_) | ty::Uint(_) - if pcx.ty.is_ptr_sized_integral() - && !cx.tcx.features().precise_pointer_size_matching => - { - // `usize`/`isize` are not allowed to be matched exhaustively unless the - // `precise_pointer_size_matching` feature is enabled. So we treat those types like - // `#[non_exhaustive]` enums by returning a special unmatchable constructor. - smallvec![NonExhaustive] } - &ty::Int(ity) => { - let bits = Integer::from_int_ty(&cx.tcx, ity).size().bits() as u128; - let min = 1u128 << (bits - 1); - let max = min - 1; - smallvec![make_range(min, max)] - } - &ty::Uint(uty) => { - let size = Integer::from_uint_ty(&cx.tcx, uty).size(); - let max = size.truncate(u128::MAX); - smallvec![make_range(0, max)] - } - // If `exhaustive_patterns` is disabled and our scrutinee is the never type, we cannot - // expose its emptiness. The exception is if the pattern is at the top level, because we - // want empty matches to be considered exhaustive. - ty::Never if !cx.tcx.features().exhaustive_patterns && !pcx.is_top_level => { - smallvec![NonExhaustive] - } - ty::Never => smallvec![], - _ if cx.is_uninhabited(pcx.ty) => smallvec![], - ty::Adt(..) | ty::Tuple(..) | ty::Ref(..) => smallvec![Single], + ty::Never => Self::Uninhabited, + _ if cx.is_uninhabited(ty) => Self::Uninhabited, + ty::Adt(..) | ty::Tuple(..) | ty::Ref(..) => Self::Single, // This type is one for which we cannot list constructors, like `str` or `f64`. - _ => smallvec![NonExhaustive], - }; - - SplitWildcard { matrix_ctors: Vec::new(), all_ctors } + _ => Self::Unlistable, + } } - /// Pass a set of constructors relative to which to split this one. Don't call twice, it won't - /// do what you want. - pub(super) fn split<'a>( - &mut self, + /// This is the core logical operation of exhaustiveness checking. This analyzes a column a + /// constructors to 1/ determine which constructors of the type (if any) are missing; 2/ split + /// constructors to handle non-trivial intersections e.g. on ranges or slices. + fn split<'a, 'tcx>( + &self, pcx: &PatCtxt<'_, '_, 'tcx>, ctors: impl Iterator> + Clone, - ) where + ) -> SplitConstructorSet<'tcx> + where 'tcx: 'a, { - // Since `all_ctors` never contains wildcards, this won't recurse further. - self.all_ctors = - self.all_ctors.iter().flat_map(|ctor| ctor.split(pcx, ctors.clone())).collect(); - self.matrix_ctors = ctors.filter(|c| !matches!(c, Wildcard | Opaque)).cloned().collect(); - } - - /// Whether there are any value constructors for this type that are not present in the matrix. - fn any_missing(&self, pcx: &PatCtxt<'_, '_, 'tcx>) -> bool { - self.iter_missing(pcx).next().is_some() - } + let mut missing = Vec::new(); + let mut present: SmallVec<[_; 1]> = SmallVec::new(); + // Constructors in `ctors`, except wildcards. + let mut seen = Vec::new(); + for ctor in ctors.cloned() { + match ctor { + // Wildcards in `ctors` are irrelevant to splitting + Opaque | Wildcard => {} + _ => { + seen.push(ctor); + } + } + } + let mut nonexhaustive_enum_missing_real_variants = false; + match self { + ConstructorSet::Single => { + if seen.is_empty() { + missing.push(Single); + } else { + present.push(Single); + } + } + ConstructorSet::Variants { variants, non_exhaustive } => { + let seen_set: FxHashSet<_> = seen.iter().map(|c| c.as_variant().unwrap()).collect(); + let mut skipped_a_hidden_variant = false; + for variant in variants { + let ctor = Variant(*variant); + if seen_set.contains(&variant) { + present.push(ctor); + } else if ctor.is_doc_hidden_variant(pcx) || ctor.is_unstable_variant(pcx) { + // We don't want to mention any variants that are `doc(hidden)` or behind an + // unstable feature gate if they aren't present in the match. + skipped_a_hidden_variant = true; + } else { + missing.push(ctor); + } + } - /// Iterate over the constructors for this type that are not present in the matrix. - pub(super) fn iter_missing<'a, 'p>( - &'a self, - pcx: &'a PatCtxt<'a, 'p, 'tcx>, - ) -> impl Iterator> + Captures<'p> { - self.all_ctors.iter().filter(move |ctor| !ctor.is_covered_by_any(pcx, &self.matrix_ctors)) - } + if *non_exhaustive { + nonexhaustive_enum_missing_real_variants = !missing.is_empty(); + missing.push(NonExhaustive); + } else if skipped_a_hidden_variant { + // FIXME(Nadrieril): This represents the skipped variants, but isn't super + // clean. Using `NonExhaustive` breaks things elsewhere. + missing.push(Wildcard); + } + } + ConstructorSet::Integers { range_1, range_2, non_exhaustive } => { + let seen_ranges = seen.iter().map(|ctor| ctor.as_int_range().unwrap()).cloned(); + for (seen, splitted_range) in range_1.split(seen_ranges.clone()) { + match seen { + Presence::Unseen => missing.push(IntRange(splitted_range)), + Presence::Seen => present.push(IntRange(splitted_range)), + } + } + if let Some(range_2) = range_2 { + for (seen, splitted_range) in range_2.split(seen_ranges) { + match seen { + Presence::Unseen => missing.push(IntRange(splitted_range)), + Presence::Seen => present.push(IntRange(splitted_range)), + } + } + } - /// Return the set of constructors resulting from splitting the wildcard. As explained at the - /// top of the file, if any constructors are missing we can ignore the present ones. - fn into_ctors(self, pcx: &PatCtxt<'_, '_, 'tcx>) -> SmallVec<[Constructor<'tcx>; 1]> { - if self.any_missing(pcx) { - // Some constructors are missing, thus we can specialize with the special `Missing` - // constructor, which stands for those constructors that are not seen in the matrix, - // and matches the same rows as any of them (namely the wildcard rows). See the top of - // the file for details. - // However, when all constructors are missing we can also specialize with the full - // `Wildcard` constructor. The difference will depend on what we want in diagnostics. - - // If some constructors are missing, we typically want to report those constructors, - // e.g.: - // ``` - // enum Direction { N, S, E, W } - // let Direction::N = ...; - // ``` - // we can report 3 witnesses: `S`, `E`, and `W`. - // - // However, if the user didn't actually specify a constructor - // in this arm, e.g., in - // ``` - // let x: (Direction, Direction, bool) = ...; - // let (_, _, false) = x; - // ``` - // we don't want to show all 16 possible witnesses `(, , - // true)` - we are satisfied with `(_, _, true)`. So if all constructors are missing we - // prefer to report just a wildcard `_`. - // - // The exception is: if we are at the top-level, for example in an empty match, we - // sometimes prefer reporting the list of constructors instead of just `_`. - let report_when_all_missing = pcx.is_top_level && !IntRange::is_integral(pcx.ty); - let ctor = if !self.matrix_ctors.is_empty() || report_when_all_missing { - if pcx.is_non_exhaustive { - Missing { - nonexhaustive_enum_missing_real_variants: self - .iter_missing(pcx) - .any(|c| !(c.is_non_exhaustive() || c.is_unstable_variant(pcx))), + if *non_exhaustive { + missing.push(NonExhaustive); + } + } + &ConstructorSet::Slice(array_len) => { + let seen_slices = seen.iter().map(|c| c.as_slice().unwrap()); + let base_slice = Slice { kind: VarLen(0, 0), array_len }; + for (seen, splitted_slice) in base_slice.split(seen_slices) { + let ctor = Slice(splitted_slice); + match seen { + Presence::Unseen => missing.push(ctor), + Presence::Seen => present.push(ctor), } + } + } + ConstructorSet::SliceOfEmpty => { + // Behaves essentially like `Single`. + let slice = Slice(Slice::new(None, FixedLen(0))); + if seen.is_empty() { + missing.push(slice); } else { - Missing { nonexhaustive_enum_missing_real_variants: false } + present.push(slice); } - } else { - Wildcard - }; - return smallvec![ctor]; + } + ConstructorSet::Unlistable => { + // Since we can't list constructors, we take the ones in the column. This might list + // some constructors several times but there's not much we can do. + present.extend(seen.iter().cloned()); + missing.push(NonExhaustive); + } + // If `exhaustive_patterns` is disabled and our scrutinee is an empty type, we cannot + // expose its emptiness. The exception is if the pattern is at the top level, because we + // want empty matches to be considered exhaustive. + ConstructorSet::Uninhabited + if !pcx.cx.tcx.features().exhaustive_patterns && !pcx.is_top_level => + { + missing.push(NonExhaustive); + } + ConstructorSet::Uninhabited => {} } - // All the constructors are present in the matrix, so we just go through them all. - self.all_ctors + SplitConstructorSet { present, missing, nonexhaustive_enum_missing_real_variants } + } + + /// Compute the set of constructors missing from this column. + /// This is only used for reporting to the user. + pub(super) fn compute_missing<'a, 'tcx>( + &self, + pcx: &PatCtxt<'_, '_, 'tcx>, + ctors: impl Iterator> + Clone, + ) -> Vec> + where + 'tcx: 'a, + { + self.split(pcx, ctors).missing } } diff --git a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs index 21031e8ba9d7..68ca0e2ac046 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs @@ -307,7 +307,7 @@ use self::ArmType::*; use self::Usefulness::*; -use super::deconstruct_pat::{Constructor, DeconstructedPat, Fields, SplitWildcard}; +use super::deconstruct_pat::{Constructor, ConstructorSet, DeconstructedPat, Fields}; use crate::errors::{NonExhaustiveOmittedPattern, Uncovered}; use rustc_data_structures::captures::Captures; @@ -368,8 +368,6 @@ pub(super) struct PatCtxt<'a, 'p, 'tcx> { /// Whether the current pattern is the whole pattern as found in a match arm, or if it's a /// subpattern. pub(super) is_top_level: bool, - /// Whether the current pattern is from a `non_exhaustive` enum. - pub(super) is_non_exhaustive: bool, } impl<'a, 'p, 'tcx> fmt::Debug for PatCtxt<'a, 'p, 'tcx> { @@ -616,62 +614,41 @@ impl<'p, 'tcx> Usefulness<'p, 'tcx> { WithWitnesses(ref witnesses) if witnesses.is_empty() => self, WithWitnesses(witnesses) => { let new_witnesses = if let Constructor::Missing { .. } = ctor { + let mut missing = ConstructorSet::for_ty(pcx.cx, pcx.ty) + .compute_missing(pcx, matrix.heads().map(DeconstructedPat::ctor)); + if missing.iter().any(|c| c.is_non_exhaustive()) { + // We only report `_` here; listing other constructors would be redundant. + missing = vec![Constructor::NonExhaustive]; + } + // We got the special `Missing` constructor, so each of the missing constructors - // gives a new pattern that is not caught by the match. We list those patterns. - if pcx.is_non_exhaustive { - witnesses - .into_iter() - // Here we don't want the user to try to list all variants, we want them to add - // a wildcard, so we only suggest that. - .map(|witness| { - witness.apply_constructor(pcx, &Constructor::NonExhaustive) - }) - .collect() - } else { - let mut split_wildcard = SplitWildcard::new(pcx); - split_wildcard.split(pcx, matrix.heads().map(DeconstructedPat::ctor)); - - // This lets us know if we skipped any variants because they are marked - // `doc(hidden)` or they are unstable feature gate (only stdlib types). - let mut hide_variant_show_wild = false; - // Construct for each missing constructor a "wild" version of this - // constructor, that matches everything that can be built with - // it. For example, if `ctor` is a `Constructor::Variant` for - // `Option::Some`, we get the pattern `Some(_)`. - let mut new_patterns: Vec> = split_wildcard - .iter_missing(pcx) - .filter_map(|missing_ctor| { - // Check if this variant is marked `doc(hidden)` - if missing_ctor.is_doc_hidden_variant(pcx) - || missing_ctor.is_unstable_variant(pcx) - { - hide_variant_show_wild = true; - return None; - } - Some(DeconstructedPat::wild_from_ctor(pcx, missing_ctor.clone())) - }) - .collect(); - - if hide_variant_show_wild { - new_patterns.push(DeconstructedPat::wildcard(pcx.ty, pcx.span)); - } - - witnesses - .into_iter() - .flat_map(|witness| { - new_patterns.iter().map(move |pat| { - Witness( - witness - .0 - .iter() - .chain(once(pat)) - .map(DeconstructedPat::clone_and_forget_reachability) - .collect(), - ) - }) + // gives a new pattern that is not caught by the match. + // We construct for each missing constructor a version of this constructor with + // wildcards for fields, i.e. that matches everything that can be built with it. + // For example, if `ctor` is a `Constructor::Variant` for `Option::Some`, we get + // the pattern `Some(_)`. + let new_patterns: Vec> = missing + .into_iter() + .map(|missing_ctor| { + DeconstructedPat::wild_from_ctor(pcx, missing_ctor.clone()) + }) + .collect(); + + witnesses + .into_iter() + .flat_map(|witness| { + new_patterns.iter().map(move |pat| { + Witness( + witness + .0 + .iter() + .chain(once(pat)) + .map(DeconstructedPat::clone_and_forget_reachability) + .collect(), + ) }) - .collect() - } + }) + .collect() } else { witnesses .into_iter() @@ -844,9 +821,8 @@ fn is_useful<'p, 'tcx>( ty = row.head().ty(); } } - let is_non_exhaustive = cx.is_foreign_non_exhaustive_enum(ty); debug!("v.head: {:?}, v.span: {:?}", v.head(), v.head().span()); - let pcx = &PatCtxt { cx, ty, span: v.head().span(), is_top_level, is_non_exhaustive }; + let pcx = &PatCtxt { cx, ty, span: v.head().span(), is_top_level }; let v_ctor = v.head().ctor(); debug!(?v_ctor); @@ -861,7 +837,8 @@ fn is_useful<'p, 'tcx>( } // We split the head constructor of `v`. let split_ctors = v_ctor.split(pcx, matrix.heads().map(DeconstructedPat::ctor)); - let is_non_exhaustive_and_wild = is_non_exhaustive && v_ctor.is_wildcard(); + let is_non_exhaustive_and_wild = + cx.is_foreign_non_exhaustive_enum(ty) && v_ctor.is_wildcard(); // For each constructor, we compute whether there's a value that starts with it that would // witness the usefulness of `v`. let start_matrix = &matrix; @@ -898,24 +875,21 @@ fn is_useful<'p, 'tcx>( Constructor::Missing { nonexhaustive_enum_missing_real_variants: true } ) { - let patterns = { - let mut split_wildcard = SplitWildcard::new(pcx); - split_wildcard.split(pcx, matrix.heads().map(DeconstructedPat::ctor)); - // Construct for each missing constructor a "wild" version of this - // constructor, that matches everything that can be built with - // it. For example, if `ctor` is a `Constructor::Variant` for - // `Option::Some`, we get the pattern `Some(_)`. - split_wildcard - .iter_missing(pcx) - // Filter out the `NonExhaustive` because we want to list only real - // variants. Also remove any unstable feature gated variants. - // Because of how we computed `nonexhaustive_enum_missing_real_variants`, - // this will not return an empty `Vec`. - .filter(|c| !(c.is_non_exhaustive() || c.is_unstable_variant(pcx))) - .cloned() - .map(|missing_ctor| DeconstructedPat::wild_from_ctor(pcx, missing_ctor)) - .collect::>() - }; + let missing = ConstructorSet::for_ty(pcx.cx, pcx.ty) + .compute_missing(pcx, matrix.heads().map(DeconstructedPat::ctor)); + // Construct for each missing constructor a "wild" version of this + // constructor, that matches everything that can be built with + // it. For example, if `ctor` is a `Constructor::Variant` for + // `Option::Some`, we get the pattern `Some(_)`. + let patterns = missing + .into_iter() + // Filter out the `NonExhaustive` because we want to list only real + // variants. Also remove any unstable feature gated variants. + // Because of how we computed `nonexhaustive_enum_missing_real_variants`, + // this will not return an empty `Vec`. + .filter(|c| !(c.is_non_exhaustive() || c.is_unstable_variant(pcx))) + .map(|missing_ctor| DeconstructedPat::wild_from_ctor(pcx, missing_ctor)) + .collect::>(); // Report that a match of a `non_exhaustive` enum marked with `non_exhaustive_omitted_patterns` // is not exhaustive enough. From 2f4cab4d214dd8a5e0b3e90d6e517aa97bd94fd9 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Tue, 3 Oct 2023 17:09:20 +0200 Subject: [PATCH 05/50] Clarify handling of hidden variants --- .../src/thir/pattern/deconstruct_pat.rs | 135 +++++++++--------- .../src/thir/pattern/usefulness.rs | 15 +- 2 files changed, 76 insertions(+), 74 deletions(-) diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs index ab30f5109c77..2a3fd416a528 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs @@ -609,19 +609,23 @@ pub(super) enum Constructor<'tcx> { /// boxes for the purposes of exhaustiveness: we must not inspect them, and they /// don't count towards making a match exhaustive. Opaque, + /// Or-pattern. + Or, + /// Wildcard pattern. + Wildcard, /// Fake extra constructor for enums that aren't allowed to be matched exhaustively. Also used /// for those types for which we cannot list constructors explicitly, like `f64` and `str`. NonExhaustive, - /// Stands for constructors that are not seen in the matrix, as explained in the code for - /// [`Constructor::split`]. The carried `bool` is used for the `non_exhaustive_omitted_patterns` - /// lint. + /// Fake extra constructor for variants that should not be mentioned in diagnostics. + /// We use this for variants behind an unstable gate as well as + /// `#[doc(hidden)]` ones. + Hidden, + /// Fake extra constructor for constructors that are not seen in the matrix, as explained in the + /// code for [`Constructor::split`]. The carried `bool` is used for the + /// `non_exhaustive_omitted_patterns` lint. Missing { - nonexhaustive_enum_missing_real_variants: bool, + nonexhaustive_enum_missing_visible_variants: bool, }, - /// Wildcard pattern. - Wildcard, - /// Or-pattern. - Or, } impl<'tcx> Constructor<'tcx> { @@ -652,32 +656,6 @@ impl<'tcx> Constructor<'tcx> { } } - /// Checks if the `Constructor` is a variant and `TyCtxt::eval_stability` returns - /// `EvalResult::Deny { .. }`. - /// - /// This means that the variant has a stdlib unstable feature marking it. - pub(super) fn is_unstable_variant(&self, pcx: &PatCtxt<'_, '_, 'tcx>) -> bool { - if let Constructor::Variant(idx) = self && let ty::Adt(adt, _) = pcx.ty.kind() { - let variant_def_id = adt.variant(*idx).def_id; - // Filter variants that depend on a disabled unstable feature. - return matches!( - pcx.cx.tcx.eval_stability(variant_def_id, None, DUMMY_SP, None), - EvalResult::Deny { .. } - ); - } - false - } - - /// Checks if the `Constructor` is a `Constructor::Variant` with a `#[doc(hidden)]` - /// attribute from a type not local to the current crate. - pub(super) fn is_doc_hidden_variant(&self, pcx: &PatCtxt<'_, '_, 'tcx>) -> bool { - if let Constructor::Variant(idx) = self && let ty::Adt(adt, _) = pcx.ty.kind() { - let variant_def_id = adt.variants()[*idx].def_id; - return pcx.cx.tcx.is_doc_hidden(variant_def_id) && !variant_def_id.is_local(); - } - false - } - fn variant_index_for_adt(&self, adt: ty::AdtDef<'tcx>) -> VariantIdx { match *self { Variant(idx) => idx, @@ -713,8 +691,9 @@ impl<'tcx> Constructor<'tcx> { | F32Range(..) | F64Range(..) | IntRange(..) - | NonExhaustive | Opaque + | NonExhaustive + | Hidden | Missing { .. } | Wildcard => 0, Or => bug!("The `Or` constructor doesn't have a fixed arity"), @@ -795,8 +774,8 @@ impl<'tcx> Constructor<'tcx> { Wildcard } else { Missing { - nonexhaustive_enum_missing_real_variants: split_set - .nonexhaustive_enum_missing_real_variants, + nonexhaustive_enum_missing_visible_variants: split_set + .nonexhaustive_enum_missing_visible_variants, } }; smallvec![ctor] @@ -828,8 +807,8 @@ impl<'tcx> Constructor<'tcx> { match (self, other) { // Wildcards cover anything (_, Wildcard) => true, - // The missing ctors are not covered by anything in the matrix except wildcards. - (Missing { .. } | Wildcard, _) => false, + // Only a wildcard pattern can match these special constructors. + (Wildcard | Missing { .. } | NonExhaustive | Hidden, _) => false, (Single, Single) => true, (Variant(self_id), Variant(other_id)) => self_id == other_id, @@ -860,8 +839,6 @@ impl<'tcx> Constructor<'tcx> { // We are trying to inspect an opaque constant. Thus we skip the row. (Opaque, _) | (_, Opaque) => false, - // Only a wildcard pattern can match the special extra constructor. - (NonExhaustive, _) => false, _ => span_bug!( pcx.span, @@ -878,7 +855,14 @@ pub(super) enum ConstructorSet { /// The type has a single constructor, e.g. `&T` or a struct. Single, /// This type has the following list of constructors. - Variants { variants: Vec, non_exhaustive: bool }, + /// Some variants are hidden, which means they won't be mentioned in diagnostics unless the user + /// mentioned them first. We use this for variants behind an unstable gate as well as + /// `#[doc(hidden)]` ones. + Variants { + visible_variants: Vec, + hidden_variants: Vec, + non_exhaustive: bool, + }, /// The type is spanned by integer values. The range or ranges give the set of allowed values. /// The second range is only useful for `char`. /// This is reused for bool. FIXME: don't. @@ -915,7 +899,7 @@ struct SplitConstructorSet<'tcx> { present: SmallVec<[Constructor<'tcx>; 1]>, missing: Vec>, /// For the `non_exhaustive_omitted_patterns` lint. - nonexhaustive_enum_missing_real_variants: bool, + nonexhaustive_enum_missing_visible_variants: bool, } impl ConstructorSet { @@ -1001,7 +985,7 @@ impl ConstructorSet { Self::Uninhabited } else { let is_exhaustive_pat_feature = cx.tcx.features().exhaustive_patterns; - let variants: Vec<_> = def + let (hidden_variants, visible_variants) = def .variants() .iter_enumerated() .filter(|(_, v)| { @@ -1013,9 +997,24 @@ impl ConstructorSet { .apply(cx.tcx, cx.param_env, cx.module) }) .map(|(idx, _)| idx) - .collect(); - - Self::Variants { variants, non_exhaustive: is_declared_nonexhaustive } + .partition(|idx| { + let variant_def_id = def.variant(*idx).def_id; + // Filter variants that depend on a disabled unstable feature. + let is_unstable = matches!( + cx.tcx.eval_stability(variant_def_id, None, DUMMY_SP, None), + EvalResult::Deny { .. } + ); + // Filter foreign `#[doc(hidden)]` variants. + let is_doc_hidden = + cx.tcx.is_doc_hidden(variant_def_id) && !variant_def_id.is_local(); + is_unstable || is_doc_hidden + }); + + Self::Variants { + visible_variants, + hidden_variants, + non_exhaustive: is_declared_nonexhaustive, + } } } ty::Never => Self::Uninhabited, @@ -1050,7 +1049,7 @@ impl ConstructorSet { } } } - let mut nonexhaustive_enum_missing_real_variants = false; + let mut nonexhaustive_enum_missing_visible_variants = false; match self { ConstructorSet::Single => { if seen.is_empty() { @@ -1059,29 +1058,34 @@ impl ConstructorSet { present.push(Single); } } - ConstructorSet::Variants { variants, non_exhaustive } => { + ConstructorSet::Variants { visible_variants, hidden_variants, non_exhaustive } => { let seen_set: FxHashSet<_> = seen.iter().map(|c| c.as_variant().unwrap()).collect(); let mut skipped_a_hidden_variant = false; - for variant in variants { + for variant in visible_variants { let ctor = Variant(*variant); if seen_set.contains(&variant) { present.push(ctor); - } else if ctor.is_doc_hidden_variant(pcx) || ctor.is_unstable_variant(pcx) { - // We don't want to mention any variants that are `doc(hidden)` or behind an - // unstable feature gate if they aren't present in the match. - skipped_a_hidden_variant = true; } else { missing.push(ctor); } } + nonexhaustive_enum_missing_visible_variants = + *non_exhaustive && !missing.is_empty(); + + for variant in hidden_variants { + let ctor = Variant(*variant); + if seen_set.contains(&variant) { + present.push(ctor); + } else { + skipped_a_hidden_variant = true; + } + } + if skipped_a_hidden_variant { + missing.push(Hidden); + } if *non_exhaustive { - nonexhaustive_enum_missing_real_variants = !missing.is_empty(); missing.push(NonExhaustive); - } else if skipped_a_hidden_variant { - // FIXME(Nadrieril): This represents the skipped variants, but isn't super - // clean. Using `NonExhaustive` breaks things elsewhere. - missing.push(Wildcard); } } ConstructorSet::Integers { range_1, range_2, non_exhaustive } => { @@ -1142,7 +1146,7 @@ impl ConstructorSet { ConstructorSet::Uninhabited => {} } - SplitConstructorSet { present, missing, nonexhaustive_enum_missing_real_variants } + SplitConstructorSet { present, missing, nonexhaustive_enum_missing_visible_variants } } /// Compute the set of constructors missing from this column. @@ -1272,8 +1276,9 @@ impl<'p, 'tcx> Fields<'p, 'tcx> { | F32Range(..) | F64Range(..) | IntRange(..) - | NonExhaustive | Opaque + | NonExhaustive + | Hidden | Missing { .. } | Wildcard => Fields::empty(), Or => { @@ -1587,7 +1592,7 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> { } &Str(value) => PatKind::Constant { value }, IntRange(range) => return range.to_pat(cx.tcx, self.ty), - Wildcard | NonExhaustive => PatKind::Wild, + Wildcard | NonExhaustive | Hidden => PatKind::Wild, Missing { .. } => bug!( "trying to convert a `Missing` constructor into a `Pat`; this is probably a bug, `Missing` should have been processed in `apply_constructors`" @@ -1770,15 +1775,15 @@ impl<'p, 'tcx> fmt::Debug for DeconstructedPat<'p, 'tcx> { F32Range(lo, hi, end) => write!(f, "{lo}{end}{hi}"), F64Range(lo, hi, end) => write!(f, "{lo}{end}{hi}"), IntRange(range) => write!(f, "{range:?}"), // Best-effort, will render e.g. `false` as `0..=0` - Wildcard | Missing { .. } | NonExhaustive => write!(f, "_ : {:?}", self.ty), + Str(value) => write!(f, "{value}"), + Opaque => write!(f, ""), Or => { for pat in self.iter_fields() { write!(f, "{}{:?}", start_or_continue(" | "), pat)?; } Ok(()) } - Str(value) => write!(f, "{value}"), - Opaque => write!(f, ""), + Wildcard | Missing { .. } | NonExhaustive | Hidden => write!(f, "_ : {:?}", self.ty), } } } diff --git a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs index 68ca0e2ac046..6cd73c7eaa95 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs @@ -872,22 +872,19 @@ fn is_useful<'p, 'tcx>( && usefulness.is_useful() && matches!(witness_preference, RealArm) && matches!( &ctor, - Constructor::Missing { nonexhaustive_enum_missing_real_variants: true } + Constructor::Missing { nonexhaustive_enum_missing_visible_variants: true } ) { let missing = ConstructorSet::for_ty(pcx.cx, pcx.ty) .compute_missing(pcx, matrix.heads().map(DeconstructedPat::ctor)); - // Construct for each missing constructor a "wild" version of this - // constructor, that matches everything that can be built with - // it. For example, if `ctor` is a `Constructor::Variant` for - // `Option::Some`, we get the pattern `Some(_)`. + // Construct for each missing constructor a "wild" version of this constructor, that + // matches everything that can be built with it. For example, if `ctor` is a + // `Constructor::Variant` for `Option::Some`, we get the pattern `Some(_)`. let patterns = missing .into_iter() - // Filter out the `NonExhaustive` because we want to list only real - // variants. Also remove any unstable feature gated variants. - // Because of how we computed `nonexhaustive_enum_missing_real_variants`, + // Because of how we computed `nonexhaustive_enum_missing_visible_variants`, // this will not return an empty `Vec`. - .filter(|c| !(c.is_non_exhaustive() || c.is_unstable_variant(pcx))) + .filter(|c| !(matches!(c, Constructor::NonExhaustive | Constructor::Hidden))) .map(|missing_ctor| DeconstructedPat::wild_from_ctor(pcx, missing_ctor)) .collect::>(); From fda0301b3395ebc6d33d9da566027010b37e1adc Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Tue, 3 Oct 2023 19:51:18 +0200 Subject: [PATCH 06/50] Don't collect `seen` if not needed --- .../src/thir/pattern/deconstruct_pat.rs | 30 +++++++------------ 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs index 2a3fd416a528..a2bbde250c3d 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs @@ -1036,30 +1036,21 @@ impl ConstructorSet { where 'tcx: 'a, { - let mut missing = Vec::new(); let mut present: SmallVec<[_; 1]> = SmallVec::new(); + let mut missing = Vec::new(); // Constructors in `ctors`, except wildcards. - let mut seen = Vec::new(); - for ctor in ctors.cloned() { - match ctor { - // Wildcards in `ctors` are irrelevant to splitting - Opaque | Wildcard => {} - _ => { - seen.push(ctor); - } - } - } + let mut seen = ctors.filter(|c| !(matches!(c, Opaque | Wildcard))); let mut nonexhaustive_enum_missing_visible_variants = false; match self { ConstructorSet::Single => { - if seen.is_empty() { + if seen.next().is_none() { missing.push(Single); } else { present.push(Single); } } ConstructorSet::Variants { visible_variants, hidden_variants, non_exhaustive } => { - let seen_set: FxHashSet<_> = seen.iter().map(|c| c.as_variant().unwrap()).collect(); + let seen_set: FxHashSet<_> = seen.map(|c| c.as_variant().unwrap()).collect(); let mut skipped_a_hidden_variant = false; for variant in visible_variants { let ctor = Variant(*variant); @@ -1089,15 +1080,16 @@ impl ConstructorSet { } } ConstructorSet::Integers { range_1, range_2, non_exhaustive } => { - let seen_ranges = seen.iter().map(|ctor| ctor.as_int_range().unwrap()).cloned(); - for (seen, splitted_range) in range_1.split(seen_ranges.clone()) { + let seen_ranges: Vec<_> = + seen.map(|ctor| ctor.as_int_range().unwrap().clone()).collect(); + for (seen, splitted_range) in range_1.split(seen_ranges.iter().cloned()) { match seen { Presence::Unseen => missing.push(IntRange(splitted_range)), Presence::Seen => present.push(IntRange(splitted_range)), } } if let Some(range_2) = range_2 { - for (seen, splitted_range) in range_2.split(seen_ranges) { + for (seen, splitted_range) in range_2.split(seen_ranges.into_iter()) { match seen { Presence::Unseen => missing.push(IntRange(splitted_range)), Presence::Seen => present.push(IntRange(splitted_range)), @@ -1110,7 +1102,7 @@ impl ConstructorSet { } } &ConstructorSet::Slice(array_len) => { - let seen_slices = seen.iter().map(|c| c.as_slice().unwrap()); + let seen_slices = seen.map(|c| c.as_slice().unwrap()); let base_slice = Slice { kind: VarLen(0, 0), array_len }; for (seen, splitted_slice) in base_slice.split(seen_slices) { let ctor = Slice(splitted_slice); @@ -1123,7 +1115,7 @@ impl ConstructorSet { ConstructorSet::SliceOfEmpty => { // Behaves essentially like `Single`. let slice = Slice(Slice::new(None, FixedLen(0))); - if seen.is_empty() { + if seen.next().is_none() { missing.push(slice); } else { present.push(slice); @@ -1132,7 +1124,7 @@ impl ConstructorSet { ConstructorSet::Unlistable => { // Since we can't list constructors, we take the ones in the column. This might list // some constructors several times but there's not much we can do. - present.extend(seen.iter().cloned()); + present.extend(seen.cloned()); missing.push(NonExhaustive); } // If `exhaustive_patterns` is disabled and our scrutinee is an empty type, we cannot From edf6a2d3371218043e4858b81fe48c99535cabe7 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Wed, 4 Oct 2023 15:59:16 +0200 Subject: [PATCH 07/50] Clarify for review --- .../src/thir/pattern/deconstruct_pat.rs | 58 +++++++++++-------- 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs index a2bbde250c3d..dd00982f7f62 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs @@ -201,18 +201,26 @@ impl IntRange { /// intersections between an output range and a column range are inclusions. No output range /// straddles the boundary of one of the inputs. /// + /// Additionally, we track for each output range whether it is covered by one of the column ranges or not. + /// /// The following input: /// ```text - /// |-------------------------| // `self` - /// |------| |----------| |----| - /// |-------| |-------| + /// (--------------------------) // `self` + /// (------) (----------) (-) + /// (------) (--------) /// ``` - /// would be iterated over as follows: + /// is first intersected with `self`: /// ```text - /// ||---|--||-|---|---|---|--| + /// (--------------------------) // `self` + /// (----) (----------) (-) + /// (------) (--------) /// ``` - /// - /// Additionally, we track for each output range whether it is covered by one of the column ranges or not. + /// and then iterated over as follows: + /// ```text + /// (-(--)-(-)-(------)-)--(-)- + /// ``` + /// where each sequence of dashes is an output range, and dashes outside parentheses are marked + /// as `Presence::Missing`. fn split( &self, column_ranges: impl Iterator, @@ -245,33 +253,30 @@ impl IntRange { .map(unpack_intrange) .flat_map(|[lo, hi]| [(lo, 1), (hi, -1)]) .collect(); + // We sort by boundary, and for each boundary we sort the "closing parentheses" first. The + // order of +1/-1 for a same boundary value is actually irrelevant, because we only look at + // the accumulated count between distinct boundary values. boundaries.sort_unstable(); - // Counter for parenthesis matching. - let mut paren_counter = 0isize; - let boundaries_with_paren_counts = boundaries - .into_iter() - // Accumulate parenthesis counts. - .map(move |(bdy, delta)| { - paren_counter += delta; - (bdy, paren_counter) - }); - let [self_start, self_end] = unpack_intrange(self.clone()); + // Accumulate parenthesis counts. + let mut paren_counter = 0isize; // Gather pairs of adjacent boundaries. let mut prev_bdy = self_start; - let mut prev_paren_count = 0; - boundaries_with_paren_counts - // End with the end of the range. The count is irrelevant. + boundaries + .into_iter() + // End with the end of the range. The count is ignored. .chain(once((self_end, 0))) - // List pairs of adjacent boundaries. - .map(move |(bdy, paren_count)| { - let ret = (prev_bdy, prev_paren_count, bdy); + // List pairs of adjacent boundaries and the count between them. + .map(move |(bdy, delta)| { + // `delta` affects the count as we cross `bdy`, so the relevant count between + // `prev_bdy` and `bdy` is untouched by `delta`. + let ret = (prev_bdy, paren_counter, bdy); prev_bdy = bdy; - prev_paren_count = paren_count; + paren_counter += delta; ret }) - // Skip duplicates. + // Skip empty ranges. .filter(|&(prev_bdy, _, bdy)| prev_bdy != bdy) // Convert back to ranges. .map(move |(prev_bdy, paren_count, bdy)| { @@ -503,7 +508,10 @@ impl Slice { let smaller_lengths; let arity = self.arity(); let mut max_slice = self.kind; + // Tracks the smallest variable-length slice we've seen. Any slice arity above it is + // therefore `Presence::Seen` in the column. let mut min_var_len = usize::MAX; + // Tracks the fixed-length slices we've seen, to mark them as `Presence::Seen`. let mut seen_fixed_lens = FxHashSet::default(); match &mut max_slice { VarLen(max_prefix_len, max_suffix_len) => { From c1b29b338dc37f96f0695e393743ce35508d3704 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Thu, 5 Oct 2023 00:58:14 +0200 Subject: [PATCH 08/50] Fix handling slices of empty types --- .../src/thir/pattern/deconstruct_pat.rs | 29 ++++++++++---- tests/ui/pattern/usefulness/slice_of_empty.rs | 22 +++++++++++ .../pattern/usefulness/slice_of_empty.stderr | 39 +++++++++++++++++++ 3 files changed, 82 insertions(+), 8 deletions(-) create mode 100644 tests/ui/pattern/usefulness/slice_of_empty.rs create mode 100644 tests/ui/pattern/usefulness/slice_of_empty.stderr diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs index dd00982f7f62..a7a000ba31c6 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs @@ -859,6 +859,7 @@ impl<'tcx> Constructor<'tcx> { } /// Describes the set of all constructors for a type. +#[derive(Debug)] pub(super) enum ConstructorSet { /// The type has a single constructor, e.g. `&T` or a struct. Single, @@ -903,6 +904,7 @@ pub(super) enum ConstructorSet { /// - constructors in `present` and `missing` are split for the column; in other words, they are /// either fully included in or disjoint from each constructor in the column. This avoids /// non-trivial intersections like between `0..10` and `5..15`. +#[derive(Debug)] struct SplitConstructorSet<'tcx> { present: SmallVec<[Constructor<'tcx>; 1]>, missing: Vec>, @@ -911,8 +913,8 @@ struct SplitConstructorSet<'tcx> { } impl ConstructorSet { + #[instrument(level = "debug", skip(cx), ret)] pub(super) fn for_ty<'p, 'tcx>(cx: &MatchCheckCtxt<'p, 'tcx>, ty: Ty<'tcx>) -> Self { - debug!("ConstructorSet::for_ty({:?})", ty); let make_range = |start, end| IntRange::from_range(cx.tcx, start, end, ty, RangeEnd::Included); // This determines the set of all possible constructors for the type `ty`. For numbers, @@ -1036,6 +1038,7 @@ impl ConstructorSet { /// This is the core logical operation of exhaustiveness checking. This analyzes a column a /// constructors to 1/ determine which constructors of the type (if any) are missing; 2/ split /// constructors to handle non-trivial intersections e.g. on ranges or slices. + #[instrument(level = "debug", skip(self, pcx, ctors), ret)] fn split<'a, 'tcx>( &self, pcx: &PatCtxt<'_, '_, 'tcx>, @@ -1111,7 +1114,7 @@ impl ConstructorSet { } &ConstructorSet::Slice(array_len) => { let seen_slices = seen.map(|c| c.as_slice().unwrap()); - let base_slice = Slice { kind: VarLen(0, 0), array_len }; + let base_slice = Slice::new(array_len, VarLen(0, 0)); for (seen, splitted_slice) in base_slice.split(seen_slices) { let ctor = Slice(splitted_slice); match seen { @@ -1121,12 +1124,22 @@ impl ConstructorSet { } } ConstructorSet::SliceOfEmpty => { - // Behaves essentially like `Single`. - let slice = Slice(Slice::new(None, FixedLen(0))); - if seen.next().is_none() { - missing.push(slice); - } else { - present.push(slice); + // This one is tricky because even though there's only one possible value of this + // type (namely `[]`), slice patterns of all lengths are allowed, they're just + // unreachable if length != 0. + // We still gather the seen constructors in `present`, but the only slice that can + // go in `missing` is `[]`. + let seen_slices = seen.map(|c| c.as_slice().unwrap()); + let base_slice = Slice::new(None, VarLen(0, 0)); + for (seen, splitted_slice) in base_slice.split(seen_slices) { + let ctor = Slice(splitted_slice); + match seen { + Presence::Seen => present.push(ctor), + Presence::Unseen if splitted_slice.arity() == 0 => { + missing.push(Slice(Slice::new(None, FixedLen(0)))) + } + Presence::Unseen => {} + } } } ConstructorSet::Unlistable => { diff --git a/tests/ui/pattern/usefulness/slice_of_empty.rs b/tests/ui/pattern/usefulness/slice_of_empty.rs new file mode 100644 index 000000000000..fe068871195a --- /dev/null +++ b/tests/ui/pattern/usefulness/slice_of_empty.rs @@ -0,0 +1,22 @@ +#![feature(never_type)] +#![feature(exhaustive_patterns)] +#![deny(unreachable_patterns)] + +fn main() {} + +fn foo(nevers: &[!]) { + match nevers { + &[] => (), + }; + + match nevers { + &[] => (), + &[_] => (), //~ ERROR unreachable pattern + &[_, _, ..] => (), //~ ERROR unreachable pattern + }; + + match nevers { + //~^ ERROR non-exhaustive patterns: `&[]` not covered + &[_] => (), //~ ERROR unreachable pattern + }; +} diff --git a/tests/ui/pattern/usefulness/slice_of_empty.stderr b/tests/ui/pattern/usefulness/slice_of_empty.stderr new file mode 100644 index 000000000000..07bb6b3a67d8 --- /dev/null +++ b/tests/ui/pattern/usefulness/slice_of_empty.stderr @@ -0,0 +1,39 @@ +error: unreachable pattern + --> $DIR/slice_of_empty.rs:14:9 + | +LL | &[_] => (), + | ^^^^ + | +note: the lint level is defined here + --> $DIR/slice_of_empty.rs:3:9 + | +LL | #![deny(unreachable_patterns)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: unreachable pattern + --> $DIR/slice_of_empty.rs:15:9 + | +LL | &[_, _, ..] => (), + | ^^^^^^^^^^^ + +error: unreachable pattern + --> $DIR/slice_of_empty.rs:20:9 + | +LL | &[_] => (), + | ^^^^ + +error[E0004]: non-exhaustive patterns: `&[]` not covered + --> $DIR/slice_of_empty.rs:18:11 + | +LL | match nevers { + | ^^^^^^ pattern `&[]` not covered + | + = note: the matched value is of type `&[!]` +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown + | +LL | &[_] => (), &[] => todo!(), + | ++++++++++++++++ + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0004`. From ae9cec58394d7a38aac17e2873d213d5fcd85f7a Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Fri, 6 Oct 2023 01:17:09 -0700 Subject: [PATCH 09/50] Copy 1-element arrays as scalars, not vectors For `[T; 1]` it's silly to copy as `<1 x T>` when we can just copy as `T`. --- compiler/rustc_codegen_llvm/src/type_of.rs | 7 +++- .../x86_64-array-pair-load-store-merge.rs | 19 +++++++++++ tests/codegen/array-codegen.rs | 22 +++++++++++++ tests/codegen/array-optimized.rs | 33 +++++++++++++++++++ 4 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 tests/assembly/x86_64-array-pair-load-store-merge.rs create mode 100644 tests/codegen/array-optimized.rs diff --git a/compiler/rustc_codegen_llvm/src/type_of.rs b/compiler/rustc_codegen_llvm/src/type_of.rs index dcc62d314fff..fd4c9572af2f 100644 --- a/compiler/rustc_codegen_llvm/src/type_of.rs +++ b/compiler/rustc_codegen_llvm/src/type_of.rs @@ -397,7 +397,12 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> { // extracts all the individual values. let ety = element.llvm_type(cx); - return Some(cx.type_vector(ety, *count)); + if *count == 1 { + // Emitting `<1 x T>` would be silly; just use the scalar. + return Some(ety); + } else { + return Some(cx.type_vector(ety, *count)); + } } // FIXME: The above only handled integer arrays; surely more things diff --git a/tests/assembly/x86_64-array-pair-load-store-merge.rs b/tests/assembly/x86_64-array-pair-load-store-merge.rs new file mode 100644 index 000000000000..4a8e40f85300 --- /dev/null +++ b/tests/assembly/x86_64-array-pair-load-store-merge.rs @@ -0,0 +1,19 @@ +// assembly-output: emit-asm +// compile-flags: --crate-type=lib -O -C llvm-args=-x86-asm-syntax=intel +// only-x86_64 +// ignore-sgx + +// Depending on various codegen choices, this might end up copying +// a `<2 x i8>`, an `i16`, or two `i8`s. +// Regardless of those choices, make sure the instructions use (2-byte) words. + +// CHECK-LABEL: array_copy_2_elements: +#[no_mangle] +pub fn array_copy_2_elements(a: &[u8; 2], p: &mut [u8; 2]) { + // CHECK-NOT: byte + // CHECK-NOT: mov + // CHECK: mov{{.+}}, word ptr + // CHECK-NEXT: mov word ptr + // CHECK-NEXT: ret + *p = *a; +} diff --git a/tests/codegen/array-codegen.rs b/tests/codegen/array-codegen.rs index ba0d444f97e3..bf5ae74679bb 100644 --- a/tests/codegen/array-codegen.rs +++ b/tests/codegen/array-codegen.rs @@ -32,3 +32,25 @@ pub fn array_copy(a: &[u8; 4], p: &mut [u8; 4]) { // CHECK: store <4 x i8> %[[TEMP2]], ptr %p, align 1 *p = *a; } + +// CHECK-LABEL: @array_copy_1_element +#[no_mangle] +pub fn array_copy_1_element(a: &[u8; 1], p: &mut [u8; 1]) { + // CHECK: %[[LOCAL:.+]] = alloca [1 x i8], align 1 + // CHECK: %[[TEMP1:.+]] = load i8, ptr %a, align 1 + // CHECK: store i8 %[[TEMP1]], ptr %[[LOCAL]], align 1 + // CHECK: %[[TEMP2:.+]] = load i8, ptr %[[LOCAL]], align 1 + // CHECK: store i8 %[[TEMP2]], ptr %p, align 1 + *p = *a; +} + +// CHECK-LABEL: @array_copy_2_elements +#[no_mangle] +pub fn array_copy_2_elements(a: &[u8; 2], p: &mut [u8; 2]) { + // CHECK: %[[LOCAL:.+]] = alloca [2 x i8], align 1 + // CHECK: %[[TEMP1:.+]] = load <2 x i8>, ptr %a, align 1 + // CHECK: store <2 x i8> %[[TEMP1]], ptr %[[LOCAL]], align 1 + // CHECK: %[[TEMP2:.+]] = load <2 x i8>, ptr %[[LOCAL]], align 1 + // CHECK: store <2 x i8> %[[TEMP2]], ptr %p, align 1 + *p = *a; +} diff --git a/tests/codegen/array-optimized.rs b/tests/codegen/array-optimized.rs new file mode 100644 index 000000000000..27448fdcfade --- /dev/null +++ b/tests/codegen/array-optimized.rs @@ -0,0 +1,33 @@ +// compile-flags: -O + +#![crate_type = "lib"] + +// CHECK-LABEL: @array_copy_1_element +#[no_mangle] +pub fn array_copy_1_element(a: &[u8; 1], p: &mut [u8; 1]) { + // CHECK-NOT: alloca + // CHECK: %[[TEMP:.+]] = load i8, ptr %a, align 1 + // CHECK: store i8 %[[TEMP]], ptr %p, align 1 + // CHECK: ret + *p = *a; +} + +// CHECK-LABEL: @array_copy_2_elements +#[no_mangle] +pub fn array_copy_2_elements(a: &[u8; 2], p: &mut [u8; 2]) { + // CHECK-NOT: alloca + // CHECK: %[[TEMP:.+]] = load <2 x i8>, ptr %a, align 1 + // CHECK: store <2 x i8> %[[TEMP]], ptr %p, align 1 + // CHECK: ret + *p = *a; +} + +// CHECK-LABEL: @array_copy_4_elements +#[no_mangle] +pub fn array_copy_4_elements(a: &[u8; 4], p: &mut [u8; 4]) { + // CHECK-NOT: alloca + // CHECK: %[[TEMP:.+]] = load <4 x i8>, ptr %a, align 1 + // CHECK: store <4 x i8> %[[TEMP]], ptr %p, align 1 + // CHECK: ret + *p = *a; +} From 6b9ee90c2c49e1abf89a294ee2942efbc80aae7b Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 16 Sep 2023 14:36:23 +0000 Subject: [PATCH 10/50] Reuse determine_cgu_reuse from cg_ssa in cg_clif --- .../rustc_codegen_cranelift/src/driver/aot.rs | 30 +------------------ compiler/rustc_codegen_ssa/src/base.rs | 2 +- 2 files changed, 2 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/driver/aot.rs b/compiler/rustc_codegen_cranelift/src/driver/aot.rs index cc2f5d727146..7a94c3aaef6a 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/aot.rs +++ b/compiler/rustc_codegen_cranelift/src/driver/aot.rs @@ -8,6 +8,7 @@ use std::thread::JoinHandle; use cranelift_object::{ObjectBuilder, ObjectModule}; use rustc_codegen_ssa::back::metadata::create_compressed_metadata_file; +use rustc_codegen_ssa::base::determine_cgu_reuse; use rustc_codegen_ssa::{CodegenResults, CompiledModule, CrateInfo, ModuleKind}; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; @@ -489,32 +490,3 @@ pub(crate) fn run_aot( concurrency_limiter, }) } - -// Adapted from https://github.com/rust-lang/rust/blob/303d8aff6092709edd4dbd35b1c88e9aa40bf6d8/src/librustc_codegen_ssa/base.rs#L922-L953 -fn determine_cgu_reuse<'tcx>(tcx: TyCtxt<'tcx>, cgu: &CodegenUnit<'tcx>) -> CguReuse { - if !tcx.dep_graph.is_fully_enabled() { - return CguReuse::No; - } - - let work_product_id = &cgu.work_product_id(); - if tcx.dep_graph.previous_work_product(work_product_id).is_none() { - // We don't have anything cached for this CGU. This can happen - // if the CGU did not exist in the previous session. - return CguReuse::No; - } - - // Try to mark the CGU as green. If it we can do so, it means that nothing - // affecting the LLVM module has changed and we can re-use a cached version. - // If we compile with any kind of LTO, this means we can re-use the bitcode - // of the Pre-LTO stage (possibly also the Post-LTO version but we'll only - // know that later). If we are not doing LTO, there is only one optimized - // version of each module, so we re-use that. - let dep_node = cgu.codegen_dep_node(tcx); - assert!( - !tcx.dep_graph.dep_node_exists(&dep_node), - "CompileCodegenUnit dep-node for CGU `{}` already exists before marking.", - cgu.name() - ); - - if tcx.try_mark_green(&dep_node) { CguReuse::PostLto } else { CguReuse::No } -} diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 1e4ea73a1724..ede1dc3dfcd1 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -994,7 +994,7 @@ pub fn provide(providers: &mut Providers) { }; } -fn determine_cgu_reuse<'tcx>(tcx: TyCtxt<'tcx>, cgu: &CodegenUnit<'tcx>) -> CguReuse { +pub fn determine_cgu_reuse<'tcx>(tcx: TyCtxt<'tcx>, cgu: &CodegenUnit<'tcx>) -> CguReuse { if !tcx.dep_graph.is_fully_enabled() { return CguReuse::No; } From 3dfd9dfe7ce9bf4bcbb4d1d880cd2c75a85b310c Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 16 Sep 2023 14:36:49 +0000 Subject: [PATCH 11/50] Remove an LTO dependent cgu_reuse_tracker.set_actual_reuse call --- compiler/rustc_codegen_llvm/src/back/lto.rs | 2 -- compiler/rustc_codegen_ssa/src/back/write.rs | 4 ---- compiler/rustc_session/src/cgu_reuse_tracker.rs | 8 +------- 3 files changed, 1 insertion(+), 13 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index cb5acf79135c..8655aeec13dd 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -19,7 +19,6 @@ use rustc_hir::def_id::LOCAL_CRATE; use rustc_middle::bug; use rustc_middle::dep_graph::WorkProduct; use rustc_middle::middle::exported_symbols::{SymbolExportInfo, SymbolExportLevel}; -use rustc_session::cgu_reuse_tracker::CguReuse; use rustc_session::config::{self, CrateType, Lto}; use std::ffi::{CStr, CString}; @@ -584,7 +583,6 @@ fn thin_lto( copy_jobs.push(work_product); info!(" - {}: re-used", module_name); assert!(cgcx.incr_comp_session_dir.is_some()); - cgcx.cgu_reuse_tracker.set_actual_reuse(module_name, CguReuse::PostLto); continue; } } diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index f192747c8aba..bc4578719e50 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -26,7 +26,6 @@ use rustc_metadata::EncodedMetadata; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_middle::middle::exported_symbols::SymbolExportInfo; use rustc_middle::ty::TyCtxt; -use rustc_session::cgu_reuse_tracker::CguReuseTracker; use rustc_session::config::{self, CrateType, Lto, OutFileName, OutputFilenames, OutputType}; use rustc_session::config::{Passes, SwitchWithOptPath}; use rustc_session::Session; @@ -366,8 +365,6 @@ pub struct CodegenContext { /// The incremental compilation session directory, or None if we are not /// compiling incrementally pub incr_comp_session_dir: Option, - /// Used to update CGU re-use information during the thinlto phase. - pub cgu_reuse_tracker: CguReuseTracker, /// Channel back to the main control thread to send messages to pub coordinator_send: Sender>, } @@ -1119,7 +1116,6 @@ fn start_executing_work( remark: sess.opts.cg.remark.clone(), remark_dir, incr_comp_session_dir: sess.incr_comp_session_dir_opt().map(|r| r.clone()), - cgu_reuse_tracker: sess.cgu_reuse_tracker.clone(), coordinator_send, expanded_args: tcx.sess.expanded_args.clone(), diag_emitter: shared_emitter.clone(), diff --git a/compiler/rustc_session/src/cgu_reuse_tracker.rs b/compiler/rustc_session/src/cgu_reuse_tracker.rs index 8703e5754655..74b68fa7d352 100644 --- a/compiler/rustc_session/src/cgu_reuse_tracker.rs +++ b/compiler/rustc_session/src/cgu_reuse_tracker.rs @@ -75,13 +75,7 @@ impl CguReuseTracker { debug!("set_actual_reuse({cgu_name:?}, {kind:?})"); let prev_reuse = data.lock().unwrap().actual_reuse.insert(cgu_name.to_string(), kind); - - if let Some(prev_reuse) = prev_reuse { - // The only time it is legal to overwrite reuse state is when - // we discover during ThinLTO that we can actually reuse the - // post-LTO version of a CGU. - assert_eq!(prev_reuse, CguReuse::PreLto); - } + assert!(prev_reuse.is_none()); } } From e9fa2ca6add1db7f77c90bdc06210be694ed2571 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 19 Sep 2023 11:23:35 +0000 Subject: [PATCH 12/50] Remove cgu_reuse_tracker from Session This removes a bit of global mutable state --- Cargo.lock | 1 + .../rustc_codegen_cranelift/src/driver/aot.rs | 68 ++++---- compiler/rustc_codegen_ssa/Cargo.toml | 1 + compiler/rustc_codegen_ssa/messages.ftl | 24 +++ .../src/assert_module_sources.rs | 149 +++++++++++++++++- compiler/rustc_codegen_ssa/src/back/write.rs | 2 - compiler/rustc_codegen_ssa/src/base.rs | 10 +- compiler/rustc_codegen_ssa/src/errors.rs | 69 ++++++++ compiler/rustc_codegen_ssa/src/lib.rs | 1 + compiler/rustc_incremental/messages.ftl | 14 -- compiler/rustc_incremental/src/errors.rs | 50 ------ compiler/rustc_incremental/src/lib.rs | 1 - compiler/rustc_interface/src/passes.rs | 3 +- compiler/rustc_session/messages.ftl | 9 -- .../rustc_session/src/cgu_reuse_tracker.rs | 130 --------------- compiler/rustc_session/src/errors.rs | 19 --- compiler/rustc_session/src/lib.rs | 1 - compiler/rustc_session/src/session.rs | 11 -- 18 files changed, 284 insertions(+), 279 deletions(-) rename compiler/{rustc_incremental => rustc_codegen_ssa}/src/assert_module_sources.rs (55%) delete mode 100644 compiler/rustc_session/src/cgu_reuse_tracker.rs diff --git a/Cargo.lock b/Cargo.lock index 082bb4be93c0..1861f986d205 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3650,6 +3650,7 @@ dependencies = [ "serde_json", "smallvec", "tempfile", + "thin-vec", "thorin-dwp", "tracing", "windows", diff --git a/compiler/rustc_codegen_cranelift/src/driver/aot.rs b/compiler/rustc_codegen_cranelift/src/driver/aot.rs index 7a94c3aaef6a..aaead1ffc5fd 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/aot.rs +++ b/compiler/rustc_codegen_cranelift/src/driver/aot.rs @@ -7,6 +7,7 @@ use std::sync::Arc; use std::thread::JoinHandle; use cranelift_object::{ObjectBuilder, ObjectModule}; +use rustc_codegen_ssa::assert_module_sources::CguReuse; use rustc_codegen_ssa::back::metadata::create_compressed_metadata_file; use rustc_codegen_ssa::base::determine_cgu_reuse; use rustc_codegen_ssa::{CodegenResults, CompiledModule, CrateInfo, ModuleKind}; @@ -15,7 +16,6 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_metadata::EncodedMetadata; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_middle::mir::mono::{CodegenUnit, MonoItem}; -use rustc_session::cgu_reuse_tracker::CguReuse; use rustc_session::config::{DebugInfo, OutputFilenames, OutputType}; use rustc_session::Session; @@ -375,43 +375,47 @@ pub(crate) fn run_aot( } } + // Calculate the CGU reuse + let cgu_reuse = tcx.sess.time("find_cgu_reuse", || { + cgus.iter().map(|cgu| determine_cgu_reuse(tcx, &cgu)).collect::>() + }); + + rustc_codegen_ssa::assert_module_sources::assert_module_sources(tcx, &|cgu_reuse_tracker| { + for (i, cgu) in cgus.iter().enumerate() { + let cgu_reuse = cgu_reuse[i]; + cgu_reuse_tracker.set_actual_reuse(cgu.name().as_str(), cgu_reuse); + } + }); + let global_asm_config = Arc::new(crate::global_asm::GlobalAsmConfig::new(tcx)); let mut concurrency_limiter = ConcurrencyLimiter::new(tcx.sess, cgus.len()); let modules = tcx.sess.time("codegen mono items", || { cgus.iter() - .map(|cgu| { - let cgu_reuse = if backend_config.disable_incr_cache { - CguReuse::No - } else { - determine_cgu_reuse(tcx, cgu) - }; - tcx.sess.cgu_reuse_tracker.set_actual_reuse(cgu.name().as_str(), cgu_reuse); - - match cgu_reuse { - CguReuse::No => { - let dep_node = cgu.codegen_dep_node(tcx); - tcx.dep_graph - .with_task( - dep_node, - tcx, - ( - backend_config.clone(), - global_asm_config.clone(), - cgu.name(), - concurrency_limiter.acquire(tcx.sess.diagnostic()), - ), - module_codegen, - Some(rustc_middle::dep_graph::hash_result), - ) - .0 - } - CguReuse::PreLto => unreachable!(), - CguReuse::PostLto => { - concurrency_limiter.job_already_done(); - OngoingModuleCodegen::Sync(reuse_workproduct_for_cgu(tcx, cgu)) - } + .enumerate() + .map(|(i, cgu)| match cgu_reuse[i] { + CguReuse::No => { + let dep_node = cgu.codegen_dep_node(tcx); + tcx.dep_graph + .with_task( + dep_node, + tcx, + ( + backend_config.clone(), + global_asm_config.clone(), + cgu.name(), + concurrency_limiter.acquire(tcx.sess.diagnostic()), + ), + module_codegen, + Some(rustc_middle::dep_graph::hash_result), + ) + .0 + } + CguReuse::PreLto => unreachable!(), + CguReuse::PostLto => { + concurrency_limiter.job_already_done(); + OngoingModuleCodegen::Sync(reuse_workproduct_for_cgu(tcx, cgu)) } }) .collect::>() diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml index 34d0e2d1df66..454e2f806763 100644 --- a/compiler/rustc_codegen_ssa/Cargo.toml +++ b/compiler/rustc_codegen_ssa/Cargo.toml @@ -16,6 +16,7 @@ pathdiff = "0.2.0" serde_json = "1.0.59" smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } regex = "1.4" +thin-vec = "0.2.12" rustc_serialize = { path = "../rustc_serialize" } rustc_arena = { path = "../rustc_arena" } diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl index 664826673361..5881c6236ece 100644 --- a/compiler/rustc_codegen_ssa/messages.ftl +++ b/compiler/rustc_codegen_ssa/messages.ftl @@ -11,6 +11,9 @@ codegen_ssa_atomic_compare_exchange = Atomic compare-exchange intrinsic missing codegen_ssa_binary_output_to_tty = option `-o` or `--emit` is used to write binary output type `{$shorthand}` to stdout, but stdout is a tty +codegen_ssa_cgu_not_recorded = + CGU-reuse for `{$cgu_user_name}` is (mangled: `{$cgu_name}`) was not recorded + codegen_ssa_check_installed_visual_studio = please ensure that Visual Studio 2017 or later, or Build Tools for Visual Studio were installed with the Visual C++ option. codegen_ssa_copy_path = could not copy {$from} to {$to}: {$error} @@ -39,6 +42,8 @@ codegen_ssa_failed_to_get_layout = failed to get layout for {$ty}: {$err} codegen_ssa_failed_to_write = failed to write {$path}: {$error} +codegen_ssa_field_associated_value_expected = associated value expected for `{$name}` + codegen_ssa_ignoring_emit_path = ignoring emit path because multiple .{$extension} files were produced codegen_ssa_ignoring_output = ignoring -o because multiple .{$extension} files were produced @@ -46,6 +51,12 @@ codegen_ssa_ignoring_output = ignoring -o because multiple .{$extension} files w codegen_ssa_illegal_link_ordinal_format = illegal ordinal format in `link_ordinal` .note = an unsuffixed integer value, e.g., `1`, is expected +codegen_ssa_incorrect_cgu_reuse_type = + CGU-reuse for `{$cgu_user_name}` is `{$actual_reuse}` but should be {$at_least -> + [one] {"at least "} + *[other] {""} + }`{$expected_reuse}` + codegen_ssa_insufficient_vs_code_product = VS Code is a different product, and is not sufficient. codegen_ssa_invalid_link_ordinal_nargs = incorrect number of arguments to `#[link_ordinal]` @@ -153,12 +164,18 @@ codegen_ssa_linker_unsupported_modifier = `as-needed` modifier not supported for codegen_ssa_linking_failed = linking with `{$linker_path}` failed: {$exit_status} +codegen_ssa_malformed_cgu_name = + found malformed codegen unit name `{$user_path}`. codegen units names must always start with the name of the crate (`{$crate_name}` in this case). + codegen_ssa_metadata_object_file_write = error writing metadata object file: {$error} codegen_ssa_missing_cpp_build_tool_component = or a necessary component may be missing from the "C++ build tools" workload codegen_ssa_missing_memory_ordering = Atomic intrinsic missing memory ordering +codegen_ssa_missing_query_depgraph = + found CGU-reuse attribute but `-Zquery-dep-graph` was not specified + codegen_ssa_msvc_missing_linker = the msvc targets depend on the msvc linker but `link.exe` was not found codegen_ssa_multiple_external_func_decl = multiple declarations of external function `{$function}` from library `{$library_name}` have different calling conventions @@ -166,6 +183,11 @@ codegen_ssa_multiple_external_func_decl = multiple declarations of external func codegen_ssa_multiple_main_functions = entry symbol `main` declared multiple times .help = did you use `#[no_mangle]` on `fn main`? Use `#[start]` instead +codegen_ssa_no_field = no field `{$name}` + +codegen_ssa_no_module_named = + no module named `{$user_path}` (mangled: {$cgu_name}). available modules: {$cgu_names} + codegen_ssa_no_natvis_directory = error enumerating natvis directory: {$error} codegen_ssa_processing_dymutil_failed = processing debug info with `dsymutil` failed: {$status} @@ -297,6 +319,8 @@ codegen_ssa_unknown_atomic_operation = unknown atomic operation codegen_ssa_unknown_atomic_ordering = unknown ordering in atomic intrinsic +codegen_ssa_unknown_reuse_kind = unknown cgu-reuse-kind `{$kind}` specified + codegen_ssa_unsupported_arch = unsupported arch `{$arch}` for os `{$os}` codegen_ssa_unsupported_link_self_contained = option `-C link-self-contained` is not supported on this target diff --git a/compiler/rustc_incremental/src/assert_module_sources.rs b/compiler/rustc_codegen_ssa/src/assert_module_sources.rs similarity index 55% rename from compiler/rustc_incremental/src/assert_module_sources.rs rename to compiler/rustc_codegen_ssa/src/assert_module_sources.rs index 8e22ab4083ee..a5a16a929ae1 100644 --- a/compiler/rustc_incremental/src/assert_module_sources.rs +++ b/compiler/rustc_codegen_ssa/src/assert_module_sources.rs @@ -25,16 +25,22 @@ use crate::errors; use rustc_ast as ast; +use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::unord::UnordSet; +use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg}; use rustc_hir::def_id::LOCAL_CRATE; use rustc_middle::mir::mono::CodegenUnitNameBuilder; use rustc_middle::ty::TyCtxt; -use rustc_session::cgu_reuse_tracker::*; -use rustc_span::symbol::{sym, Symbol}; +use rustc_session::Session; +use rustc_span::symbol::sym; +use rustc_span::{Span, Symbol}; +use std::borrow::Cow; +use std::fmt::{self}; +use std::sync::{Arc, Mutex}; use thin_vec::ThinVec; #[allow(missing_docs)] -pub fn assert_module_sources(tcx: TyCtxt<'_>) { +pub fn assert_module_sources(tcx: TyCtxt<'_>, set_reuse: &dyn Fn(&CguReuseTracker)) { tcx.dep_graph.with_ignore(|| { if tcx.sess.opts.incremental.is_none() { return; @@ -43,17 +49,30 @@ pub fn assert_module_sources(tcx: TyCtxt<'_>) { let available_cgus = tcx.collect_and_partition_mono_items(()).1.iter().map(|cgu| cgu.name()).collect(); - let ams = AssertModuleSource { tcx, available_cgus }; + let ams = AssertModuleSource { + tcx, + available_cgus, + cgu_reuse_tracker: if tcx.sess.opts.unstable_opts.query_dep_graph { + CguReuseTracker::new() + } else { + CguReuseTracker::new_disabled() + }, + }; for attr in tcx.hir().attrs(rustc_hir::CRATE_HIR_ID) { ams.check_attr(attr); } - }) + + set_reuse(&ams.cgu_reuse_tracker); + + ams.cgu_reuse_tracker.check_expected_reuse(tcx.sess); + }); } struct AssertModuleSource<'tcx> { tcx: TyCtxt<'tcx>, available_cgus: UnordSet, + cgu_reuse_tracker: CguReuseTracker, } impl<'tcx> AssertModuleSource<'tcx> { @@ -129,7 +148,7 @@ impl<'tcx> AssertModuleSource<'tcx> { }); } - self.tcx.sess.cgu_reuse_tracker.set_expectation( + self.cgu_reuse_tracker.set_expectation( cgu_name, &user_path, attr.span, @@ -169,3 +188,121 @@ impl<'tcx> AssertModuleSource<'tcx> { false } } + +#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)] +pub enum CguReuse { + No, + PreLto, + PostLto, +} + +impl fmt::Display for CguReuse { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match *self { + CguReuse::No => write!(f, "No"), + CguReuse::PreLto => write!(f, "PreLto "), + CguReuse::PostLto => write!(f, "PostLto "), + } + } +} + +impl IntoDiagnosticArg for CguReuse { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + DiagnosticArgValue::Str(Cow::Owned(self.to_string())) + } +} + +#[derive(Copy, Clone, Debug, PartialEq)] +pub enum ComparisonKind { + Exact, + AtLeast, +} + +struct TrackerData { + actual_reuse: FxHashMap, + expected_reuse: FxHashMap, +} + +// Span does not implement `Send`, so we can't just store it in the shared +// `TrackerData` object. Instead of splitting up `TrackerData` into shared and +// non-shared parts (which would be complicated), we just mark the `Span` here +// explicitly as `Send`. That's safe because the span data here is only ever +// accessed from the main thread. +struct SendSpan(Span); +unsafe impl Send for SendSpan {} + +#[derive(Clone)] +pub struct CguReuseTracker { + data: Option>>, +} + +impl CguReuseTracker { + pub fn new() -> CguReuseTracker { + let data = + TrackerData { actual_reuse: Default::default(), expected_reuse: Default::default() }; + + CguReuseTracker { data: Some(Arc::new(Mutex::new(data))) } + } + + pub fn new_disabled() -> CguReuseTracker { + CguReuseTracker { data: None } + } + + pub fn set_actual_reuse(&self, cgu_name: &str, kind: CguReuse) { + if let Some(ref data) = self.data { + debug!("set_actual_reuse({cgu_name:?}, {kind:?})"); + + let prev_reuse = data.lock().unwrap().actual_reuse.insert(cgu_name.to_string(), kind); + assert!(prev_reuse.is_none()); + } + } + + pub fn set_expectation( + &self, + cgu_name: Symbol, + cgu_user_name: &str, + error_span: Span, + expected_reuse: CguReuse, + comparison_kind: ComparisonKind, + ) { + if let Some(ref data) = self.data { + debug!("set_expectation({cgu_name:?}, {expected_reuse:?}, {comparison_kind:?})"); + let mut data = data.lock().unwrap(); + + data.expected_reuse.insert( + cgu_name.to_string(), + (cgu_user_name.to_string(), SendSpan(error_span), expected_reuse, comparison_kind), + ); + } + } + + pub fn check_expected_reuse(&self, sess: &Session) { + if let Some(ref data) = self.data { + let data = data.lock().unwrap(); + + for (cgu_name, &(ref cgu_user_name, ref error_span, expected_reuse, comparison_kind)) in + &data.expected_reuse + { + if let Some(&actual_reuse) = data.actual_reuse.get(cgu_name) { + let (error, at_least) = match comparison_kind { + ComparisonKind::Exact => (expected_reuse != actual_reuse, false), + ComparisonKind::AtLeast => (actual_reuse < expected_reuse, true), + }; + + if error { + let at_least = if at_least { 1 } else { 0 }; + errors::IncorrectCguReuseType { + span: error_span.0, + cgu_user_name, + actual_reuse, + expected_reuse, + at_least, + }; + } + } else { + sess.emit_fatal(errors::CguNotRecorded { cgu_user_name, cgu_name }); + } + } + } + } +} diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index bc4578719e50..3d6a21243346 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -1965,8 +1965,6 @@ impl OngoingCodegen { } }); - sess.cgu_reuse_tracker.check_expected_reuse(sess); - sess.abort_if_errors(); let work_products = diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index ede1dc3dfcd1..198e5696357a 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -1,3 +1,4 @@ +use crate::assert_module_sources::CguReuse; use crate::back::link::are_upstream_rust_objects_already_included; use crate::back::metadata::create_compressed_metadata_file; use crate::back::write::{ @@ -31,7 +32,6 @@ use rustc_middle::mir::mono::{CodegenUnit, CodegenUnitNameBuilder, MonoItem}; use rustc_middle::query::Providers; use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout}; use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; -use rustc_session::cgu_reuse_tracker::CguReuse; use rustc_session::config::{self, CrateType, EntryFnType, OutputType}; use rustc_session::Session; use rustc_span::symbol::sym; @@ -683,6 +683,13 @@ pub fn codegen_crate( codegen_units.iter().map(|cgu| determine_cgu_reuse(tcx, &cgu)).collect::>() }); + crate::assert_module_sources::assert_module_sources(tcx, &|cgu_reuse_tracker| { + for (i, cgu) in codegen_units.iter().enumerate() { + let cgu_reuse = cgu_reuse[i]; + cgu_reuse_tracker.set_actual_reuse(cgu.name().as_str(), cgu_reuse); + } + }); + let mut total_codegen_time = Duration::new(0, 0); let start_rss = tcx.sess.opts.unstable_opts.time_passes.then(|| get_resident_set_size()); @@ -727,7 +734,6 @@ pub fn codegen_crate( ongoing_codegen.check_for_errors(tcx.sess); let cgu_reuse = cgu_reuse[i]; - tcx.sess.cgu_reuse_tracker.set_actual_reuse(cgu.name().as_str(), cgu_reuse); match cgu_reuse { CguReuse::No => { diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index 39b2fa37fbf8..ed6ac9f9c5da 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -1,5 +1,6 @@ //! Errors emitted by codegen_ssa +use crate::assert_module_sources::CguReuse; use crate::back::command::Command; use crate::fluent_generated as fluent; use rustc_errors::{ @@ -16,6 +17,74 @@ use std::io::Error; use std::path::{Path, PathBuf}; use std::process::ExitStatus; +#[derive(Diagnostic)] +#[diag(codegen_ssa_incorrect_cgu_reuse_type)] +pub struct IncorrectCguReuseType<'a> { + #[primary_span] + pub span: Span, + pub cgu_user_name: &'a str, + pub actual_reuse: CguReuse, + pub expected_reuse: CguReuse, + pub at_least: u8, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_cgu_not_recorded)] +pub struct CguNotRecorded<'a> { + pub cgu_user_name: &'a str, + pub cgu_name: &'a str, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_unknown_reuse_kind)] +pub struct UnknownReuseKind { + #[primary_span] + pub span: Span, + pub kind: Symbol, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_missing_query_depgraph)] +pub struct MissingQueryDepGraph { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_malformed_cgu_name)] +pub struct MalformedCguName { + #[primary_span] + pub span: Span, + pub user_path: String, + pub crate_name: String, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_no_module_named)] +pub struct NoModuleNamed<'a> { + #[primary_span] + pub span: Span, + pub user_path: &'a str, + pub cgu_name: Symbol, + pub cgu_names: String, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_field_associated_value_expected)] +pub struct FieldAssociatedValueExpected { + #[primary_span] + pub span: Span, + pub name: Symbol, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_no_field)] +pub struct NoField { + #[primary_span] + pub span: Span, + pub name: Symbol, +} + #[derive(Diagnostic)] #[diag(codegen_ssa_lib_def_write_failure)] pub struct LibDefWriteFailure { diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index f6186a290f81..008da2a7ce07 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -43,6 +43,7 @@ use std::collections::BTreeSet; use std::io; use std::path::{Path, PathBuf}; +pub mod assert_module_sources; pub mod back; pub mod base; pub mod codegen_attrs; diff --git a/compiler/rustc_incremental/messages.ftl b/compiler/rustc_incremental/messages.ftl index 9fa4e0fb27cf..5d885e07192d 100644 --- a/compiler/rustc_incremental/messages.ftl +++ b/compiler/rustc_incremental/messages.ftl @@ -46,8 +46,6 @@ incremental_delete_partial = failed to delete partly initialized session dir `{$ incremental_delete_workproduct = file-system error deleting outdated file `{$path}`: {$err} -incremental_field_associated_value_expected = associated value expected for `{$name}` - incremental_finalize = error finalizing incremental compilation session directory `{$path}`: {$err} incremental_finalized_gc_failed = @@ -63,25 +61,15 @@ incremental_load_dep_graph = could not load dep-graph from `{$path}`: {$err} incremental_lock_unsupported = the filesystem for the incremental path at {$session_dir} does not appear to support locking, consider changing the incremental path to a filesystem that supports locking or disable incremental compilation -incremental_malformed_cgu_name = - found malformed codegen unit name `{$user_path}`. codegen units names must always start with the name of the crate (`{$crate_name}` in this case). incremental_missing_depnode = missing `DepNode` variant incremental_missing_if_this_changed = no `#[rustc_if_this_changed]` annotation detected -incremental_missing_query_depgraph = - found CGU-reuse attribute but `-Zquery-dep-graph` was not specified - incremental_move_dep_graph = failed to move dependency graph from `{$from}` to `{$to}`: {$err} incremental_no_cfg = no cfg attribute -incremental_no_field = no field `{$name}` - -incremental_no_module_named = - no module named `{$user_path}` (mangled: {$cgu_name}). available modules: {$cgu_names} - incremental_no_path = no path from `{$source}` to `{$target}` incremental_not_clean = `{$dep_node_str}` should be clean but is not @@ -107,8 +95,6 @@ incremental_undefined_clean_dirty_assertions_item = incremental_unknown_item = unknown item `{$name}` -incremental_unknown_reuse_kind = unknown cgu-reuse-kind `{$kind}` specified - incremental_unrecognized_depnode = unrecognized `DepNode` variant: {$name} incremental_unrecognized_depnode_label = dep-node label `{$label}` not recognized diff --git a/compiler/rustc_incremental/src/errors.rs b/compiler/rustc_incremental/src/errors.rs index deb876783654..05ed4f7598d4 100644 --- a/compiler/rustc_incremental/src/errors.rs +++ b/compiler/rustc_incremental/src/errors.rs @@ -40,56 +40,6 @@ pub struct NoPath { pub source: String, } -#[derive(Diagnostic)] -#[diag(incremental_unknown_reuse_kind)] -pub struct UnknownReuseKind { - #[primary_span] - pub span: Span, - pub kind: Symbol, -} - -#[derive(Diagnostic)] -#[diag(incremental_missing_query_depgraph)] -pub struct MissingQueryDepGraph { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(incremental_malformed_cgu_name)] -pub struct MalformedCguName { - #[primary_span] - pub span: Span, - pub user_path: String, - pub crate_name: String, -} - -#[derive(Diagnostic)] -#[diag(incremental_no_module_named)] -pub struct NoModuleNamed<'a> { - #[primary_span] - pub span: Span, - pub user_path: &'a str, - pub cgu_name: Symbol, - pub cgu_names: String, -} - -#[derive(Diagnostic)] -#[diag(incremental_field_associated_value_expected)] -pub struct FieldAssociatedValueExpected { - #[primary_span] - pub span: Span, - pub name: Symbol, -} - -#[derive(Diagnostic)] -#[diag(incremental_no_field)] -pub struct NoField { - #[primary_span] - pub span: Span, - pub name: Symbol, -} - #[derive(Diagnostic)] #[diag(incremental_assertion_auto)] pub struct AssertionAuto<'a> { diff --git a/compiler/rustc_incremental/src/lib.rs b/compiler/rustc_incremental/src/lib.rs index 220ea194a6de..e4050099fc12 100644 --- a/compiler/rustc_incremental/src/lib.rs +++ b/compiler/rustc_incremental/src/lib.rs @@ -13,7 +13,6 @@ extern crate rustc_middle; extern crate tracing; mod assert_dep_graph; -pub mod assert_module_sources; mod errors; mod persist; diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 0e8f93cef173..718dbaaafcce 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -957,10 +957,9 @@ pub fn start_codegen<'tcx>( codegen_backend.codegen_crate(tcx, metadata, need_metadata_module) }); - // Don't run these test assertions when not doing codegen. Compiletest tries to build + // Don't run this test assertions when not doing codegen. Compiletest tries to build // build-fail tests in check mode first and expects it to not give an error in that case. if tcx.sess.opts.output_types.should_codegen() { - rustc_incremental::assert_module_sources::assert_module_sources(tcx); rustc_symbol_mangling::test::report_symbol_names(tcx); } diff --git a/compiler/rustc_session/messages.ftl b/compiler/rustc_session/messages.ftl index b356b503aa54..fa1b6f9f13d6 100644 --- a/compiler/rustc_session/messages.ftl +++ b/compiler/rustc_session/messages.ftl @@ -5,9 +5,6 @@ session_cannot_enable_crt_static_linux = sanitizer is incompatible with statical session_cannot_mix_and_match_sanitizers = `-Zsanitizer={$first}` is incompatible with `-Zsanitizer={$second}` -session_cgu_not_recorded = - CGU-reuse for `{$cgu_user_name}` is (mangled: `{$cgu_name}`) was not recorded - session_cli_feature_diagnostic_help = add `-Zcrate-attr="feature({$feature})"` to the command-line options to enable @@ -34,12 +31,6 @@ session_hexadecimal_float_literal_not_supported = hexadecimal float literal is n session_incompatible_linker_flavor = linker flavor `{$flavor}` is incompatible with the current target .note = compatible flavors are: {$compatible_list} -session_incorrect_cgu_reuse_type = - CGU-reuse for `{$cgu_user_name}` is `{$actual_reuse}` but should be {$at_least -> - [one] {"at least "} - *[other] {""} - }`{$expected_reuse}` - session_instrumentation_not_supported = {$us} instrumentation is not supported for this target session_int_literal_too_large = integer literal is too large diff --git a/compiler/rustc_session/src/cgu_reuse_tracker.rs b/compiler/rustc_session/src/cgu_reuse_tracker.rs deleted file mode 100644 index 74b68fa7d352..000000000000 --- a/compiler/rustc_session/src/cgu_reuse_tracker.rs +++ /dev/null @@ -1,130 +0,0 @@ -//! Some facilities for tracking how codegen-units are reused during incremental -//! compilation. This is used for incremental compilation tests and debug -//! output. - -use crate::errors::{CguNotRecorded, IncorrectCguReuseType}; -use crate::Session; -use rustc_data_structures::fx::FxHashMap; -use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg}; -use rustc_span::{Span, Symbol}; -use std::borrow::Cow; -use std::fmt::{self}; -use std::sync::{Arc, Mutex}; - -#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)] -pub enum CguReuse { - No, - PreLto, - PostLto, -} - -impl fmt::Display for CguReuse { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match *self { - CguReuse::No => write!(f, "No"), - CguReuse::PreLto => write!(f, "PreLto "), - CguReuse::PostLto => write!(f, "PostLto "), - } - } -} - -impl IntoDiagnosticArg for CguReuse { - fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { - DiagnosticArgValue::Str(Cow::Owned(self.to_string())) - } -} - -#[derive(Copy, Clone, Debug, PartialEq)] -pub enum ComparisonKind { - Exact, - AtLeast, -} - -struct TrackerData { - actual_reuse: FxHashMap, - expected_reuse: FxHashMap, -} - -// Span does not implement `Send`, so we can't just store it in the shared -// `TrackerData` object. Instead of splitting up `TrackerData` into shared and -// non-shared parts (which would be complicated), we just mark the `Span` here -// explicitly as `Send`. That's safe because the span data here is only ever -// accessed from the main thread. -struct SendSpan(Span); -unsafe impl Send for SendSpan {} - -#[derive(Clone)] -pub struct CguReuseTracker { - data: Option>>, -} - -impl CguReuseTracker { - pub fn new() -> CguReuseTracker { - let data = - TrackerData { actual_reuse: Default::default(), expected_reuse: Default::default() }; - - CguReuseTracker { data: Some(Arc::new(Mutex::new(data))) } - } - - pub fn new_disabled() -> CguReuseTracker { - CguReuseTracker { data: None } - } - - pub fn set_actual_reuse(&self, cgu_name: &str, kind: CguReuse) { - if let Some(ref data) = self.data { - debug!("set_actual_reuse({cgu_name:?}, {kind:?})"); - - let prev_reuse = data.lock().unwrap().actual_reuse.insert(cgu_name.to_string(), kind); - assert!(prev_reuse.is_none()); - } - } - - pub fn set_expectation( - &self, - cgu_name: Symbol, - cgu_user_name: &str, - error_span: Span, - expected_reuse: CguReuse, - comparison_kind: ComparisonKind, - ) { - if let Some(ref data) = self.data { - debug!("set_expectation({cgu_name:?}, {expected_reuse:?}, {comparison_kind:?})"); - let mut data = data.lock().unwrap(); - - data.expected_reuse.insert( - cgu_name.to_string(), - (cgu_user_name.to_string(), SendSpan(error_span), expected_reuse, comparison_kind), - ); - } - } - - pub fn check_expected_reuse(&self, sess: &Session) { - if let Some(ref data) = self.data { - let data = data.lock().unwrap(); - - for (cgu_name, &(ref cgu_user_name, ref error_span, expected_reuse, comparison_kind)) in - &data.expected_reuse - { - if let Some(&actual_reuse) = data.actual_reuse.get(cgu_name) { - let (error, at_least) = match comparison_kind { - ComparisonKind::Exact => (expected_reuse != actual_reuse, false), - ComparisonKind::AtLeast => (actual_reuse < expected_reuse, true), - }; - - if error { - let at_least = if at_least { 1 } else { 0 }; - IncorrectCguReuseType { - span: error_span.0, - cgu_user_name, - actual_reuse, - expected_reuse, - at_least, - }; - } - } else { - sess.emit_fatal(CguNotRecorded { cgu_user_name, cgu_name }); - } - } - } - } -} diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs index 5f8bbfca8908..31094e0d2666 100644 --- a/compiler/rustc_session/src/errors.rs +++ b/compiler/rustc_session/src/errors.rs @@ -1,6 +1,5 @@ use std::num::NonZeroU32; -use crate::cgu_reuse_tracker::CguReuse; use crate::parse::ParseSess; use rustc_ast::token; use rustc_ast::util::literal::LitError; @@ -9,24 +8,6 @@ use rustc_macros::Diagnostic; use rustc_span::{BytePos, Span, Symbol}; use rustc_target::spec::{SplitDebuginfo, StackProtector, TargetTriple}; -#[derive(Diagnostic)] -#[diag(session_incorrect_cgu_reuse_type)] -pub struct IncorrectCguReuseType<'a> { - #[primary_span] - pub span: Span, - pub cgu_user_name: &'a str, - pub actual_reuse: CguReuse, - pub expected_reuse: CguReuse, - pub at_least: u8, -} - -#[derive(Diagnostic)] -#[diag(session_cgu_not_recorded)] -pub struct CguNotRecorded<'a> { - pub cgu_user_name: &'a str, - pub cgu_name: &'a str, -} - pub struct FeatureGateError { pub span: MultiSpan, pub explain: DiagnosticMessage, diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs index d6c746a7bd85..66a5092ccd49 100644 --- a/compiler/rustc_session/src/lib.rs +++ b/compiler/rustc_session/src/lib.rs @@ -22,7 +22,6 @@ extern crate tracing; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; use rustc_fluent_macro::fluent_messages; -pub mod cgu_reuse_tracker; pub mod utils; pub use lint::{declare_lint, declare_lint_pass, declare_tool_lint, impl_lint_pass}; pub use rustc_lint_defs as lint; diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index b484978eed23..5cac11cc8f78 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1,4 +1,3 @@ -use crate::cgu_reuse_tracker::CguReuseTracker; use crate::code_stats::CodeStats; pub use crate::code_stats::{DataTypeKind, FieldInfo, FieldKind, SizeKind, VariantInfo}; use crate::config::{ @@ -153,9 +152,6 @@ pub struct Session { pub io: CompilerIO, incr_comp_session: OneThread>, - /// Used for incremental compilation tests. Will only be populated if - /// `-Zquery-dep-graph` is specified. - pub cgu_reuse_tracker: CguReuseTracker, /// Used by `-Z self-profile`. pub prof: SelfProfilerRef, @@ -1431,12 +1427,6 @@ pub fn build_session( }); let print_fuel = AtomicU64::new(0); - let cgu_reuse_tracker = if sopts.unstable_opts.query_dep_graph { - CguReuseTracker::new() - } else { - CguReuseTracker::new_disabled() - }; - let prof = SelfProfilerRef::new( self_profiler, sopts.unstable_opts.time_passes.then(|| sopts.unstable_opts.time_passes_format), @@ -1461,7 +1451,6 @@ pub fn build_session( sysroot, io, incr_comp_session: OneThread::new(RefCell::new(IncrCompSession::NotInitialized)), - cgu_reuse_tracker, prof, perf_stats: PerfStats { symbol_hash_time: Lock::new(Duration::from_secs(0)), From 7f5af72e64ec08addd1398c7b809f149f5ff57c5 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 19 Sep 2023 11:26:46 +0000 Subject: [PATCH 13/50] Remove interior mutability from CguReuseTracker --- .../src/assert_module_sources.rs | 43 +++++++------------ 1 file changed, 15 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/assert_module_sources.rs b/compiler/rustc_codegen_ssa/src/assert_module_sources.rs index a5a16a929ae1..27873dd2e1ab 100644 --- a/compiler/rustc_codegen_ssa/src/assert_module_sources.rs +++ b/compiler/rustc_codegen_ssa/src/assert_module_sources.rs @@ -35,12 +35,11 @@ use rustc_session::Session; use rustc_span::symbol::sym; use rustc_span::{Span, Symbol}; use std::borrow::Cow; -use std::fmt::{self}; -use std::sync::{Arc, Mutex}; +use std::fmt; use thin_vec::ThinVec; #[allow(missing_docs)] -pub fn assert_module_sources(tcx: TyCtxt<'_>, set_reuse: &dyn Fn(&CguReuseTracker)) { +pub fn assert_module_sources(tcx: TyCtxt<'_>, set_reuse: &dyn Fn(&mut CguReuseTracker)) { tcx.dep_graph.with_ignore(|| { if tcx.sess.opts.incremental.is_none() { return; @@ -49,7 +48,7 @@ pub fn assert_module_sources(tcx: TyCtxt<'_>, set_reuse: &dyn Fn(&CguReuseTracke let available_cgus = tcx.collect_and_partition_mono_items(()).1.iter().map(|cgu| cgu.name()).collect(); - let ams = AssertModuleSource { + let mut ams = AssertModuleSource { tcx, available_cgus, cgu_reuse_tracker: if tcx.sess.opts.unstable_opts.query_dep_graph { @@ -63,7 +62,7 @@ pub fn assert_module_sources(tcx: TyCtxt<'_>, set_reuse: &dyn Fn(&CguReuseTracke ams.check_attr(attr); } - set_reuse(&ams.cgu_reuse_tracker); + set_reuse(&mut ams.cgu_reuse_tracker); ams.cgu_reuse_tracker.check_expected_reuse(tcx.sess); }); @@ -76,7 +75,7 @@ struct AssertModuleSource<'tcx> { } impl<'tcx> AssertModuleSource<'tcx> { - fn check_attr(&self, attr: &ast::Attribute) { + fn check_attr(&mut self, attr: &ast::Attribute) { let (expected_reuse, comp_kind) = if attr.has_name(sym::rustc_partition_reused) { (CguReuse::PreLto, ComparisonKind::AtLeast) } else if attr.has_name(sym::rustc_partition_codegened) { @@ -220,20 +219,11 @@ pub enum ComparisonKind { struct TrackerData { actual_reuse: FxHashMap, - expected_reuse: FxHashMap, + expected_reuse: FxHashMap, } -// Span does not implement `Send`, so we can't just store it in the shared -// `TrackerData` object. Instead of splitting up `TrackerData` into shared and -// non-shared parts (which would be complicated), we just mark the `Span` here -// explicitly as `Send`. That's safe because the span data here is only ever -// accessed from the main thread. -struct SendSpan(Span); -unsafe impl Send for SendSpan {} - -#[derive(Clone)] pub struct CguReuseTracker { - data: Option>>, + data: Option, } impl CguReuseTracker { @@ -241,45 +231,42 @@ impl CguReuseTracker { let data = TrackerData { actual_reuse: Default::default(), expected_reuse: Default::default() }; - CguReuseTracker { data: Some(Arc::new(Mutex::new(data))) } + CguReuseTracker { data: Some(data) } } pub fn new_disabled() -> CguReuseTracker { CguReuseTracker { data: None } } - pub fn set_actual_reuse(&self, cgu_name: &str, kind: CguReuse) { - if let Some(ref data) = self.data { + pub fn set_actual_reuse(&mut self, cgu_name: &str, kind: CguReuse) { + if let Some(data) = &mut self.data { debug!("set_actual_reuse({cgu_name:?}, {kind:?})"); - let prev_reuse = data.lock().unwrap().actual_reuse.insert(cgu_name.to_string(), kind); + let prev_reuse = data.actual_reuse.insert(cgu_name.to_string(), kind); assert!(prev_reuse.is_none()); } } pub fn set_expectation( - &self, + &mut self, cgu_name: Symbol, cgu_user_name: &str, error_span: Span, expected_reuse: CguReuse, comparison_kind: ComparisonKind, ) { - if let Some(ref data) = self.data { + if let Some(data) = &mut self.data { debug!("set_expectation({cgu_name:?}, {expected_reuse:?}, {comparison_kind:?})"); - let mut data = data.lock().unwrap(); data.expected_reuse.insert( cgu_name.to_string(), - (cgu_user_name.to_string(), SendSpan(error_span), expected_reuse, comparison_kind), + (cgu_user_name.to_string(), error_span, expected_reuse, comparison_kind), ); } } pub fn check_expected_reuse(&self, sess: &Session) { if let Some(ref data) = self.data { - let data = data.lock().unwrap(); - for (cgu_name, &(ref cgu_user_name, ref error_span, expected_reuse, comparison_kind)) in &data.expected_reuse { @@ -292,7 +279,7 @@ impl CguReuseTracker { if error { let at_least = if at_least { 1 } else { 0 }; errors::IncorrectCguReuseType { - span: error_span.0, + span: *error_span, cgu_user_name, actual_reuse, expected_reuse, From f0b5820fa5b29d840e700ee5d760b55d291311c3 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 5 Oct 2023 09:49:10 +0000 Subject: [PATCH 14/50] Fix review comments --- compiler/rustc_codegen_cranelift/src/driver/aot.rs | 2 +- compiler/rustc_codegen_ssa/src/assert_module_sources.rs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/driver/aot.rs b/compiler/rustc_codegen_cranelift/src/driver/aot.rs index aaead1ffc5fd..49f51f9f956b 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/aot.rs +++ b/compiler/rustc_codegen_cranelift/src/driver/aot.rs @@ -412,7 +412,7 @@ pub(crate) fn run_aot( ) .0 } - CguReuse::PreLto => unreachable!(), + CguReuse::PreLto => unreachable!("LTO not yet supported"), CguReuse::PostLto => { concurrency_limiter.job_already_done(); OngoingModuleCodegen::Sync(reuse_workproduct_for_cgu(tcx, cgu)) diff --git a/compiler/rustc_codegen_ssa/src/assert_module_sources.rs b/compiler/rustc_codegen_ssa/src/assert_module_sources.rs index 27873dd2e1ab..16bb7b12bd3c 100644 --- a/compiler/rustc_codegen_ssa/src/assert_module_sources.rs +++ b/compiler/rustc_codegen_ssa/src/assert_module_sources.rs @@ -227,14 +227,14 @@ pub struct CguReuseTracker { } impl CguReuseTracker { - pub fn new() -> CguReuseTracker { + fn new() -> CguReuseTracker { let data = TrackerData { actual_reuse: Default::default(), expected_reuse: Default::default() }; CguReuseTracker { data: Some(data) } } - pub fn new_disabled() -> CguReuseTracker { + fn new_disabled() -> CguReuseTracker { CguReuseTracker { data: None } } @@ -247,7 +247,7 @@ impl CguReuseTracker { } } - pub fn set_expectation( + fn set_expectation( &mut self, cgu_name: Symbol, cgu_user_name: &str, @@ -265,7 +265,7 @@ impl CguReuseTracker { } } - pub fn check_expected_reuse(&self, sess: &Session) { + fn check_expected_reuse(&self, sess: &Session) { if let Some(ref data) = self.data { for (cgu_name, &(ref cgu_user_name, ref error_span, expected_reuse, comparison_kind)) in &data.expected_reuse From b6b11c72c96d69bc622c7a82484c29c3c3365ce7 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 10 Oct 2023 14:02:42 +1100 Subject: [PATCH 15/50] Rejig some top-level `rustc_hir_pretty` functions. There are several that are unused and can be removed. And there are some calls to `to_string`, which can be expressed more nicely as a `foo_to_string` call, and then `to_string` need not be `pub`. (This requires adding `pat_to_string`). --- compiler/rustc_hir_pretty/src/lib.rs | 38 ++----------------- compiler/rustc_hir_typeck/src/pat.rs | 12 ++---- .../src/matches/match_wild_err_arm.rs | 2 +- .../clippy/clippy_lints/src/mut_reference.rs | 2 +- 4 files changed, 8 insertions(+), 46 deletions(-) diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 8587b009f25a..bc5b2a10d9f6 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -187,7 +187,7 @@ impl<'a> State<'a> { } } -pub fn to_string(ann: &dyn PpAnn, f: F) -> String +fn to_string(ann: &dyn PpAnn, f: F) -> String where F: FnOnce(&mut State<'_>), { @@ -196,48 +196,16 @@ where printer.s.eof() } -pub fn generic_params_to_string(generic_params: &[GenericParam<'_>]) -> String { - to_string(NO_ANN, |s| s.print_generic_params(generic_params)) -} - -pub fn bounds_to_string<'b>(bounds: impl IntoIterator>) -> String { - to_string(NO_ANN, |s| s.print_bounds("", bounds)) -} - pub fn ty_to_string(ty: &hir::Ty<'_>) -> String { to_string(NO_ANN, |s| s.print_type(ty)) } -pub fn path_segment_to_string(segment: &hir::PathSegment<'_>) -> String { - to_string(NO_ANN, |s| s.print_path_segment(segment)) -} - -pub fn path_to_string(segment: &hir::Path<'_>) -> String { - to_string(NO_ANN, |s| s.print_path(segment, false)) -} - pub fn qpath_to_string(segment: &hir::QPath<'_>) -> String { to_string(NO_ANN, |s| s.print_qpath(segment, false)) } -pub fn fn_to_string( - decl: &hir::FnDecl<'_>, - header: hir::FnHeader, - name: Option, - generics: &hir::Generics<'_>, - arg_names: &[Ident], - body_id: Option, -) -> String { - to_string(NO_ANN, |s| s.print_fn(decl, header, name, generics, arg_names, body_id)) -} - -pub fn enum_def_to_string( - enum_definition: &hir::EnumDef<'_>, - generics: &hir::Generics<'_>, - name: Symbol, - span: rustc_span::Span, -) -> String { - to_string(NO_ANN, |s| s.print_enum_def(enum_definition, generics, name, span)) +pub fn pat_to_string(pat: &hir::Pat<'_>) -> String { + to_string(NO_ANN, |s| s.print_pat(pat)) } impl<'a> State<'a> { diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 3f9c9b3381ba..072c7a9f36ad 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -1504,9 +1504,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { let has_shorthand_field_name = field_patterns.iter().any(|field| field.is_shorthand); if has_shorthand_field_name { - let path = rustc_hir_pretty::to_string(rustc_hir_pretty::NO_ANN, |s| { - s.print_qpath(qpath, false) - }); + let path = rustc_hir_pretty::qpath_to_string(qpath); let mut err = struct_span_err!( self.tcx.sess, pat.span, @@ -1688,9 +1686,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return None; } - let path = rustc_hir_pretty::to_string(rustc_hir_pretty::NO_ANN, |s| { - s.print_qpath(qpath, false) - }); + let path = rustc_hir_pretty::qpath_to_string(qpath); let mut err = struct_span_err!( self.tcx.sess, pat.span, @@ -1740,9 +1736,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { f } } - Err(_) => rustc_hir_pretty::to_string(rustc_hir_pretty::NO_ANN, |s| { - s.print_pat(field.pat) - }), + Err(_) => rustc_hir_pretty::pat_to_string(field.pat), } }) .collect::>() diff --git a/src/tools/clippy/clippy_lints/src/matches/match_wild_err_arm.rs b/src/tools/clippy/clippy_lints/src/matches/match_wild_err_arm.rs index de911f7a0280..a2903e52ae08 100644 --- a/src/tools/clippy/clippy_lints/src/matches/match_wild_err_arm.rs +++ b/src/tools/clippy/clippy_lints/src/matches/match_wild_err_arm.rs @@ -19,7 +19,7 @@ pub(crate) fn check<'tcx>(cx: &LateContext<'tcx>, ex: &Expr<'tcx>, arms: &[Arm<' if is_type_diagnostic_item(cx, ex_ty, sym::Result) { for arm in arms { if let PatKind::TupleStruct(ref path, inner, _) = arm.pat.kind { - let path_str = rustc_hir_pretty::to_string(rustc_hir_pretty::NO_ANN, |s| s.print_qpath(path, false)); + let path_str = rustc_hir_pretty::qpath_to_string(path); if path_str == "Err" { let mut matching_wild = inner.iter().any(is_wild); let mut ident_bind_name = kw::Underscore; diff --git a/src/tools/clippy/clippy_lints/src/mut_reference.rs b/src/tools/clippy/clippy_lints/src/mut_reference.rs index e53e146ec5db..01b850cdb113 100644 --- a/src/tools/clippy/clippy_lints/src/mut_reference.rs +++ b/src/tools/clippy/clippy_lints/src/mut_reference.rs @@ -49,7 +49,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryMutPassed { cx, arguments.iter().collect(), cx.typeck_results().expr_ty(fn_expr), - &rustc_hir_pretty::to_string(rustc_hir_pretty::NO_ANN, |s| s.print_qpath(path, false)), + &rustc_hir_pretty::qpath_to_string(path), "function", ); } From 51e8c807277580f3575df4bbd01ebf2bfde941ff Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Tue, 10 Oct 2023 02:40:26 -0400 Subject: [PATCH 16/50] Add unstable book page for the no-jump-tables codegen option --- .../src/compiler-flags/no-jump-tables.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/doc/unstable-book/src/compiler-flags/no-jump-tables.md diff --git a/src/doc/unstable-book/src/compiler-flags/no-jump-tables.md b/src/doc/unstable-book/src/compiler-flags/no-jump-tables.md new file mode 100644 index 000000000000..f096c20f4bd5 --- /dev/null +++ b/src/doc/unstable-book/src/compiler-flags/no-jump-tables.md @@ -0,0 +1,19 @@ +# `no-jump-tables` + +The tracking issue for this feature is [#116592](https://github.com/rust-lang/rust/issues/116592) + +--- + +This option enables the `-fno-jump-tables` flag for LLVM, which makes the +codegen backend avoid generating jump tables when lowering switches. + +This option adds the LLVM `no-jump-tables=true` attribute to every function. + +The option can be used to help provide protection against +jump-oriented-programming (JOP) attacks, such as with the linux kernel's [IBT]. + +```sh +RUSTFLAGS="-Zno-jump-tables" cargo +nightly build -Z build-std +``` + +[IBT]: https://www.phoronix.com/news/Linux-IBT-By-Default-Tip From 664b1858aac90a75e6bbaca9f3c0726877a04ab3 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 10 Oct 2023 14:01:36 +1100 Subject: [PATCH 17/50] Remove many unneeded `pub`s. --- compiler/rustc_hir_pretty/src/lib.rs | 117 ++++++++++++++------------- 1 file changed, 59 insertions(+), 58 deletions(-) diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index bc5b2a10d9f6..e6388f34eea2 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -75,7 +75,7 @@ pub struct State<'a> { } impl<'a> State<'a> { - pub fn print_node(&mut self, node: Node<'_>) { + fn print_node(&mut self, node: Node<'_>) { match node { Node::Param(a) => self.print_param(a), Node::Item(a) => self.print_item(a), @@ -144,7 +144,7 @@ impl<'a> PrintState<'a> for State<'a> { } } -pub const INDENT_UNIT: isize = 4; +const INDENT_UNIT: isize = 4; /// Requires you to pass an input filename and reader so that /// it can scan the input text for comments to copy forward. @@ -167,7 +167,7 @@ pub fn print_crate<'a>( } impl<'a> State<'a> { - pub fn new_from_input( + fn new_from_input( sm: &'a SourceMap, filename: FileName, input: String, @@ -209,7 +209,7 @@ pub fn pat_to_string(pat: &hir::Pat<'_>) -> String { } impl<'a> State<'a> { - pub fn bclose_maybe_open(&mut self, span: rustc_span::Span, close_box: bool) { + fn bclose_maybe_open(&mut self, span: rustc_span::Span, close_box: bool) { self.maybe_print_comment(span.hi()); self.break_offset_if_not_bol(1, -INDENT_UNIT); self.word("}"); @@ -218,11 +218,11 @@ impl<'a> State<'a> { } } - pub fn bclose(&mut self, span: rustc_span::Span) { + fn bclose(&mut self, span: rustc_span::Span) { self.bclose_maybe_open(span, true) } - pub fn commasep_cmnt(&mut self, b: Breaks, elts: &[T], mut op: F, mut get_span: G) + fn commasep_cmnt(&mut self, b: Breaks, elts: &[T], mut op: F, mut get_span: G) where F: FnMut(&mut State<'_>, &T), G: FnMut(&T) -> rustc_span::Span, @@ -243,25 +243,25 @@ impl<'a> State<'a> { self.end(); } - pub fn commasep_exprs(&mut self, b: Breaks, exprs: &[hir::Expr<'_>]) { + fn commasep_exprs(&mut self, b: Breaks, exprs: &[hir::Expr<'_>]) { self.commasep_cmnt(b, exprs, |s, e| s.print_expr(e), |e| e.span); } - pub fn print_mod(&mut self, _mod: &hir::Mod<'_>, attrs: &[ast::Attribute]) { + fn print_mod(&mut self, _mod: &hir::Mod<'_>, attrs: &[ast::Attribute]) { self.print_inner_attributes(attrs); for &item_id in _mod.item_ids { self.ann.nested(self, Nested::Item(item_id)); } } - pub fn print_opt_lifetime(&mut self, lifetime: &hir::Lifetime) { + fn print_opt_lifetime(&mut self, lifetime: &hir::Lifetime) { if !lifetime.is_elided() { self.print_lifetime(lifetime); self.nbsp(); } } - pub fn print_type(&mut self, ty: &hir::Ty<'_>) { + fn print_type(&mut self, ty: &hir::Ty<'_>) { self.maybe_print_comment(ty.span.lo()); self.ibox(0); match ty.kind { @@ -339,7 +339,7 @@ impl<'a> State<'a> { self.end() } - pub fn print_foreign_item(&mut self, item: &hir::ForeignItem<'_>) { + fn print_foreign_item(&mut self, item: &hir::ForeignItem<'_>) { self.hardbreak_if_not_bol(); self.maybe_print_comment(item.span.lo()); self.print_outer_attributes(self.attrs(item.hir_id())); @@ -447,7 +447,7 @@ impl<'a> State<'a> { } /// Pretty-print an item - pub fn print_item(&mut self, item: &hir::Item<'_>) { + fn print_item(&mut self, item: &hir::Item<'_>) { self.hardbreak_if_not_bol(); self.maybe_print_comment(item.span.lo()); let attrs = self.attrs(item.hir_id()); @@ -672,7 +672,7 @@ impl<'a> State<'a> { self.ann.post(self, AnnNode::Item(item)) } - pub fn print_trait_ref(&mut self, t: &hir::TraitRef<'_>) { + fn print_trait_ref(&mut self, t: &hir::TraitRef<'_>) { self.print_path(t.path, false); } @@ -689,7 +689,7 @@ impl<'a> State<'a> { self.print_trait_ref(&t.trait_ref); } - pub fn print_enum_def( + fn print_enum_def( &mut self, enum_definition: &hir::EnumDef<'_>, generics: &hir::Generics<'_>, @@ -704,7 +704,7 @@ impl<'a> State<'a> { self.print_variants(enum_definition.variants, span); } - pub fn print_variants(&mut self, variants: &[hir::Variant<'_>], span: rustc_span::Span) { + fn print_variants(&mut self, variants: &[hir::Variant<'_>], span: rustc_span::Span) { self.bopen(); for v in variants { self.space_if_not_bol(); @@ -719,14 +719,14 @@ impl<'a> State<'a> { self.bclose(span) } - pub fn print_defaultness(&mut self, defaultness: hir::Defaultness) { + fn print_defaultness(&mut self, defaultness: hir::Defaultness) { match defaultness { hir::Defaultness::Default { .. } => self.word_nbsp("default"), hir::Defaultness::Final => (), } } - pub fn print_struct( + fn print_struct( &mut self, struct_def: &hir::VariantData<'_>, generics: &hir::Generics<'_>, @@ -775,7 +775,7 @@ impl<'a> State<'a> { } } - pub fn print_variant(&mut self, v: &hir::Variant<'_>) { + fn print_variant(&mut self, v: &hir::Variant<'_>) { self.head(""); let generics = hir::Generics::empty(); self.print_struct(&v.data, generics, v.ident.name, v.span, false); @@ -785,7 +785,8 @@ impl<'a> State<'a> { self.print_anon_const(d); } } - pub fn print_method_sig( + + fn print_method_sig( &mut self, ident: Ident, m: &hir::FnSig<'_>, @@ -796,7 +797,7 @@ impl<'a> State<'a> { self.print_fn(m.decl, m.header, Some(ident.name), generics, arg_names, body_id); } - pub fn print_trait_item(&mut self, ti: &hir::TraitItem<'_>) { + fn print_trait_item(&mut self, ti: &hir::TraitItem<'_>) { self.ann.pre(self, AnnNode::SubItem(ti.hir_id())); self.hardbreak_if_not_bol(); self.maybe_print_comment(ti.span.lo()); @@ -824,7 +825,7 @@ impl<'a> State<'a> { self.ann.post(self, AnnNode::SubItem(ti.hir_id())) } - pub fn print_impl_item(&mut self, ii: &hir::ImplItem<'_>) { + fn print_impl_item(&mut self, ii: &hir::ImplItem<'_>) { self.ann.pre(self, AnnNode::SubItem(ii.hir_id())); self.hardbreak_if_not_bol(); self.maybe_print_comment(ii.span.lo()); @@ -849,7 +850,7 @@ impl<'a> State<'a> { self.ann.post(self, AnnNode::SubItem(ii.hir_id())) } - pub fn print_local( + fn print_local( &mut self, init: Option<&hir::Expr<'_>>, els: Option<&hir::Block<'_>>, @@ -882,7 +883,7 @@ impl<'a> State<'a> { self.end() } - pub fn print_stmt(&mut self, st: &hir::Stmt<'_>) { + fn print_stmt(&mut self, st: &hir::Stmt<'_>) { self.maybe_print_comment(st.span.lo()); match st.kind { hir::StmtKind::Local(loc) => { @@ -905,19 +906,19 @@ impl<'a> State<'a> { self.maybe_print_trailing_comment(st.span, None) } - pub fn print_block(&mut self, blk: &hir::Block<'_>) { + fn print_block(&mut self, blk: &hir::Block<'_>) { self.print_block_with_attrs(blk, &[]) } - pub fn print_block_unclosed(&mut self, blk: &hir::Block<'_>) { + fn print_block_unclosed(&mut self, blk: &hir::Block<'_>) { self.print_block_maybe_unclosed(blk, &[], false) } - pub fn print_block_with_attrs(&mut self, blk: &hir::Block<'_>, attrs: &[ast::Attribute]) { + fn print_block_with_attrs(&mut self, blk: &hir::Block<'_>, attrs: &[ast::Attribute]) { self.print_block_maybe_unclosed(blk, attrs, true) } - pub fn print_block_maybe_unclosed( + fn print_block_maybe_unclosed( &mut self, blk: &hir::Block<'_>, attrs: &[ast::Attribute], @@ -973,7 +974,7 @@ impl<'a> State<'a> { } } - pub fn print_if( + fn print_if( &mut self, test: &hir::Expr<'_>, blk: &hir::Expr<'_>, @@ -986,14 +987,14 @@ impl<'a> State<'a> { self.print_else(elseopt) } - pub fn print_array_length(&mut self, len: &hir::ArrayLen) { + fn print_array_length(&mut self, len: &hir::ArrayLen) { match len { hir::ArrayLen::Infer(_, _) => self.word("_"), hir::ArrayLen::Body(ct) => self.print_anon_const(ct), } } - pub fn print_anon_const(&mut self, constant: &hir::AnonConst) { + fn print_anon_const(&mut self, constant: &hir::AnonConst) { self.ann.nested(self, Nested::Body(constant.body)) } @@ -1009,7 +1010,7 @@ impl<'a> State<'a> { /// Prints an expr using syntax that's acceptable in a condition position, such as the `cond` in /// `if cond { ... }`. - pub fn print_expr_as_cond(&mut self, expr: &hir::Expr<'_>) { + fn print_expr_as_cond(&mut self, expr: &hir::Expr<'_>) { self.print_expr_cond_paren(expr, Self::cond_needs_par(expr)) } @@ -1328,7 +1329,7 @@ impl<'a> State<'a> { self.pclose(); } - pub fn print_expr(&mut self, expr: &hir::Expr<'_>) { + fn print_expr(&mut self, expr: &hir::Expr<'_>) { self.maybe_print_comment(expr.span.lo()); self.print_outer_attributes(self.attrs(expr.hir_id)); self.ibox(INDENT_UNIT); @@ -1561,7 +1562,7 @@ impl<'a> State<'a> { self.end() } - pub fn print_local_decl(&mut self, loc: &hir::Local<'_>) { + fn print_local_decl(&mut self, loc: &hir::Local<'_>) { self.print_pat(loc.pat); if let Some(ty) = loc.ty { self.word_space(":"); @@ -1569,11 +1570,11 @@ impl<'a> State<'a> { } } - pub fn print_name(&mut self, name: Symbol) { + fn print_name(&mut self, name: Symbol) { self.print_ident(Ident::with_dummy_span(name)) } - pub fn print_path(&mut self, path: &hir::Path<'_, R>, colons_before_params: bool) { + fn print_path(&mut self, path: &hir::Path<'_, R>, colons_before_params: bool) { self.maybe_print_comment(path.span.lo()); for (i, segment) in path.segments.iter().enumerate() { @@ -1587,14 +1588,14 @@ impl<'a> State<'a> { } } - pub fn print_path_segment(&mut self, segment: &hir::PathSegment<'_>) { + fn print_path_segment(&mut self, segment: &hir::PathSegment<'_>) { if segment.ident.name != kw::PathRoot { self.print_ident(segment.ident); self.print_generic_args(segment.args(), false); } } - pub fn print_qpath(&mut self, qpath: &hir::QPath<'_>, colons_before_params: bool) { + fn print_qpath(&mut self, qpath: &hir::QPath<'_>, colons_before_params: bool) { match *qpath { hir::QPath::Resolved(None, path) => self.print_path(path, colons_before_params), hir::QPath::Resolved(Some(qself), path) => { @@ -1711,7 +1712,7 @@ impl<'a> State<'a> { } } - pub fn print_type_binding(&mut self, binding: &hir::TypeBinding<'_>) { + fn print_type_binding(&mut self, binding: &hir::TypeBinding<'_>) { self.print_ident(binding.ident); self.print_generic_args(binding.gen_args, false); self.space(); @@ -1729,7 +1730,7 @@ impl<'a> State<'a> { } } - pub fn print_pat(&mut self, pat: &hir::Pat<'_>) { + fn print_pat(&mut self, pat: &hir::Pat<'_>) { self.maybe_print_comment(pat.span.lo()); self.ann.pre(self, AnnNode::Pat(pat)); // Pat isn't normalized, but the beauty of it @@ -1873,7 +1874,7 @@ impl<'a> State<'a> { self.ann.post(self, AnnNode::Pat(pat)) } - pub fn print_patfield(&mut self, field: &hir::PatField<'_>) { + fn print_patfield(&mut self, field: &hir::PatField<'_>) { if self.attrs(field.hir_id).is_empty() { self.space(); } @@ -1887,12 +1888,12 @@ impl<'a> State<'a> { self.end(); } - pub fn print_param(&mut self, arg: &hir::Param<'_>) { + fn print_param(&mut self, arg: &hir::Param<'_>) { self.print_outer_attributes(self.attrs(arg.hir_id)); self.print_pat(arg.pat); } - pub fn print_arm(&mut self, arm: &hir::Arm<'_>) { + fn print_arm(&mut self, arm: &hir::Arm<'_>) { // I have no idea why this check is necessary, but here it // is :( if self.attrs(arm.hir_id).is_empty() { @@ -1944,7 +1945,7 @@ impl<'a> State<'a> { self.end() // close enclosing cbox } - pub fn print_fn( + fn print_fn( &mut self, decl: &hir::FnDecl<'_>, header: hir::FnHeader, @@ -2024,14 +2025,14 @@ impl<'a> State<'a> { } } - pub fn print_capture_clause(&mut self, capture_clause: hir::CaptureBy) { + fn print_capture_clause(&mut self, capture_clause: hir::CaptureBy) { match capture_clause { hir::CaptureBy::Value => self.word_space("move"), hir::CaptureBy::Ref => {} } } - pub fn print_closure_binder( + fn print_closure_binder( &mut self, binder: hir::ClosureBinder, generic_params: &[GenericParam<'_>], @@ -2067,7 +2068,7 @@ impl<'a> State<'a> { } } - pub fn print_bounds<'b>( + fn print_bounds<'b>( &mut self, prefix: &'static str, bounds: impl IntoIterator>, @@ -2105,7 +2106,7 @@ impl<'a> State<'a> { } } - pub fn print_generic_params(&mut self, generic_params: &[GenericParam<'_>]) { + fn print_generic_params(&mut self, generic_params: &[GenericParam<'_>]) { if !generic_params.is_empty() { self.word("<"); @@ -2115,7 +2116,7 @@ impl<'a> State<'a> { } } - pub fn print_generic_param(&mut self, param: &GenericParam<'_>) { + fn print_generic_param(&mut self, param: &GenericParam<'_>) { if let GenericParamKind::Const { .. } = param.kind { self.word_space("const"); } @@ -2143,11 +2144,11 @@ impl<'a> State<'a> { } } - pub fn print_lifetime(&mut self, lifetime: &hir::Lifetime) { + fn print_lifetime(&mut self, lifetime: &hir::Lifetime) { self.print_ident(lifetime.ident) } - pub fn print_where_clause(&mut self, generics: &hir::Generics<'_>) { + fn print_where_clause(&mut self, generics: &hir::Generics<'_>) { if generics.predicates.is_empty() { return; } @@ -2204,7 +2205,7 @@ impl<'a> State<'a> { } } - pub fn print_mutability(&mut self, mutbl: hir::Mutability, print_const: bool) { + fn print_mutability(&mut self, mutbl: hir::Mutability, print_const: bool) { match mutbl { hir::Mutability::Mut => self.word_nbsp("mut"), hir::Mutability::Not => { @@ -2215,12 +2216,12 @@ impl<'a> State<'a> { } } - pub fn print_mt(&mut self, mt: &hir::MutTy<'_>, print_const: bool) { + fn print_mt(&mut self, mt: &hir::MutTy<'_>, print_const: bool) { self.print_mutability(mt.mutbl, print_const); self.print_type(mt.ty); } - pub fn print_fn_output(&mut self, decl: &hir::FnDecl<'_>) { + fn print_fn_output(&mut self, decl: &hir::FnDecl<'_>) { if let hir::FnRetTy::DefaultReturn(..) = decl.output { return; } @@ -2239,7 +2240,7 @@ impl<'a> State<'a> { } } - pub fn print_ty_fn( + fn print_ty_fn( &mut self, abi: Abi, unsafety: hir::Unsafety, @@ -2267,7 +2268,7 @@ impl<'a> State<'a> { self.end(); } - pub fn print_fn_header_info(&mut self, header: hir::FnHeader) { + fn print_fn_header_info(&mut self, header: hir::FnHeader) { self.print_constness(header.constness); match header.asyncness { @@ -2285,21 +2286,21 @@ impl<'a> State<'a> { self.word("fn") } - pub fn print_constness(&mut self, s: hir::Constness) { + fn print_constness(&mut self, s: hir::Constness) { match s { hir::Constness::NotConst => {} hir::Constness::Const => self.word_nbsp("const"), } } - pub fn print_unsafety(&mut self, s: hir::Unsafety) { + fn print_unsafety(&mut self, s: hir::Unsafety) { match s { hir::Unsafety::Normal => {} hir::Unsafety::Unsafe => self.word_nbsp("unsafe"), } } - pub fn print_is_auto(&mut self, s: hir::IsAuto) { + fn print_is_auto(&mut self, s: hir::IsAuto) { match s { hir::IsAuto::Yes => self.word_nbsp("auto"), hir::IsAuto::No => {} From 494bc8514aa98b7f4786b66a7774004902ef4aa2 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 10 Oct 2023 14:14:13 +1100 Subject: [PATCH 18/50] Tweak comments. - Remove an out-of-date comment. (There is no `PpAnn` implementation for `hir::Crate`.) - Remove a low-value comment. - And break a very long comment. --- compiler/rustc_hir_pretty/src/lib.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index e6388f34eea2..077f9e947e68 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -52,8 +52,6 @@ pub struct NoAnn; impl PpAnn for NoAnn {} pub const NO_ANN: &dyn PpAnn = &NoAnn; -/// Identical to the `PpAnn` implementation for `hir::Crate`, -/// except it avoids creating a dependency on the whole crate. impl PpAnn for &dyn rustc_hir::intravisit::Map<'_> { fn nested(&self, state: &mut State<'_>, nested: Nested) { match nested { @@ -446,7 +444,6 @@ impl<'a> State<'a> { self.end(); // end the outer ibox } - /// Pretty-print an item fn print_item(&mut self, item: &hir::Item<'_>) { self.hardbreak_if_not_bol(); self.maybe_print_comment(item.span.lo()); @@ -2052,7 +2049,8 @@ impl<'a> State<'a> { match binder { hir::ClosureBinder::Default => {} - // we need to distinguish `|...| {}` from `for<> |...| {}` as `for<>` adds additional restrictions + // We need to distinguish `|...| {}` from `for<> |...| {}` as `for<>` adds additional + // restrictions. hir::ClosureBinder::For { .. } if generic_params.is_empty() => self.word("for<>"), hir::ClosureBinder::For { .. } => { self.word("for"); From 7d35902c6275f5236f77427c2cca8d58f8f8a579 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 10 Oct 2023 14:23:08 +1100 Subject: [PATCH 19/50] Fiddle with `State` functions. Remove and inline `new_from_input`, because it has a single call site. And move `attrs` into the earlier `impl` block. --- compiler/rustc_hir_pretty/src/lib.rs | 32 +++++++++------------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 077f9e947e68..ab6ab391484f 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -73,6 +73,10 @@ pub struct State<'a> { } impl<'a> State<'a> { + fn attrs(&self, id: hir::HirId) -> &'a [ast::Attribute] { + (self.attrs)(id) + } + fn print_node(&mut self, node: Node<'_>) { match node { Node::Param(a) => self.print_param(a), @@ -154,7 +158,12 @@ pub fn print_crate<'a>( attrs: &'a dyn Fn(hir::HirId) -> &'a [ast::Attribute], ann: &'a dyn PpAnn, ) -> String { - let mut s = State::new_from_input(sm, filename, input, attrs, ann); + let mut s = State { + s: pp::Printer::new(), + comments: Some(Comments::new(sm, filename, input)), + attrs, + ann, + }; // When printing the AST, we sometimes need to inject `#[no_std]` here. // Since you can't compile the HIR, it's not necessary. @@ -164,27 +173,6 @@ pub fn print_crate<'a>( s.s.eof() } -impl<'a> State<'a> { - fn new_from_input( - sm: &'a SourceMap, - filename: FileName, - input: String, - attrs: &'a dyn Fn(hir::HirId) -> &'a [ast::Attribute], - ann: &'a dyn PpAnn, - ) -> State<'a> { - State { - s: pp::Printer::new(), - comments: Some(Comments::new(sm, filename, input)), - attrs, - ann, - } - } - - fn attrs(&self, id: hir::HirId) -> &'a [ast::Attribute] { - (self.attrs)(id) - } -} - fn to_string(ann: &dyn PpAnn, f: F) -> String where F: FnOnce(&mut State<'_>), From 232aaeba7c6779233659b0a57ed75a5d7a48cfb0 Mon Sep 17 00:00:00 2001 From: Georg Semmler Date: Wed, 11 Oct 2023 21:57:53 +0200 Subject: [PATCH 20/50] Handle several `#[diagnostic::on_unimplemented]` attributes correctly This PR fixes an issues where rustc would ignore subsequent `#[diagnostic::on_unimplemented]` attributes. The [corresponding RFC](https://rust-lang.github.io/rfcs/3368-diagnostic-attribute-namespace.html) specifies that the first matching instance of each option is used. Invalid attributes are linted and otherwise ignored. --- .../error_reporting/on_unimplemented.rs | 46 +++++++++++----- ...ed_options_and_continue_to_use_fallback.rs | 22 ++++++++ ...ptions_and_continue_to_use_fallback.stderr | 52 +++++++++++++++++++ 3 files changed, 108 insertions(+), 12 deletions(-) create mode 100644 tests/ui/diagnostic_namespace/on_unimplemented/ignore_unsupported_options_and_continue_to_use_fallback.rs create mode 100644 tests/ui/diagnostic_namespace/on_unimplemented/ignore_unsupported_options_and_continue_to_use_fallback.stderr diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs index d9059e46a8c5..cc1f13a2f0f2 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs @@ -1,6 +1,6 @@ use super::{ObligationCauseCode, PredicateObligation}; use crate::infer::error_reporting::TypeErrCtxt; -use rustc_ast::{MetaItem, NestedMetaItem}; +use rustc_ast::{Attribute, MetaItem, NestedMetaItem}; use rustc_attr as attr; use rustc_data_structures::fx::FxHashMap; use rustc_errors::{struct_span_err, ErrorGuaranteed}; @@ -474,18 +474,40 @@ impl<'tcx> OnUnimplementedDirective { } pub fn of_item(tcx: TyCtxt<'tcx>, item_def_id: DefId) -> Result, ErrorGuaranteed> { - let mut is_diagnostic_namespace_variant = false; - let Some(attr) = tcx.get_attr(item_def_id, sym::rustc_on_unimplemented).or_else(|| { - if tcx.features().diagnostic_namespace { - is_diagnostic_namespace_variant = true; - tcx.get_attrs_by_path(item_def_id, &[sym::diagnostic, sym::on_unimplemented]).next() - } else { - None - } - }) else { - return Ok(None); - }; + if let Some(attr) = tcx.get_attr(item_def_id, sym::rustc_on_unimplemented) { + return Self::parse_attribute(attr, false, tcx, item_def_id); + } else if tcx.features().diagnostic_namespace { + tcx.get_attrs_by_path(item_def_id, &[sym::diagnostic, sym::on_unimplemented]) + .filter_map(|attr| Self::parse_attribute(attr, true, tcx, item_def_id).transpose()) + .try_fold(None, |aggr: Option, directive| { + let directive = directive?; + if let Some(aggr) = aggr { + let mut subcommands = aggr.subcommands; + subcommands.extend(directive.subcommands); + Ok(Some(Self { + condition: aggr.condition.or(directive.condition), + subcommands, + message: aggr.message.or(directive.message), + label: aggr.label.or(directive.label), + note: aggr.note.or(directive.note), + parent_label: aggr.parent_label.or(directive.parent_label), + append_const_msg: aggr.append_const_msg.or(directive.append_const_msg), + })) + } else { + Ok(Some(directive)) + } + }) + } else { + Ok(None) + } + } + fn parse_attribute( + attr: &Attribute, + is_diagnostic_namespace_variant: bool, + tcx: TyCtxt<'tcx>, + item_def_id: DefId, + ) -> Result, ErrorGuaranteed> { let result = if let Some(items) = attr.meta_item_list() { Self::parse(tcx, item_def_id, &items, attr.span, true, is_diagnostic_namespace_variant) } else if let Some(value) = attr.value_str() { diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/ignore_unsupported_options_and_continue_to_use_fallback.rs b/tests/ui/diagnostic_namespace/on_unimplemented/ignore_unsupported_options_and_continue_to_use_fallback.rs new file mode 100644 index 000000000000..353075863918 --- /dev/null +++ b/tests/ui/diagnostic_namespace/on_unimplemented/ignore_unsupported_options_and_continue_to_use_fallback.rs @@ -0,0 +1,22 @@ +#![feature(diagnostic_namespace)] + +#[diagnostic::on_unimplemented( + //~^WARN malformed `on_unimplemented` attribute + //~|WARN malformed `on_unimplemented` attribute + if(Self = ()), + message = "not used yet", + label = "not used yet", + note = "not used yet" +)] +#[diagnostic::on_unimplemented(message = "fallback!!")] +#[diagnostic::on_unimplemented(label = "fallback label")] +#[diagnostic::on_unimplemented(note = "fallback note")] +#[diagnostic::on_unimplemented(message = "fallback2!!")] +trait Foo {} + +fn takes_foo(_: impl Foo) {} + +fn main() { + takes_foo(()); + //~^ERROR fallback!! +} diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/ignore_unsupported_options_and_continue_to_use_fallback.stderr b/tests/ui/diagnostic_namespace/on_unimplemented/ignore_unsupported_options_and_continue_to_use_fallback.stderr new file mode 100644 index 000000000000..6a83d8e39c65 --- /dev/null +++ b/tests/ui/diagnostic_namespace/on_unimplemented/ignore_unsupported_options_and_continue_to_use_fallback.stderr @@ -0,0 +1,52 @@ +warning: malformed `on_unimplemented` attribute + --> $DIR/ignore_unsupported_options_and_continue_to_use_fallback.rs:3:1 + | +LL | / #[diagnostic::on_unimplemented( +LL | | +LL | | +LL | | if(Self = ()), +... | +LL | | note = "not used yet" +LL | | )] + | |__^ + | + = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default + +warning: malformed `on_unimplemented` attribute + --> $DIR/ignore_unsupported_options_and_continue_to_use_fallback.rs:3:1 + | +LL | / #[diagnostic::on_unimplemented( +LL | | +LL | | +LL | | if(Self = ()), +... | +LL | | note = "not used yet" +LL | | )] + | |__^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0277]: fallback!! + --> $DIR/ignore_unsupported_options_and_continue_to_use_fallback.rs:20:15 + | +LL | takes_foo(()); + | --------- ^^ fallback label + | | + | required by a bound introduced by this call + | + = help: the trait `Foo` is not implemented for `()` + = note: fallback note +help: this trait has no implementations, consider adding one + --> $DIR/ignore_unsupported_options_and_continue_to_use_fallback.rs:15:1 + | +LL | trait Foo {} + | ^^^^^^^^^ +note: required by a bound in `takes_foo` + --> $DIR/ignore_unsupported_options_and_continue_to_use_fallback.rs:17:22 + | +LL | fn takes_foo(_: impl Foo) {} + | ^^^ required by this bound in `takes_foo` + +error: aborting due to previous error; 2 warnings emitted + +For more information about this error, try `rustc --explain E0277`. From d6056ecb0a4938a594d6cc8ed7eff8046271928f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 10 Oct 2023 16:18:49 +0200 Subject: [PATCH 21/50] Show enum discriminant if a compatible repr is used --- src/librustdoc/html/render/print_item.rs | 34 +++++++++++++++++------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 467493cb0b30..3873a3f35222 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -7,6 +7,7 @@ use rustc_hir::def::CtorKind; use rustc_hir::def_id::DefId; use rustc_index::IndexVec; use rustc_middle::middle::stability; +use rustc_middle::query::Key; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{kw, sym, Symbol}; @@ -1249,6 +1250,9 @@ fn item_type_alias(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &c match inner_type { clean::TypeAliasInnerType::Enum { variants, is_non_exhaustive } => { let variants_iter = || variants.iter().filter(|i| !i.is_stripped()); + let ty = cx.tcx().type_of(it.def_id().unwrap()).instantiate_identity(); + let enum_def_id = ty.ty_adt_id().unwrap(); + wrap_item(w, |w| { let variants_len = variants.len(); let variants_count = variants_iter().count(); @@ -1263,10 +1267,10 @@ fn item_type_alias(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &c variants_count, has_stripped_entries, *is_non_exhaustive, - it.def_id().unwrap(), + enum_def_id, ) }); - item_variants(w, cx, it, &variants); + item_variants(w, cx, it, &variants, enum_def_id); } clean::TypeAliasInnerType::Union { fields } => { wrap_item(w, |w| { @@ -1435,16 +1439,20 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean:: write!(w, "{}", document(cx, it, None, HeadingOffset::H2)); if count_variants != 0 { - item_variants(w, cx, it, &e.variants); + item_variants(w, cx, it, &e.variants, it.def_id().unwrap()); } let def_id = it.item_id.expect_def_id(); write!(w, "{}", render_assoc_items(cx, it, def_id, AssocItemRender::All)); write!(w, "{}", document_type_layout(cx, def_id)); } -/// It'll return true if all variants are C-like variants and if at least one of them has a value -/// set. -fn should_show_enum_discriminant(variants: &IndexVec) -> bool { +/// It'll return false if any variant is not a C-like variant. Otherwise it'll return true if at +/// least one of them has a value set or if the enum has `#[repr(C)]` or has an integer `repr`. +fn should_show_enum_discriminant( + cx: &Context<'_>, + enum_def_id: DefId, + variants: &IndexVec, +) -> bool { let mut has_variants_with_value = false; for variant in variants { if let clean::VariantItem(ref var) = *variant.kind && @@ -1455,7 +1463,12 @@ fn should_show_enum_discriminant(variants: &IndexVec) - return false; } } - has_variants_with_value + if has_variants_with_value { + return true; + } + let repr = cx.tcx().adt_def(enum_def_id).repr(); + // let repr = cx.tcx().repr_options_of_def(enum_def_id); + repr.c() || repr.int.is_some() } fn display_c_like_variant( @@ -1493,7 +1506,7 @@ fn render_enum_fields( is_non_exhaustive: bool, enum_def_id: DefId, ) { - let should_show_enum_discriminant = should_show_enum_discriminant(variants); + let should_show_enum_discriminant = should_show_enum_discriminant(cx, enum_def_id, variants); if !g.is_some_and(|g| print_where_clause_and_check(w, g, cx)) { // If there wasn't a `where` clause, we add a whitespace. w.write_str(" "); @@ -1552,6 +1565,7 @@ fn item_variants( cx: &mut Context<'_>, it: &clean::Item, variants: &IndexVec, + enum_def_id: DefId, ) { let tcx = cx.tcx(); write!( @@ -1564,7 +1578,7 @@ fn item_variants( document_non_exhaustive_header(it), document_non_exhaustive(it) ); - let should_show_enum_discriminant = should_show_enum_discriminant(variants); + let should_show_enum_discriminant = should_show_enum_discriminant(cx, enum_def_id, variants); for (index, variant) in variants.iter_enumerated() { if variant.is_stripped() { continue; @@ -1594,7 +1608,7 @@ fn item_variants( var, index, should_show_enum_discriminant, - it.def_id().unwrap(), + enum_def_id, ); } else { w.write_str(variant.name.unwrap().as_str()); From bd59fc603f57f9cf9f8bae4ddfdf79a883129e76 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 10 Oct 2023 16:55:39 +0200 Subject: [PATCH 22/50] Add tests for enum discriminant value display with `repr` --- tests/rustdoc/auxiliary/enum-variant.rs | 24 ++++++++ tests/rustdoc/enum-variant-value.rs | 74 +++++++++++++++++++++++++ 2 files changed, 98 insertions(+) diff --git a/tests/rustdoc/auxiliary/enum-variant.rs b/tests/rustdoc/auxiliary/enum-variant.rs index 90c71b863290..a0a7fd894f90 100644 --- a/tests/rustdoc/auxiliary/enum-variant.rs +++ b/tests/rustdoc/auxiliary/enum-variant.rs @@ -22,3 +22,27 @@ pub enum H { A, C(u32), } + +#[repr(C)] +pub enum N { + A, + B, +} + +#[repr(C)] +pub enum O { + A(u32), + B, +} + +#[repr(u32)] +pub enum P { + A, + B, +} + +#[repr(u32)] +pub enum Q { + A(u32), + B, +} diff --git a/tests/rustdoc/enum-variant-value.rs b/tests/rustdoc/enum-variant-value.rs index c306736bfe91..096f8cd4122f 100644 --- a/tests/rustdoc/enum-variant-value.rs +++ b/tests/rustdoc/enum-variant-value.rs @@ -115,3 +115,77 @@ pub enum I { C = Self::B as isize + X + 3, D = -1, } + +// Testing `repr`. + +// @has 'foo/enum.J.html' +// @has - '//*[@class="rust item-decl"]/code' 'A = 0,' +// @has - '//*[@class="rust item-decl"]/code' 'B = 1,' +// @matches - '//*[@id="variant.A"]/h3' '^A = 0$' +// @matches - '//*[@id="variant.B"]/h3' '^B = 1$' +#[repr(C)] +pub enum J { + A, + B, +} + +// @has 'foo/enum.K.html' +// @has - '//*[@class="rust item-decl"]/code' 'A(u32),' +// @has - '//*[@class="rust item-decl"]/code' 'B,' +// @has - '//*[@id="variant.A"]/h3' 'A(u32)' +// @matches - '//*[@id="variant.B"]/h3' '^B$' +#[repr(C)] +pub enum K { + A(u32), + B, +} + +// @has 'foo/enum.L.html' +// @has - '//*[@class="rust item-decl"]/code' 'A = 0,' +// @has - '//*[@class="rust item-decl"]/code' 'B = 1,' +// @matches - '//*[@id="variant.A"]/h3' '^A = 0$' +// @matches - '//*[@id="variant.B"]/h3' '^B = 1$' +#[repr(u32)] +pub enum L { + A, + B, +} + +// @has 'foo/enum.M.html' +// @has - '//*[@class="rust item-decl"]/code' 'A(u32),' +// @has - '//*[@class="rust item-decl"]/code' 'B,' +// @has - '//*[@id="variant.A"]/h3' 'A(u32)' +// @matches - '//*[@id="variant.B"]/h3' '^B$' +#[repr(u32)] +pub enum M { + A(u32), + B, +} + +// @has 'foo/enum.N.html' +// @has - '//*[@class="rust item-decl"]/code' 'A = 0,' +// @has - '//*[@class="rust item-decl"]/code' 'B = 1,' +// @matches - '//*[@id="variant.A"]/h3' '^A = 0$' +// @matches - '//*[@id="variant.B"]/h3' '^B = 1$' +pub use bar::N; + +// @has 'foo/enum.O.html' +// @has - '//*[@class="rust item-decl"]/code' 'A(u32),' +// @has - '//*[@class="rust item-decl"]/code' 'B,' +// @has - '//*[@id="variant.A"]/h3' 'A(u32)' +// @matches - '//*[@id="variant.B"]/h3' '^B$' +pub use bar::O; + +// @has 'foo/enum.P.html' +// @has - '//*[@class="rust item-decl"]/code' 'A = 0,' +// @has - '//*[@class="rust item-decl"]/code' 'B = 1,' +// @matches - '//*[@id="variant.A"]/h3' '^A = 0$' +// @matches - '//*[@id="variant.B"]/h3' '^B = 1$' +pub use bar::P; + +// @has 'foo/enum.Q.html' +// @has - '//*[@class="rust item-decl"]/code' 'A(u32),' +// @has - '//*[@class="rust item-decl"]/code' 'B,' +// @has - '//*[@id="variant.A"]/h3' 'A(u32)' +// @matches - '//*[@id="variant.B"]/h3' '^B$' +pub use bar::Q; From 00c3de96e689d4b20be218692f88f8afa88ced87 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 11 Oct 2023 23:46:11 +0200 Subject: [PATCH 23/50] Improve code documentation a bit --- src/librustdoc/html/render/print_item.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 3873a3f35222..cd31493bf3ff 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -1447,7 +1447,8 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean:: } /// It'll return false if any variant is not a C-like variant. Otherwise it'll return true if at -/// least one of them has a value set or if the enum has `#[repr(C)]` or has an integer `repr`. +/// least one of them has an explicit discriminant or if the enum has `#[repr(C)]` or an integer +/// `repr`. fn should_show_enum_discriminant( cx: &Context<'_>, enum_def_id: DefId, @@ -1467,7 +1468,6 @@ fn should_show_enum_discriminant( return true; } let repr = cx.tcx().adt_def(enum_def_id).repr(); - // let repr = cx.tcx().repr_options_of_def(enum_def_id); repr.c() || repr.int.is_some() } From becf4942a26288916302f9a5f3fc6d4cc88abae8 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 8 Aug 2023 11:34:07 +1000 Subject: [PATCH 24/50] Rename `Token::is_op` as `Token::is_punct`. For consistency with `proc_macro::Punct`. --- compiler/rustc_ast/src/token.rs | 2 +- compiler/rustc_parse/src/lexer/tokentrees.rs | 7 +++++-- compiler/rustc_parse/src/parser/expr.rs | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index 09bfbd02198c..2de398521f57 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -404,7 +404,7 @@ impl Token { [DotDot, DotDotDot, DotDotEq].contains(&self.kind) } - pub fn is_op(&self) -> bool { + pub fn is_punct(&self) -> bool { match self.kind { Eq | Lt | Le | EqEq | Ne | Ge | Gt | AndAnd | OrOr | Not | Tilde | BinOp(_) | BinOpEq(_) | At | Dot | DotDot | DotDotDot | DotDotEq | Comma | Semi | Colon diff --git a/compiler/rustc_parse/src/lexer/tokentrees.rs b/compiler/rustc_parse/src/lexer/tokentrees.rs index 07910113dee7..7cdb19704709 100644 --- a/compiler/rustc_parse/src/lexer/tokentrees.rs +++ b/compiler/rustc_parse/src/lexer/tokentrees.rs @@ -59,8 +59,11 @@ impl<'a> TokenTreesReader<'a> { if let Some(glued) = self.token.glue(&next_tok) { self.token = glued; } else { - let this_spacing = - if next_tok.is_op() { Spacing::Joint } else { Spacing::Alone }; + let this_spacing = if next_tok.is_punct() { + Spacing::Joint + } else { + Spacing::Alone + }; break (this_spacing, next_tok); } } else { diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 91bb2d9eb666..1d883e16f9dc 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1592,7 +1592,7 @@ impl<'a> Parser<'a> { } else if !ate_colon && self.may_recover() && (matches!(self.token.kind, token::CloseDelim(_) | token::Comma) - || self.token.is_op()) + || self.token.is_punct()) { let (lit, _) = self.recover_unclosed_char(label_.ident, Parser::mk_token_lit_char, |self_| { From 129fe9a998e611f3b16da9156934fc78149e0860 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 8 Aug 2023 11:28:29 +1000 Subject: [PATCH 25/50] Add a comment to `tests/ui/proc-macro/issue-75930-derive-cfg.rs`. Explaining something in the output that surprised me. --- tests/ui/proc-macro/issue-75930-derive-cfg.rs | 30 + .../proc-macro/issue-75930-derive-cfg.stderr | 4 +- .../proc-macro/issue-75930-derive-cfg.stdout | 768 +++++++++--------- 3 files changed, 416 insertions(+), 386 deletions(-) diff --git a/tests/ui/proc-macro/issue-75930-derive-cfg.rs b/tests/ui/proc-macro/issue-75930-derive-cfg.rs index ef56e8e02d0c..e0213527c500 100644 --- a/tests/ui/proc-macro/issue-75930-derive-cfg.rs +++ b/tests/ui/proc-macro/issue-75930-derive-cfg.rs @@ -16,6 +16,36 @@ extern crate std; #[macro_use] extern crate test_macros; +// Note: the expected output contains this sequence: +// ``` +// Punct { +// ch: '<', +// spacing: Joint, +// span: $DIR/issue-75930-derive-cfg.rs:25:11: 25:12 (#0), +// }, +// Ident { +// ident: "B", +// span: $DIR/issue-75930-derive-cfg.rs:25:29: 25:30 (#0), +// }, +// ``` +// It's surprising to see a `Joint` token tree followed by an `Ident` token +// tree, because `Joint` is supposed to only be used if the following token is +// `Punct`. +// +// It is because of this code from below: +// ``` +// struct Foo<#[cfg(FALSE)] A, B> +// ``` +// When the token stream is formed during parsing, `<` is followed immediately +// by `#`, which is punctuation, so it is marked `Joint`. But before being +// passed to the proc macro it is rewritten to this: +// ``` +// struct Foo +// ``` +// But the `Joint` marker on the `<` is not updated. Perhaps it should be +// corrected before being passed to the proc macro? But a prior attempt to do +// that kind of correction caused the problem seen in #76399, so maybe not. + #[print_helper(a)] //~ WARN derive helper attribute is used before it is introduced //~| WARN this was previously accepted #[cfg_attr(not(FALSE), allow(dead_code))] diff --git a/tests/ui/proc-macro/issue-75930-derive-cfg.stderr b/tests/ui/proc-macro/issue-75930-derive-cfg.stderr index f3f470676e40..1017745de6f2 100644 --- a/tests/ui/proc-macro/issue-75930-derive-cfg.stderr +++ b/tests/ui/proc-macro/issue-75930-derive-cfg.stderr @@ -1,5 +1,5 @@ warning: derive helper attribute is used before it is introduced - --> $DIR/issue-75930-derive-cfg.rs:19:3 + --> $DIR/issue-75930-derive-cfg.rs:49:3 | LL | #[print_helper(a)] | ^^^^^^^^^^^^ @@ -12,7 +12,7 @@ LL | #[derive(Print)] = note: `#[warn(legacy_derive_helpers)]` on by default warning: derive helper attribute is used before it is introduced - --> $DIR/issue-75930-derive-cfg.rs:19:3 + --> $DIR/issue-75930-derive-cfg.rs:49:3 | LL | #[print_helper(a)] | ^^^^^^^^^^^^ diff --git a/tests/ui/proc-macro/issue-75930-derive-cfg.stdout b/tests/ui/proc-macro/issue-75930-derive-cfg.stdout index 83afd0d3eaec..31a1c44b6df0 100644 --- a/tests/ui/proc-macro/issue-75930-derive-cfg.stdout +++ b/tests/ui/proc-macro/issue-75930-derive-cfg.stdout @@ -26,158 +26,158 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '#', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:19:1: 19:2 (#0), + span: $DIR/issue-75930-derive-cfg.rs:49:1: 49:2 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "print_helper", - span: $DIR/issue-75930-derive-cfg.rs:19:3: 19:15 (#0), + span: $DIR/issue-75930-derive-cfg.rs:49:3: 49:15 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "a", - span: $DIR/issue-75930-derive-cfg.rs:19:16: 19:17 (#0), + span: $DIR/issue-75930-derive-cfg.rs:49:16: 49:17 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:19:15: 19:18 (#0), + span: $DIR/issue-75930-derive-cfg.rs:49:15: 49:18 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:19:2: 19:19 (#0), + span: $DIR/issue-75930-derive-cfg.rs:49:2: 49:19 (#0), }, Punct { ch: '#', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:21:1: 21:2 (#0), + span: $DIR/issue-75930-derive-cfg.rs:51:1: 51:2 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "allow", - span: $DIR/issue-75930-derive-cfg.rs:21:24: 21:29 (#0), + span: $DIR/issue-75930-derive-cfg.rs:51:24: 51:29 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "dead_code", - span: $DIR/issue-75930-derive-cfg.rs:21:30: 21:39 (#0), + span: $DIR/issue-75930-derive-cfg.rs:51:30: 51:39 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:21:29: 21:40 (#0), + span: $DIR/issue-75930-derive-cfg.rs:51:29: 51:40 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:21:1: 21:2 (#0), + span: $DIR/issue-75930-derive-cfg.rs:51:1: 51:2 (#0), }, Punct { ch: '#', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:23:1: 23:2 (#0), + span: $DIR/issue-75930-derive-cfg.rs:53:1: 53:2 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "derive", - span: $DIR/issue-75930-derive-cfg.rs:23:3: 23:9 (#0), + span: $DIR/issue-75930-derive-cfg.rs:53:3: 53:9 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "Print", - span: $DIR/issue-75930-derive-cfg.rs:23:10: 23:15 (#0), + span: $DIR/issue-75930-derive-cfg.rs:53:10: 53:15 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:23:9: 23:16 (#0), + span: $DIR/issue-75930-derive-cfg.rs:53:9: 53:16 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:23:2: 23:17 (#0), + span: $DIR/issue-75930-derive-cfg.rs:53:2: 53:17 (#0), }, Punct { ch: '#', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:24:1: 24:2 (#0), + span: $DIR/issue-75930-derive-cfg.rs:54:1: 54:2 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "print_helper", - span: $DIR/issue-75930-derive-cfg.rs:24:3: 24:15 (#0), + span: $DIR/issue-75930-derive-cfg.rs:54:3: 54:15 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "b", - span: $DIR/issue-75930-derive-cfg.rs:24:16: 24:17 (#0), + span: $DIR/issue-75930-derive-cfg.rs:54:16: 54:17 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:24:15: 24:18 (#0), + span: $DIR/issue-75930-derive-cfg.rs:54:15: 54:18 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:24:2: 24:19 (#0), + span: $DIR/issue-75930-derive-cfg.rs:54:2: 54:19 (#0), }, Ident { ident: "struct", - span: $DIR/issue-75930-derive-cfg.rs:25:1: 25:7 (#0), + span: $DIR/issue-75930-derive-cfg.rs:55:1: 55:7 (#0), }, Ident { ident: "Foo", - span: $DIR/issue-75930-derive-cfg.rs:25:8: 25:11 (#0), + span: $DIR/issue-75930-derive-cfg.rs:55:8: 55:11 (#0), }, Punct { ch: '<', spacing: Joint, - span: $DIR/issue-75930-derive-cfg.rs:25:11: 25:12 (#0), + span: $DIR/issue-75930-derive-cfg.rs:55:11: 55:12 (#0), }, Punct { ch: '#', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:25:12: 25:13 (#0), + span: $DIR/issue-75930-derive-cfg.rs:55:12: 55:13 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "cfg", - span: $DIR/issue-75930-derive-cfg.rs:25:14: 25:17 (#0), + span: $DIR/issue-75930-derive-cfg.rs:55:14: 55:17 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "FALSE", - span: $DIR/issue-75930-derive-cfg.rs:25:18: 25:23 (#0), + span: $DIR/issue-75930-derive-cfg.rs:55:18: 55:23 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:25:17: 25:24 (#0), + span: $DIR/issue-75930-derive-cfg.rs:55:17: 55:24 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:25:13: 25:25 (#0), + span: $DIR/issue-75930-derive-cfg.rs:55:13: 55:25 (#0), }, Ident { ident: "A", - span: $DIR/issue-75930-derive-cfg.rs:25:26: 25:27 (#0), + span: $DIR/issue-75930-derive-cfg.rs:55:26: 55:27 (#0), }, Punct { ch: ',', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:25:27: 25:28 (#0), + span: $DIR/issue-75930-derive-cfg.rs:55:27: 55:28 (#0), }, Ident { ident: "B", - span: $DIR/issue-75930-derive-cfg.rs:25:29: 25:30 (#0), + span: $DIR/issue-75930-derive-cfg.rs:55:29: 55:30 (#0), }, Punct { ch: '>', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:25:30: 25:31 (#0), + span: $DIR/issue-75930-derive-cfg.rs:55:30: 55:31 (#0), }, Group { delimiter: Brace, @@ -185,128 +185,128 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '#', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:26:5: 26:6 (#0), + span: $DIR/issue-75930-derive-cfg.rs:56:5: 56:6 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "cfg", - span: $DIR/issue-75930-derive-cfg.rs:26:7: 26:10 (#0), + span: $DIR/issue-75930-derive-cfg.rs:56:7: 56:10 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "FALSE", - span: $DIR/issue-75930-derive-cfg.rs:26:11: 26:16 (#0), + span: $DIR/issue-75930-derive-cfg.rs:56:11: 56:16 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:26:10: 26:17 (#0), + span: $DIR/issue-75930-derive-cfg.rs:56:10: 56:17 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:26:6: 26:18 (#0), + span: $DIR/issue-75930-derive-cfg.rs:56:6: 56:18 (#0), }, Ident { ident: "first", - span: $DIR/issue-75930-derive-cfg.rs:26:19: 26:24 (#0), + span: $DIR/issue-75930-derive-cfg.rs:56:19: 56:24 (#0), }, Punct { ch: ':', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:26:24: 26:25 (#0), + span: $DIR/issue-75930-derive-cfg.rs:56:24: 56:25 (#0), }, Ident { ident: "String", - span: $DIR/issue-75930-derive-cfg.rs:26:26: 26:32 (#0), + span: $DIR/issue-75930-derive-cfg.rs:56:26: 56:32 (#0), }, Punct { ch: ',', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:26:32: 26:33 (#0), + span: $DIR/issue-75930-derive-cfg.rs:56:32: 56:33 (#0), }, Punct { ch: '#', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:27:5: 27:6 (#0), + span: $DIR/issue-75930-derive-cfg.rs:57:5: 57:6 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "cfg_attr", - span: $DIR/issue-75930-derive-cfg.rs:27:7: 27:15 (#0), + span: $DIR/issue-75930-derive-cfg.rs:57:7: 57:15 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "FALSE", - span: $DIR/issue-75930-derive-cfg.rs:27:16: 27:21 (#0), + span: $DIR/issue-75930-derive-cfg.rs:57:16: 57:21 (#0), }, Punct { ch: ',', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:27:21: 27:22 (#0), + span: $DIR/issue-75930-derive-cfg.rs:57:21: 57:22 (#0), }, Ident { ident: "deny", - span: $DIR/issue-75930-derive-cfg.rs:27:23: 27:27 (#0), + span: $DIR/issue-75930-derive-cfg.rs:57:23: 57:27 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "warnings", - span: $DIR/issue-75930-derive-cfg.rs:27:28: 27:36 (#0), + span: $DIR/issue-75930-derive-cfg.rs:57:28: 57:36 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:27:27: 27:37 (#0), + span: $DIR/issue-75930-derive-cfg.rs:57:27: 57:37 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:27:15: 27:38 (#0), + span: $DIR/issue-75930-derive-cfg.rs:57:15: 57:38 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:27:6: 27:39 (#0), + span: $DIR/issue-75930-derive-cfg.rs:57:6: 57:39 (#0), }, Ident { ident: "second", - span: $DIR/issue-75930-derive-cfg.rs:27:40: 27:46 (#0), + span: $DIR/issue-75930-derive-cfg.rs:57:40: 57:46 (#0), }, Punct { ch: ':', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:27:46: 27:47 (#0), + span: $DIR/issue-75930-derive-cfg.rs:57:46: 57:47 (#0), }, Ident { ident: "bool", - span: $DIR/issue-75930-derive-cfg.rs:27:48: 27:52 (#0), + span: $DIR/issue-75930-derive-cfg.rs:57:48: 57:52 (#0), }, Punct { ch: ',', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:27:52: 27:53 (#0), + span: $DIR/issue-75930-derive-cfg.rs:57:52: 57:53 (#0), }, Ident { ident: "third", - span: $DIR/issue-75930-derive-cfg.rs:28:5: 28:10 (#0), + span: $DIR/issue-75930-derive-cfg.rs:58:5: 58:10 (#0), }, Punct { ch: ':', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:28:10: 28:11 (#0), + span: $DIR/issue-75930-derive-cfg.rs:58:10: 58:11 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "u8", - span: $DIR/issue-75930-derive-cfg.rs:28:13: 28:15 (#0), + span: $DIR/issue-75930-derive-cfg.rs:58:13: 58:15 (#0), }, Punct { ch: ';', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:28:15: 28:16 (#0), + span: $DIR/issue-75930-derive-cfg.rs:58:15: 58:16 (#0), }, Group { delimiter: Brace, @@ -314,145 +314,145 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '#', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:29:9: 29:10 (#0), + span: $DIR/issue-75930-derive-cfg.rs:59:9: 59:10 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "cfg", - span: $DIR/issue-75930-derive-cfg.rs:29:11: 29:14 (#0), + span: $DIR/issue-75930-derive-cfg.rs:59:11: 59:14 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "FALSE", - span: $DIR/issue-75930-derive-cfg.rs:29:15: 29:20 (#0), + span: $DIR/issue-75930-derive-cfg.rs:59:15: 59:20 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:29:14: 29:21 (#0), + span: $DIR/issue-75930-derive-cfg.rs:59:14: 59:21 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:29:10: 29:22 (#0), + span: $DIR/issue-75930-derive-cfg.rs:59:10: 59:22 (#0), }, Ident { ident: "struct", - span: $DIR/issue-75930-derive-cfg.rs:29:23: 29:29 (#0), + span: $DIR/issue-75930-derive-cfg.rs:59:23: 59:29 (#0), }, Ident { ident: "Bar", - span: $DIR/issue-75930-derive-cfg.rs:29:30: 29:33 (#0), + span: $DIR/issue-75930-derive-cfg.rs:59:30: 59:33 (#0), }, Punct { ch: ';', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:29:33: 29:34 (#0), + span: $DIR/issue-75930-derive-cfg.rs:59:33: 59:34 (#0), }, Punct { ch: '#', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:30:9: 30:10 (#0), + span: $DIR/issue-75930-derive-cfg.rs:60:9: 60:10 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "cfg", - span: $DIR/issue-75930-derive-cfg.rs:30:11: 30:14 (#0), + span: $DIR/issue-75930-derive-cfg.rs:60:11: 60:14 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "not", - span: $DIR/issue-75930-derive-cfg.rs:30:15: 30:18 (#0), + span: $DIR/issue-75930-derive-cfg.rs:60:15: 60:18 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "FALSE", - span: $DIR/issue-75930-derive-cfg.rs:30:19: 30:24 (#0), + span: $DIR/issue-75930-derive-cfg.rs:60:19: 60:24 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:30:18: 30:25 (#0), + span: $DIR/issue-75930-derive-cfg.rs:60:18: 60:25 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:30:14: 30:26 (#0), + span: $DIR/issue-75930-derive-cfg.rs:60:14: 60:26 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:30:10: 30:27 (#0), + span: $DIR/issue-75930-derive-cfg.rs:60:10: 60:27 (#0), }, Ident { ident: "struct", - span: $DIR/issue-75930-derive-cfg.rs:30:28: 30:34 (#0), + span: $DIR/issue-75930-derive-cfg.rs:60:28: 60:34 (#0), }, Ident { ident: "Inner", - span: $DIR/issue-75930-derive-cfg.rs:30:35: 30:40 (#0), + span: $DIR/issue-75930-derive-cfg.rs:60:35: 60:40 (#0), }, Punct { ch: ';', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:30:40: 30:41 (#0), + span: $DIR/issue-75930-derive-cfg.rs:60:40: 60:41 (#0), }, Punct { ch: '#', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:31:9: 31:10 (#0), + span: $DIR/issue-75930-derive-cfg.rs:61:9: 61:10 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "cfg", - span: $DIR/issue-75930-derive-cfg.rs:31:11: 31:14 (#0), + span: $DIR/issue-75930-derive-cfg.rs:61:11: 61:14 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "FALSE", - span: $DIR/issue-75930-derive-cfg.rs:31:15: 31:20 (#0), + span: $DIR/issue-75930-derive-cfg.rs:61:15: 61:20 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:31:14: 31:21 (#0), + span: $DIR/issue-75930-derive-cfg.rs:61:14: 61:21 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:31:10: 31:22 (#0), + span: $DIR/issue-75930-derive-cfg.rs:61:10: 61:22 (#0), }, Ident { ident: "let", - span: $DIR/issue-75930-derive-cfg.rs:31:23: 31:26 (#0), + span: $DIR/issue-75930-derive-cfg.rs:61:23: 61:26 (#0), }, Ident { ident: "a", - span: $DIR/issue-75930-derive-cfg.rs:31:27: 31:28 (#0), + span: $DIR/issue-75930-derive-cfg.rs:61:27: 61:28 (#0), }, Punct { ch: '=', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:31:29: 31:30 (#0), + span: $DIR/issue-75930-derive-cfg.rs:61:29: 61:30 (#0), }, Literal { kind: Integer, symbol: "25", suffix: None, - span: $DIR/issue-75930-derive-cfg.rs:31:31: 31:33 (#0), + span: $DIR/issue-75930-derive-cfg.rs:61:31: 61:33 (#0), }, Punct { ch: ';', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:31:33: 31:34 (#0), + span: $DIR/issue-75930-derive-cfg.rs:61:33: 61:34 (#0), }, Ident { ident: "match", - span: $DIR/issue-75930-derive-cfg.rs:32:9: 32:14 (#0), + span: $DIR/issue-75930-derive-cfg.rs:62:9: 62:14 (#0), }, Ident { ident: "true", - span: $DIR/issue-75930-derive-cfg.rs:32:15: 32:19 (#0), + span: $DIR/issue-75930-derive-cfg.rs:62:15: 62:19 (#0), }, Group { delimiter: Brace, @@ -460,194 +460,194 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '#', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:33:13: 33:14 (#0), + span: $DIR/issue-75930-derive-cfg.rs:63:13: 63:14 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "cfg", - span: $DIR/issue-75930-derive-cfg.rs:33:15: 33:18 (#0), + span: $DIR/issue-75930-derive-cfg.rs:63:15: 63:18 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "FALSE", - span: $DIR/issue-75930-derive-cfg.rs:33:19: 33:24 (#0), + span: $DIR/issue-75930-derive-cfg.rs:63:19: 63:24 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:33:18: 33:25 (#0), + span: $DIR/issue-75930-derive-cfg.rs:63:18: 63:25 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:33:14: 33:26 (#0), + span: $DIR/issue-75930-derive-cfg.rs:63:14: 63:26 (#0), }, Ident { ident: "true", - span: $DIR/issue-75930-derive-cfg.rs:33:27: 33:31 (#0), + span: $DIR/issue-75930-derive-cfg.rs:63:27: 63:31 (#0), }, Punct { ch: '=', spacing: Joint, - span: $DIR/issue-75930-derive-cfg.rs:33:32: 33:33 (#0), + span: $DIR/issue-75930-derive-cfg.rs:63:32: 63:33 (#0), }, Punct { ch: '>', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:33:33: 33:34 (#0), + span: $DIR/issue-75930-derive-cfg.rs:63:33: 63:34 (#0), }, Group { delimiter: Brace, stream: TokenStream [], - span: $DIR/issue-75930-derive-cfg.rs:33:35: 33:37 (#0), + span: $DIR/issue-75930-derive-cfg.rs:63:35: 63:37 (#0), }, Punct { ch: ',', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:33:37: 33:38 (#0), + span: $DIR/issue-75930-derive-cfg.rs:63:37: 63:38 (#0), }, Punct { ch: '#', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:34:13: 34:14 (#0), + span: $DIR/issue-75930-derive-cfg.rs:64:13: 64:14 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "cfg_attr", - span: $DIR/issue-75930-derive-cfg.rs:34:15: 34:23 (#0), + span: $DIR/issue-75930-derive-cfg.rs:64:15: 64:23 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "not", - span: $DIR/issue-75930-derive-cfg.rs:34:24: 34:27 (#0), + span: $DIR/issue-75930-derive-cfg.rs:64:24: 64:27 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "FALSE", - span: $DIR/issue-75930-derive-cfg.rs:34:28: 34:33 (#0), + span: $DIR/issue-75930-derive-cfg.rs:64:28: 64:33 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:34:27: 34:34 (#0), + span: $DIR/issue-75930-derive-cfg.rs:64:27: 64:34 (#0), }, Punct { ch: ',', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:34:34: 34:35 (#0), + span: $DIR/issue-75930-derive-cfg.rs:64:34: 64:35 (#0), }, Ident { ident: "allow", - span: $DIR/issue-75930-derive-cfg.rs:34:36: 34:41 (#0), + span: $DIR/issue-75930-derive-cfg.rs:64:36: 64:41 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "warnings", - span: $DIR/issue-75930-derive-cfg.rs:34:42: 34:50 (#0), + span: $DIR/issue-75930-derive-cfg.rs:64:42: 64:50 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:34:41: 34:51 (#0), + span: $DIR/issue-75930-derive-cfg.rs:64:41: 64:51 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:34:23: 34:52 (#0), + span: $DIR/issue-75930-derive-cfg.rs:64:23: 64:52 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:34:14: 34:53 (#0), + span: $DIR/issue-75930-derive-cfg.rs:64:14: 64:53 (#0), }, Ident { ident: "false", - span: $DIR/issue-75930-derive-cfg.rs:34:54: 34:59 (#0), + span: $DIR/issue-75930-derive-cfg.rs:64:54: 64:59 (#0), }, Punct { ch: '=', spacing: Joint, - span: $DIR/issue-75930-derive-cfg.rs:34:60: 34:61 (#0), + span: $DIR/issue-75930-derive-cfg.rs:64:60: 64:61 (#0), }, Punct { ch: '>', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:34:61: 34:62 (#0), + span: $DIR/issue-75930-derive-cfg.rs:64:61: 64:62 (#0), }, Group { delimiter: Brace, stream: TokenStream [], - span: $DIR/issue-75930-derive-cfg.rs:34:63: 34:65 (#0), + span: $DIR/issue-75930-derive-cfg.rs:64:63: 64:65 (#0), }, Punct { ch: ',', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:34:65: 34:66 (#0), + span: $DIR/issue-75930-derive-cfg.rs:64:65: 64:66 (#0), }, Ident { ident: "_", - span: $DIR/issue-75930-derive-cfg.rs:35:13: 35:14 (#0), + span: $DIR/issue-75930-derive-cfg.rs:65:13: 65:14 (#0), }, Punct { ch: '=', spacing: Joint, - span: $DIR/issue-75930-derive-cfg.rs:35:15: 35:16 (#0), + span: $DIR/issue-75930-derive-cfg.rs:65:15: 65:16 (#0), }, Punct { ch: '>', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:35:16: 35:17 (#0), + span: $DIR/issue-75930-derive-cfg.rs:65:16: 65:17 (#0), }, Group { delimiter: Brace, stream: TokenStream [], - span: $DIR/issue-75930-derive-cfg.rs:35:18: 35:20 (#0), + span: $DIR/issue-75930-derive-cfg.rs:65:18: 65:20 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:32:20: 36:10 (#0), + span: $DIR/issue-75930-derive-cfg.rs:62:20: 66:10 (#0), }, Punct { ch: ';', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:36:10: 36:11 (#0), + span: $DIR/issue-75930-derive-cfg.rs:66:10: 66:11 (#0), }, Punct { ch: '#', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:38:9: 38:10 (#0), + span: $DIR/issue-75930-derive-cfg.rs:68:9: 68:10 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "print_helper", - span: $DIR/issue-75930-derive-cfg.rs:38:11: 38:23 (#0), + span: $DIR/issue-75930-derive-cfg.rs:68:11: 68:23 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "should_be_removed", - span: $DIR/issue-75930-derive-cfg.rs:38:24: 38:41 (#0), + span: $DIR/issue-75930-derive-cfg.rs:68:24: 68:41 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:38:23: 38:42 (#0), + span: $DIR/issue-75930-derive-cfg.rs:68:23: 68:42 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:38:10: 38:43 (#0), + span: $DIR/issue-75930-derive-cfg.rs:68:10: 68:43 (#0), }, Ident { ident: "fn", - span: $DIR/issue-75930-derive-cfg.rs:39:9: 39:11 (#0), + span: $DIR/issue-75930-derive-cfg.rs:69:9: 69:11 (#0), }, Ident { ident: "removed_fn", - span: $DIR/issue-75930-derive-cfg.rs:39:12: 39:22 (#0), + span: $DIR/issue-75930-derive-cfg.rs:69:12: 69:22 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [], - span: $DIR/issue-75930-derive-cfg.rs:39:22: 39:24 (#0), + span: $DIR/issue-75930-derive-cfg.rs:69:22: 69:24 (#0), }, Group { delimiter: Brace, @@ -655,108 +655,108 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '#', spacing: Joint, - span: $DIR/issue-75930-derive-cfg.rs:40:13: 40:14 (#0), + span: $DIR/issue-75930-derive-cfg.rs:70:13: 70:14 (#0), }, Punct { ch: '!', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:40:14: 40:15 (#0), + span: $DIR/issue-75930-derive-cfg.rs:70:14: 70:15 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "cfg", - span: $DIR/issue-75930-derive-cfg.rs:40:16: 40:19 (#0), + span: $DIR/issue-75930-derive-cfg.rs:70:16: 70:19 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "FALSE", - span: $DIR/issue-75930-derive-cfg.rs:40:20: 40:25 (#0), + span: $DIR/issue-75930-derive-cfg.rs:70:20: 70:25 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:40:19: 40:26 (#0), + span: $DIR/issue-75930-derive-cfg.rs:70:19: 70:26 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:40:15: 40:27 (#0), + span: $DIR/issue-75930-derive-cfg.rs:70:15: 70:27 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:39:25: 41:10 (#0), + span: $DIR/issue-75930-derive-cfg.rs:69:25: 71:10 (#0), }, Punct { ch: '#', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:43:9: 43:10 (#0), + span: $DIR/issue-75930-derive-cfg.rs:73:9: 73:10 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "print_helper", - span: $DIR/issue-75930-derive-cfg.rs:43:11: 43:23 (#0), + span: $DIR/issue-75930-derive-cfg.rs:73:11: 73:23 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "c", - span: $DIR/issue-75930-derive-cfg.rs:43:24: 43:25 (#0), + span: $DIR/issue-75930-derive-cfg.rs:73:24: 73:25 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:43:23: 43:26 (#0), + span: $DIR/issue-75930-derive-cfg.rs:73:23: 73:26 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:43:10: 43:27 (#0), + span: $DIR/issue-75930-derive-cfg.rs:73:10: 73:27 (#0), }, Punct { ch: '#', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:43:28: 43:29 (#0), + span: $DIR/issue-75930-derive-cfg.rs:73:28: 73:29 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "cfg", - span: $DIR/issue-75930-derive-cfg.rs:43:30: 43:33 (#0), + span: $DIR/issue-75930-derive-cfg.rs:73:30: 73:33 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "not", - span: $DIR/issue-75930-derive-cfg.rs:43:34: 43:37 (#0), + span: $DIR/issue-75930-derive-cfg.rs:73:34: 73:37 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "FALSE", - span: $DIR/issue-75930-derive-cfg.rs:43:38: 43:43 (#0), + span: $DIR/issue-75930-derive-cfg.rs:73:38: 73:43 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:43:37: 43:44 (#0), + span: $DIR/issue-75930-derive-cfg.rs:73:37: 73:44 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:43:33: 43:45 (#0), + span: $DIR/issue-75930-derive-cfg.rs:73:33: 73:45 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:43:29: 43:46 (#0), + span: $DIR/issue-75930-derive-cfg.rs:73:29: 73:46 (#0), }, Ident { ident: "fn", - span: $DIR/issue-75930-derive-cfg.rs:43:47: 43:49 (#0), + span: $DIR/issue-75930-derive-cfg.rs:73:47: 73:49 (#0), }, Ident { ident: "kept_fn", - span: $DIR/issue-75930-derive-cfg.rs:43:50: 43:57 (#0), + span: $DIR/issue-75930-derive-cfg.rs:73:50: 73:57 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [], - span: $DIR/issue-75930-derive-cfg.rs:43:57: 43:59 (#0), + span: $DIR/issue-75930-derive-cfg.rs:73:57: 73:59 (#0), }, Group { delimiter: Brace, @@ -764,82 +764,82 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '#', spacing: Joint, - span: $DIR/issue-75930-derive-cfg.rs:44:13: 44:14 (#0), + span: $DIR/issue-75930-derive-cfg.rs:74:13: 74:14 (#0), }, Punct { ch: '!', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:44:14: 44:15 (#0), + span: $DIR/issue-75930-derive-cfg.rs:74:14: 74:15 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "cfg", - span: $DIR/issue-75930-derive-cfg.rs:44:16: 44:19 (#0), + span: $DIR/issue-75930-derive-cfg.rs:74:16: 74:19 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "not", - span: $DIR/issue-75930-derive-cfg.rs:44:20: 44:23 (#0), + span: $DIR/issue-75930-derive-cfg.rs:74:20: 74:23 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "FALSE", - span: $DIR/issue-75930-derive-cfg.rs:44:24: 44:29 (#0), + span: $DIR/issue-75930-derive-cfg.rs:74:24: 74:29 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:44:23: 44:30 (#0), + span: $DIR/issue-75930-derive-cfg.rs:74:23: 74:30 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:44:19: 44:31 (#0), + span: $DIR/issue-75930-derive-cfg.rs:74:19: 74:31 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:44:15: 44:32 (#0), + span: $DIR/issue-75930-derive-cfg.rs:74:15: 74:32 (#0), }, Ident { ident: "let", - span: $DIR/issue-75930-derive-cfg.rs:45:13: 45:16 (#0), + span: $DIR/issue-75930-derive-cfg.rs:75:13: 75:16 (#0), }, Ident { ident: "my_val", - span: $DIR/issue-75930-derive-cfg.rs:45:17: 45:23 (#0), + span: $DIR/issue-75930-derive-cfg.rs:75:17: 75:23 (#0), }, Punct { ch: '=', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:45:24: 45:25 (#0), + span: $DIR/issue-75930-derive-cfg.rs:75:24: 75:25 (#0), }, Ident { ident: "true", - span: $DIR/issue-75930-derive-cfg.rs:45:26: 45:30 (#0), + span: $DIR/issue-75930-derive-cfg.rs:75:26: 75:30 (#0), }, Punct { ch: ';', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:45:30: 45:31 (#0), + span: $DIR/issue-75930-derive-cfg.rs:75:30: 75:31 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:43:60: 46:10 (#0), + span: $DIR/issue-75930-derive-cfg.rs:73:60: 76:10 (#0), }, Ident { ident: "enum", - span: $DIR/issue-75930-derive-cfg.rs:48:9: 48:13 (#0), + span: $DIR/issue-75930-derive-cfg.rs:78:9: 78:13 (#0), }, Ident { ident: "TupleEnum", - span: $DIR/issue-75930-derive-cfg.rs:48:14: 48:23 (#0), + span: $DIR/issue-75930-derive-cfg.rs:78:14: 78:23 (#0), }, Group { delimiter: Brace, stream: TokenStream [ Ident { ident: "Foo", - span: $DIR/issue-75930-derive-cfg.rs:49:13: 49:16 (#0), + span: $DIR/issue-75930-derive-cfg.rs:79:13: 79:16 (#0), }, Group { delimiter: Parenthesis, @@ -847,166 +847,166 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '#', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:50:17: 50:18 (#0), + span: $DIR/issue-75930-derive-cfg.rs:80:17: 80:18 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "cfg", - span: $DIR/issue-75930-derive-cfg.rs:50:19: 50:22 (#0), + span: $DIR/issue-75930-derive-cfg.rs:80:19: 80:22 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "FALSE", - span: $DIR/issue-75930-derive-cfg.rs:50:23: 50:28 (#0), + span: $DIR/issue-75930-derive-cfg.rs:80:23: 80:28 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:50:22: 50:29 (#0), + span: $DIR/issue-75930-derive-cfg.rs:80:22: 80:29 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:50:18: 50:30 (#0), + span: $DIR/issue-75930-derive-cfg.rs:80:18: 80:30 (#0), }, Ident { ident: "u8", - span: $DIR/issue-75930-derive-cfg.rs:50:31: 50:33 (#0), + span: $DIR/issue-75930-derive-cfg.rs:80:31: 80:33 (#0), }, Punct { ch: ',', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:50:33: 50:34 (#0), + span: $DIR/issue-75930-derive-cfg.rs:80:33: 80:34 (#0), }, Punct { ch: '#', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:51:17: 51:18 (#0), + span: $DIR/issue-75930-derive-cfg.rs:81:17: 81:18 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "cfg", - span: $DIR/issue-75930-derive-cfg.rs:51:19: 51:22 (#0), + span: $DIR/issue-75930-derive-cfg.rs:81:19: 81:22 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "FALSE", - span: $DIR/issue-75930-derive-cfg.rs:51:23: 51:28 (#0), + span: $DIR/issue-75930-derive-cfg.rs:81:23: 81:28 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:51:22: 51:29 (#0), + span: $DIR/issue-75930-derive-cfg.rs:81:22: 81:29 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:51:18: 51:30 (#0), + span: $DIR/issue-75930-derive-cfg.rs:81:18: 81:30 (#0), }, Ident { ident: "bool", - span: $DIR/issue-75930-derive-cfg.rs:51:31: 51:35 (#0), + span: $DIR/issue-75930-derive-cfg.rs:81:31: 81:35 (#0), }, Punct { ch: ',', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:51:35: 51:36 (#0), + span: $DIR/issue-75930-derive-cfg.rs:81:35: 81:36 (#0), }, Punct { ch: '#', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:52:17: 52:18 (#0), + span: $DIR/issue-75930-derive-cfg.rs:82:17: 82:18 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "cfg", - span: $DIR/issue-75930-derive-cfg.rs:52:19: 52:22 (#0), + span: $DIR/issue-75930-derive-cfg.rs:82:19: 82:22 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "not", - span: $DIR/issue-75930-derive-cfg.rs:52:23: 52:26 (#0), + span: $DIR/issue-75930-derive-cfg.rs:82:23: 82:26 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "FALSE", - span: $DIR/issue-75930-derive-cfg.rs:52:27: 52:32 (#0), + span: $DIR/issue-75930-derive-cfg.rs:82:27: 82:32 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:52:26: 52:33 (#0), + span: $DIR/issue-75930-derive-cfg.rs:82:26: 82:33 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:52:22: 52:34 (#0), + span: $DIR/issue-75930-derive-cfg.rs:82:22: 82:34 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:52:18: 52:35 (#0), + span: $DIR/issue-75930-derive-cfg.rs:82:18: 82:35 (#0), }, Ident { ident: "i32", - span: $DIR/issue-75930-derive-cfg.rs:52:36: 52:39 (#0), + span: $DIR/issue-75930-derive-cfg.rs:82:36: 82:39 (#0), }, Punct { ch: ',', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:52:39: 52:40 (#0), + span: $DIR/issue-75930-derive-cfg.rs:82:39: 82:40 (#0), }, Punct { ch: '#', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:53:17: 53:18 (#0), + span: $DIR/issue-75930-derive-cfg.rs:83:17: 83:18 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "cfg", - span: $DIR/issue-75930-derive-cfg.rs:53:19: 53:22 (#0), + span: $DIR/issue-75930-derive-cfg.rs:83:19: 83:22 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "FALSE", - span: $DIR/issue-75930-derive-cfg.rs:53:23: 53:28 (#0), + span: $DIR/issue-75930-derive-cfg.rs:83:23: 83:28 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:53:22: 53:29 (#0), + span: $DIR/issue-75930-derive-cfg.rs:83:22: 83:29 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:53:18: 53:30 (#0), + span: $DIR/issue-75930-derive-cfg.rs:83:18: 83:30 (#0), }, Ident { ident: "String", - span: $DIR/issue-75930-derive-cfg.rs:53:31: 53:37 (#0), + span: $DIR/issue-75930-derive-cfg.rs:83:31: 83:37 (#0), }, Punct { ch: ',', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:53:37: 53:38 (#0), + span: $DIR/issue-75930-derive-cfg.rs:83:37: 83:38 (#0), }, Ident { ident: "u8", - span: $DIR/issue-75930-derive-cfg.rs:53:39: 53:41 (#0), + span: $DIR/issue-75930-derive-cfg.rs:83:39: 83:41 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:49:16: 54:14 (#0), + span: $DIR/issue-75930-derive-cfg.rs:79:16: 84:14 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:48:24: 55:10 (#0), + span: $DIR/issue-75930-derive-cfg.rs:78:24: 85:10 (#0), }, Ident { ident: "struct", - span: $DIR/issue-75930-derive-cfg.rs:57:9: 57:15 (#0), + span: $DIR/issue-75930-derive-cfg.rs:87:9: 87:15 (#0), }, Ident { ident: "TupleStruct", - span: $DIR/issue-75930-derive-cfg.rs:57:16: 57:27 (#0), + span: $DIR/issue-75930-derive-cfg.rs:87:16: 87:27 (#0), }, Group { delimiter: Parenthesis, @@ -1014,139 +1014,139 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '#', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:58:13: 58:14 (#0), + span: $DIR/issue-75930-derive-cfg.rs:88:13: 88:14 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "cfg", - span: $DIR/issue-75930-derive-cfg.rs:58:15: 58:18 (#0), + span: $DIR/issue-75930-derive-cfg.rs:88:15: 88:18 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "FALSE", - span: $DIR/issue-75930-derive-cfg.rs:58:19: 58:24 (#0), + span: $DIR/issue-75930-derive-cfg.rs:88:19: 88:24 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:58:18: 58:25 (#0), + span: $DIR/issue-75930-derive-cfg.rs:88:18: 88:25 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:58:14: 58:26 (#0), + span: $DIR/issue-75930-derive-cfg.rs:88:14: 88:26 (#0), }, Ident { ident: "String", - span: $DIR/issue-75930-derive-cfg.rs:58:27: 58:33 (#0), + span: $DIR/issue-75930-derive-cfg.rs:88:27: 88:33 (#0), }, Punct { ch: ',', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:58:33: 58:34 (#0), + span: $DIR/issue-75930-derive-cfg.rs:88:33: 88:34 (#0), }, Punct { ch: '#', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:59:13: 59:14 (#0), + span: $DIR/issue-75930-derive-cfg.rs:89:13: 89:14 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "cfg", - span: $DIR/issue-75930-derive-cfg.rs:59:15: 59:18 (#0), + span: $DIR/issue-75930-derive-cfg.rs:89:15: 89:18 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "not", - span: $DIR/issue-75930-derive-cfg.rs:59:19: 59:22 (#0), + span: $DIR/issue-75930-derive-cfg.rs:89:19: 89:22 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "FALSE", - span: $DIR/issue-75930-derive-cfg.rs:59:23: 59:28 (#0), + span: $DIR/issue-75930-derive-cfg.rs:89:23: 89:28 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:59:22: 59:29 (#0), + span: $DIR/issue-75930-derive-cfg.rs:89:22: 89:29 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:59:18: 59:30 (#0), + span: $DIR/issue-75930-derive-cfg.rs:89:18: 89:30 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:59:14: 59:31 (#0), + span: $DIR/issue-75930-derive-cfg.rs:89:14: 89:31 (#0), }, Ident { ident: "i32", - span: $DIR/issue-75930-derive-cfg.rs:59:32: 59:35 (#0), + span: $DIR/issue-75930-derive-cfg.rs:89:32: 89:35 (#0), }, Punct { ch: ',', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:59:35: 59:36 (#0), + span: $DIR/issue-75930-derive-cfg.rs:89:35: 89:36 (#0), }, Punct { ch: '#', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:60:13: 60:14 (#0), + span: $DIR/issue-75930-derive-cfg.rs:90:13: 90:14 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "cfg", - span: $DIR/issue-75930-derive-cfg.rs:60:15: 60:18 (#0), + span: $DIR/issue-75930-derive-cfg.rs:90:15: 90:18 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "FALSE", - span: $DIR/issue-75930-derive-cfg.rs:60:19: 60:24 (#0), + span: $DIR/issue-75930-derive-cfg.rs:90:19: 90:24 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:60:18: 60:25 (#0), + span: $DIR/issue-75930-derive-cfg.rs:90:18: 90:25 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:60:14: 60:26 (#0), + span: $DIR/issue-75930-derive-cfg.rs:90:14: 90:26 (#0), }, Ident { ident: "bool", - span: $DIR/issue-75930-derive-cfg.rs:60:27: 60:31 (#0), + span: $DIR/issue-75930-derive-cfg.rs:90:27: 90:31 (#0), }, Punct { ch: ',', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:60:31: 60:32 (#0), + span: $DIR/issue-75930-derive-cfg.rs:90:31: 90:32 (#0), }, Ident { ident: "u8", - span: $DIR/issue-75930-derive-cfg.rs:61:13: 61:15 (#0), + span: $DIR/issue-75930-derive-cfg.rs:91:13: 91:15 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:57:27: 62:10 (#0), + span: $DIR/issue-75930-derive-cfg.rs:87:27: 92:10 (#0), }, Punct { ch: ';', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:62:10: 62:11 (#0), + span: $DIR/issue-75930-derive-cfg.rs:92:10: 92:11 (#0), }, Ident { ident: "fn", - span: $DIR/issue-75930-derive-cfg.rs:64:9: 64:11 (#0), + span: $DIR/issue-75930-derive-cfg.rs:94:9: 94:11 (#0), }, Ident { ident: "plain_removed_fn", - span: $DIR/issue-75930-derive-cfg.rs:64:12: 64:28 (#0), + span: $DIR/issue-75930-derive-cfg.rs:94:12: 94:28 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [], - span: $DIR/issue-75930-derive-cfg.rs:64:28: 64:30 (#0), + span: $DIR/issue-75930-derive-cfg.rs:94:28: 94:30 (#0), }, Group { delimiter: Brace, @@ -1154,122 +1154,122 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '#', spacing: Joint, - span: $DIR/issue-75930-derive-cfg.rs:65:13: 65:14 (#0), + span: $DIR/issue-75930-derive-cfg.rs:95:13: 95:14 (#0), }, Punct { ch: '!', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:65:14: 65:15 (#0), + span: $DIR/issue-75930-derive-cfg.rs:95:14: 95:15 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "cfg_attr", - span: $DIR/issue-75930-derive-cfg.rs:65:16: 65:24 (#0), + span: $DIR/issue-75930-derive-cfg.rs:95:16: 95:24 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "not", - span: $DIR/issue-75930-derive-cfg.rs:65:25: 65:28 (#0), + span: $DIR/issue-75930-derive-cfg.rs:95:25: 95:28 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "FALSE", - span: $DIR/issue-75930-derive-cfg.rs:65:29: 65:34 (#0), + span: $DIR/issue-75930-derive-cfg.rs:95:29: 95:34 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:65:28: 65:35 (#0), + span: $DIR/issue-75930-derive-cfg.rs:95:28: 95:35 (#0), }, Punct { ch: ',', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:65:35: 65:36 (#0), + span: $DIR/issue-75930-derive-cfg.rs:95:35: 95:36 (#0), }, Ident { ident: "cfg", - span: $DIR/issue-75930-derive-cfg.rs:65:37: 65:40 (#0), + span: $DIR/issue-75930-derive-cfg.rs:95:37: 95:40 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "FALSE", - span: $DIR/issue-75930-derive-cfg.rs:65:41: 65:46 (#0), + span: $DIR/issue-75930-derive-cfg.rs:95:41: 95:46 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:65:40: 65:47 (#0), + span: $DIR/issue-75930-derive-cfg.rs:95:40: 95:47 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:65:24: 65:48 (#0), + span: $DIR/issue-75930-derive-cfg.rs:95:24: 95:48 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:65:15: 65:49 (#0), + span: $DIR/issue-75930-derive-cfg.rs:95:15: 95:49 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:64:31: 66:10 (#0), + span: $DIR/issue-75930-derive-cfg.rs:94:31: 96:10 (#0), }, Literal { kind: Integer, symbol: "0", suffix: None, - span: $DIR/issue-75930-derive-cfg.rs:68:9: 68:10 (#0), + span: $DIR/issue-75930-derive-cfg.rs:98:9: 98:10 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:28:17: 69:6 (#0), + span: $DIR/issue-75930-derive-cfg.rs:58:17: 99:6 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:28:12: 69:7 (#0), + span: $DIR/issue-75930-derive-cfg.rs:58:12: 99:7 (#0), }, Punct { ch: ',', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:69:7: 69:8 (#0), + span: $DIR/issue-75930-derive-cfg.rs:99:7: 99:8 (#0), }, Punct { ch: '#', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:70:5: 70:6 (#0), + span: $DIR/issue-75930-derive-cfg.rs:100:5: 100:6 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "print_helper", - span: $DIR/issue-75930-derive-cfg.rs:70:7: 70:19 (#0), + span: $DIR/issue-75930-derive-cfg.rs:100:7: 100:19 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "d", - span: $DIR/issue-75930-derive-cfg.rs:70:20: 70:21 (#0), + span: $DIR/issue-75930-derive-cfg.rs:100:20: 100:21 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:70:19: 70:22 (#0), + span: $DIR/issue-75930-derive-cfg.rs:100:19: 100:22 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:70:6: 70:23 (#0), + span: $DIR/issue-75930-derive-cfg.rs:100:6: 100:23 (#0), }, Ident { ident: "fourth", - span: $DIR/issue-75930-derive-cfg.rs:71:5: 71:11 (#0), + span: $DIR/issue-75930-derive-cfg.rs:101:5: 101:11 (#0), }, Punct { ch: ':', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:71:11: 71:12 (#0), + span: $DIR/issue-75930-derive-cfg.rs:101:11: 101:12 (#0), }, Ident { ident: "B", - span: $DIR/issue-75930-derive-cfg.rs:71:13: 71:14 (#0), + span: $DIR/issue-75930-derive-cfg.rs:101:13: 101:14 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:25:32: 72:2 (#0), + span: $DIR/issue-75930-derive-cfg.rs:55:32: 102:2 (#0), }, ] PRINT-DERIVE INPUT (DISPLAY): #[print_helper(a)] #[allow(dead_code)] #[print_helper(b)] struct Foo < B > @@ -1289,141 +1289,141 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [ Punct { ch: '#', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:19:1: 19:2 (#0), + span: $DIR/issue-75930-derive-cfg.rs:49:1: 49:2 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "print_helper", - span: $DIR/issue-75930-derive-cfg.rs:19:3: 19:15 (#0), + span: $DIR/issue-75930-derive-cfg.rs:49:3: 49:15 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "a", - span: $DIR/issue-75930-derive-cfg.rs:19:16: 19:17 (#0), + span: $DIR/issue-75930-derive-cfg.rs:49:16: 49:17 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:19:15: 19:18 (#0), + span: $DIR/issue-75930-derive-cfg.rs:49:15: 49:18 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:19:2: 19:19 (#0), + span: $DIR/issue-75930-derive-cfg.rs:49:2: 49:19 (#0), }, Punct { ch: '#', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:21:1: 21:2 (#0), + span: $DIR/issue-75930-derive-cfg.rs:51:1: 51:2 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "allow", - span: $DIR/issue-75930-derive-cfg.rs:21:24: 21:29 (#0), + span: $DIR/issue-75930-derive-cfg.rs:51:24: 51:29 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "dead_code", - span: $DIR/issue-75930-derive-cfg.rs:21:30: 21:39 (#0), + span: $DIR/issue-75930-derive-cfg.rs:51:30: 51:39 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:21:29: 21:40 (#0), + span: $DIR/issue-75930-derive-cfg.rs:51:29: 51:40 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:21:1: 21:2 (#0), + span: $DIR/issue-75930-derive-cfg.rs:51:1: 51:2 (#0), }, Punct { ch: '#', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:24:1: 24:2 (#0), + span: $DIR/issue-75930-derive-cfg.rs:54:1: 54:2 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "print_helper", - span: $DIR/issue-75930-derive-cfg.rs:24:3: 24:15 (#0), + span: $DIR/issue-75930-derive-cfg.rs:54:3: 54:15 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "b", - span: $DIR/issue-75930-derive-cfg.rs:24:16: 24:17 (#0), + span: $DIR/issue-75930-derive-cfg.rs:54:16: 54:17 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:24:15: 24:18 (#0), + span: $DIR/issue-75930-derive-cfg.rs:54:15: 54:18 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:24:2: 24:19 (#0), + span: $DIR/issue-75930-derive-cfg.rs:54:2: 54:19 (#0), }, Ident { ident: "struct", - span: $DIR/issue-75930-derive-cfg.rs:25:1: 25:7 (#0), + span: $DIR/issue-75930-derive-cfg.rs:55:1: 55:7 (#0), }, Ident { ident: "Foo", - span: $DIR/issue-75930-derive-cfg.rs:25:8: 25:11 (#0), + span: $DIR/issue-75930-derive-cfg.rs:55:8: 55:11 (#0), }, Punct { ch: '<', spacing: Joint, - span: $DIR/issue-75930-derive-cfg.rs:25:11: 25:12 (#0), + span: $DIR/issue-75930-derive-cfg.rs:55:11: 55:12 (#0), }, Ident { ident: "B", - span: $DIR/issue-75930-derive-cfg.rs:25:29: 25:30 (#0), + span: $DIR/issue-75930-derive-cfg.rs:55:29: 55:30 (#0), }, Punct { ch: '>', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:25:30: 25:31 (#0), + span: $DIR/issue-75930-derive-cfg.rs:55:30: 55:31 (#0), }, Group { delimiter: Brace, stream: TokenStream [ Ident { ident: "second", - span: $DIR/issue-75930-derive-cfg.rs:27:40: 27:46 (#0), + span: $DIR/issue-75930-derive-cfg.rs:57:40: 57:46 (#0), }, Punct { ch: ':', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:27:46: 27:47 (#0), + span: $DIR/issue-75930-derive-cfg.rs:57:46: 57:47 (#0), }, Ident { ident: "bool", - span: $DIR/issue-75930-derive-cfg.rs:27:48: 27:52 (#0), + span: $DIR/issue-75930-derive-cfg.rs:57:48: 57:52 (#0), }, Punct { ch: ',', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:27:52: 27:53 (#0), + span: $DIR/issue-75930-derive-cfg.rs:57:52: 57:53 (#0), }, Ident { ident: "third", - span: $DIR/issue-75930-derive-cfg.rs:28:5: 28:10 (#0), + span: $DIR/issue-75930-derive-cfg.rs:58:5: 58:10 (#0), }, Punct { ch: ':', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:28:10: 28:11 (#0), + span: $DIR/issue-75930-derive-cfg.rs:58:10: 58:11 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "u8", - span: $DIR/issue-75930-derive-cfg.rs:28:13: 28:15 (#0), + span: $DIR/issue-75930-derive-cfg.rs:58:13: 58:15 (#0), }, Punct { ch: ';', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:28:15: 28:16 (#0), + span: $DIR/issue-75930-derive-cfg.rs:58:15: 58:16 (#0), }, Group { delimiter: Brace, @@ -1431,58 +1431,58 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [ Punct { ch: '#', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:30:9: 30:10 (#0), + span: $DIR/issue-75930-derive-cfg.rs:60:9: 60:10 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "cfg", - span: $DIR/issue-75930-derive-cfg.rs:30:11: 30:14 (#0), + span: $DIR/issue-75930-derive-cfg.rs:60:11: 60:14 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "not", - span: $DIR/issue-75930-derive-cfg.rs:30:15: 30:18 (#0), + span: $DIR/issue-75930-derive-cfg.rs:60:15: 60:18 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "FALSE", - span: $DIR/issue-75930-derive-cfg.rs:30:19: 30:24 (#0), + span: $DIR/issue-75930-derive-cfg.rs:60:19: 60:24 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:30:18: 30:25 (#0), + span: $DIR/issue-75930-derive-cfg.rs:60:18: 60:25 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:30:14: 30:26 (#0), + span: $DIR/issue-75930-derive-cfg.rs:60:14: 60:26 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:30:10: 30:27 (#0), + span: $DIR/issue-75930-derive-cfg.rs:60:10: 60:27 (#0), }, Ident { ident: "struct", - span: $DIR/issue-75930-derive-cfg.rs:30:28: 30:34 (#0), + span: $DIR/issue-75930-derive-cfg.rs:60:28: 60:34 (#0), }, Ident { ident: "Inner", - span: $DIR/issue-75930-derive-cfg.rs:30:35: 30:40 (#0), + span: $DIR/issue-75930-derive-cfg.rs:60:35: 60:40 (#0), }, Punct { ch: ';', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:30:40: 30:41 (#0), + span: $DIR/issue-75930-derive-cfg.rs:60:40: 60:41 (#0), }, Ident { ident: "match", - span: $DIR/issue-75930-derive-cfg.rs:32:9: 32:14 (#0), + span: $DIR/issue-75930-derive-cfg.rs:62:9: 62:14 (#0), }, Ident { ident: "true", - span: $DIR/issue-75930-derive-cfg.rs:32:15: 32:19 (#0), + span: $DIR/issue-75930-derive-cfg.rs:62:15: 62:19 (#0), }, Group { delimiter: Brace, @@ -1490,151 +1490,151 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [ Punct { ch: '#', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:34:13: 34:14 (#0), + span: $DIR/issue-75930-derive-cfg.rs:64:13: 64:14 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "allow", - span: $DIR/issue-75930-derive-cfg.rs:34:36: 34:41 (#0), + span: $DIR/issue-75930-derive-cfg.rs:64:36: 64:41 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "warnings", - span: $DIR/issue-75930-derive-cfg.rs:34:42: 34:50 (#0), + span: $DIR/issue-75930-derive-cfg.rs:64:42: 64:50 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:34:41: 34:51 (#0), + span: $DIR/issue-75930-derive-cfg.rs:64:41: 64:51 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:34:13: 34:14 (#0), + span: $DIR/issue-75930-derive-cfg.rs:64:13: 64:14 (#0), }, Ident { ident: "false", - span: $DIR/issue-75930-derive-cfg.rs:34:54: 34:59 (#0), + span: $DIR/issue-75930-derive-cfg.rs:64:54: 64:59 (#0), }, Punct { ch: '=', spacing: Joint, - span: $DIR/issue-75930-derive-cfg.rs:34:60: 34:61 (#0), + span: $DIR/issue-75930-derive-cfg.rs:64:60: 64:61 (#0), }, Punct { ch: '>', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:34:61: 34:62 (#0), + span: $DIR/issue-75930-derive-cfg.rs:64:61: 64:62 (#0), }, Group { delimiter: Brace, stream: TokenStream [], - span: $DIR/issue-75930-derive-cfg.rs:34:63: 34:65 (#0), + span: $DIR/issue-75930-derive-cfg.rs:64:63: 64:65 (#0), }, Punct { ch: ',', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:34:65: 34:66 (#0), + span: $DIR/issue-75930-derive-cfg.rs:64:65: 64:66 (#0), }, Ident { ident: "_", - span: $DIR/issue-75930-derive-cfg.rs:35:13: 35:14 (#0), + span: $DIR/issue-75930-derive-cfg.rs:65:13: 65:14 (#0), }, Punct { ch: '=', spacing: Joint, - span: $DIR/issue-75930-derive-cfg.rs:35:15: 35:16 (#0), + span: $DIR/issue-75930-derive-cfg.rs:65:15: 65:16 (#0), }, Punct { ch: '>', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:35:16: 35:17 (#0), + span: $DIR/issue-75930-derive-cfg.rs:65:16: 65:17 (#0), }, Group { delimiter: Brace, stream: TokenStream [], - span: $DIR/issue-75930-derive-cfg.rs:35:18: 35:20 (#0), + span: $DIR/issue-75930-derive-cfg.rs:65:18: 65:20 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:32:20: 36:10 (#0), + span: $DIR/issue-75930-derive-cfg.rs:62:20: 66:10 (#0), }, Punct { ch: ';', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:36:10: 36:11 (#0), + span: $DIR/issue-75930-derive-cfg.rs:66:10: 66:11 (#0), }, Punct { ch: '#', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:43:9: 43:10 (#0), + span: $DIR/issue-75930-derive-cfg.rs:73:9: 73:10 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "print_helper", - span: $DIR/issue-75930-derive-cfg.rs:43:11: 43:23 (#0), + span: $DIR/issue-75930-derive-cfg.rs:73:11: 73:23 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "c", - span: $DIR/issue-75930-derive-cfg.rs:43:24: 43:25 (#0), + span: $DIR/issue-75930-derive-cfg.rs:73:24: 73:25 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:43:23: 43:26 (#0), + span: $DIR/issue-75930-derive-cfg.rs:73:23: 73:26 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:43:10: 43:27 (#0), + span: $DIR/issue-75930-derive-cfg.rs:73:10: 73:27 (#0), }, Punct { ch: '#', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:43:28: 43:29 (#0), + span: $DIR/issue-75930-derive-cfg.rs:73:28: 73:29 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "cfg", - span: $DIR/issue-75930-derive-cfg.rs:43:30: 43:33 (#0), + span: $DIR/issue-75930-derive-cfg.rs:73:30: 73:33 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "not", - span: $DIR/issue-75930-derive-cfg.rs:43:34: 43:37 (#0), + span: $DIR/issue-75930-derive-cfg.rs:73:34: 73:37 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "FALSE", - span: $DIR/issue-75930-derive-cfg.rs:43:38: 43:43 (#0), + span: $DIR/issue-75930-derive-cfg.rs:73:38: 73:43 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:43:37: 43:44 (#0), + span: $DIR/issue-75930-derive-cfg.rs:73:37: 73:44 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:43:33: 43:45 (#0), + span: $DIR/issue-75930-derive-cfg.rs:73:33: 73:45 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:43:29: 43:46 (#0), + span: $DIR/issue-75930-derive-cfg.rs:73:29: 73:46 (#0), }, Ident { ident: "fn", - span: $DIR/issue-75930-derive-cfg.rs:43:47: 43:49 (#0), + span: $DIR/issue-75930-derive-cfg.rs:73:47: 73:49 (#0), }, Ident { ident: "kept_fn", - span: $DIR/issue-75930-derive-cfg.rs:43:50: 43:57 (#0), + span: $DIR/issue-75930-derive-cfg.rs:73:50: 73:57 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [], - span: $DIR/issue-75930-derive-cfg.rs:43:57: 43:59 (#0), + span: $DIR/issue-75930-derive-cfg.rs:73:57: 73:59 (#0), }, Group { delimiter: Brace, @@ -1642,82 +1642,82 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [ Punct { ch: '#', spacing: Joint, - span: $DIR/issue-75930-derive-cfg.rs:44:13: 44:14 (#0), + span: $DIR/issue-75930-derive-cfg.rs:74:13: 74:14 (#0), }, Punct { ch: '!', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:44:14: 44:15 (#0), + span: $DIR/issue-75930-derive-cfg.rs:74:14: 74:15 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "cfg", - span: $DIR/issue-75930-derive-cfg.rs:44:16: 44:19 (#0), + span: $DIR/issue-75930-derive-cfg.rs:74:16: 74:19 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "not", - span: $DIR/issue-75930-derive-cfg.rs:44:20: 44:23 (#0), + span: $DIR/issue-75930-derive-cfg.rs:74:20: 74:23 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "FALSE", - span: $DIR/issue-75930-derive-cfg.rs:44:24: 44:29 (#0), + span: $DIR/issue-75930-derive-cfg.rs:74:24: 74:29 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:44:23: 44:30 (#0), + span: $DIR/issue-75930-derive-cfg.rs:74:23: 74:30 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:44:19: 44:31 (#0), + span: $DIR/issue-75930-derive-cfg.rs:74:19: 74:31 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:44:15: 44:32 (#0), + span: $DIR/issue-75930-derive-cfg.rs:74:15: 74:32 (#0), }, Ident { ident: "let", - span: $DIR/issue-75930-derive-cfg.rs:45:13: 45:16 (#0), + span: $DIR/issue-75930-derive-cfg.rs:75:13: 75:16 (#0), }, Ident { ident: "my_val", - span: $DIR/issue-75930-derive-cfg.rs:45:17: 45:23 (#0), + span: $DIR/issue-75930-derive-cfg.rs:75:17: 75:23 (#0), }, Punct { ch: '=', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:45:24: 45:25 (#0), + span: $DIR/issue-75930-derive-cfg.rs:75:24: 75:25 (#0), }, Ident { ident: "true", - span: $DIR/issue-75930-derive-cfg.rs:45:26: 45:30 (#0), + span: $DIR/issue-75930-derive-cfg.rs:75:26: 75:30 (#0), }, Punct { ch: ';', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:45:30: 45:31 (#0), + span: $DIR/issue-75930-derive-cfg.rs:75:30: 75:31 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:43:60: 46:10 (#0), + span: $DIR/issue-75930-derive-cfg.rs:73:60: 76:10 (#0), }, Ident { ident: "enum", - span: $DIR/issue-75930-derive-cfg.rs:48:9: 48:13 (#0), + span: $DIR/issue-75930-derive-cfg.rs:78:9: 78:13 (#0), }, Ident { ident: "TupleEnum", - span: $DIR/issue-75930-derive-cfg.rs:48:14: 48:23 (#0), + span: $DIR/issue-75930-derive-cfg.rs:78:14: 78:23 (#0), }, Group { delimiter: Brace, stream: TokenStream [ Ident { ident: "Foo", - span: $DIR/issue-75930-derive-cfg.rs:49:13: 49:16 (#0), + span: $DIR/issue-75930-derive-cfg.rs:79:13: 79:16 (#0), }, Group { delimiter: Parenthesis, @@ -1725,64 +1725,64 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [ Punct { ch: '#', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:52:17: 52:18 (#0), + span: $DIR/issue-75930-derive-cfg.rs:82:17: 82:18 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "cfg", - span: $DIR/issue-75930-derive-cfg.rs:52:19: 52:22 (#0), + span: $DIR/issue-75930-derive-cfg.rs:82:19: 82:22 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "not", - span: $DIR/issue-75930-derive-cfg.rs:52:23: 52:26 (#0), + span: $DIR/issue-75930-derive-cfg.rs:82:23: 82:26 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "FALSE", - span: $DIR/issue-75930-derive-cfg.rs:52:27: 52:32 (#0), + span: $DIR/issue-75930-derive-cfg.rs:82:27: 82:32 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:52:26: 52:33 (#0), + span: $DIR/issue-75930-derive-cfg.rs:82:26: 82:33 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:52:22: 52:34 (#0), + span: $DIR/issue-75930-derive-cfg.rs:82:22: 82:34 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:52:18: 52:35 (#0), + span: $DIR/issue-75930-derive-cfg.rs:82:18: 82:35 (#0), }, Ident { ident: "i32", - span: $DIR/issue-75930-derive-cfg.rs:52:36: 52:39 (#0), + span: $DIR/issue-75930-derive-cfg.rs:82:36: 82:39 (#0), }, Punct { ch: ',', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:52:39: 52:40 (#0), + span: $DIR/issue-75930-derive-cfg.rs:82:39: 82:40 (#0), }, Ident { ident: "u8", - span: $DIR/issue-75930-derive-cfg.rs:53:39: 53:41 (#0), + span: $DIR/issue-75930-derive-cfg.rs:83:39: 83:41 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:49:16: 54:14 (#0), + span: $DIR/issue-75930-derive-cfg.rs:79:16: 84:14 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:48:24: 55:10 (#0), + span: $DIR/issue-75930-derive-cfg.rs:78:24: 85:10 (#0), }, Ident { ident: "struct", - span: $DIR/issue-75930-derive-cfg.rs:57:9: 57:15 (#0), + span: $DIR/issue-75930-derive-cfg.rs:87:9: 87:15 (#0), }, Ident { ident: "TupleStruct", - span: $DIR/issue-75930-derive-cfg.rs:57:16: 57:27 (#0), + span: $DIR/issue-75930-derive-cfg.rs:87:16: 87:27 (#0), }, Group { delimiter: Parenthesis, @@ -1790,115 +1790,115 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [ Punct { ch: '#', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:59:13: 59:14 (#0), + span: $DIR/issue-75930-derive-cfg.rs:89:13: 89:14 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "cfg", - span: $DIR/issue-75930-derive-cfg.rs:59:15: 59:18 (#0), + span: $DIR/issue-75930-derive-cfg.rs:89:15: 89:18 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "not", - span: $DIR/issue-75930-derive-cfg.rs:59:19: 59:22 (#0), + span: $DIR/issue-75930-derive-cfg.rs:89:19: 89:22 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "FALSE", - span: $DIR/issue-75930-derive-cfg.rs:59:23: 59:28 (#0), + span: $DIR/issue-75930-derive-cfg.rs:89:23: 89:28 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:59:22: 59:29 (#0), + span: $DIR/issue-75930-derive-cfg.rs:89:22: 89:29 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:59:18: 59:30 (#0), + span: $DIR/issue-75930-derive-cfg.rs:89:18: 89:30 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:59:14: 59:31 (#0), + span: $DIR/issue-75930-derive-cfg.rs:89:14: 89:31 (#0), }, Ident { ident: "i32", - span: $DIR/issue-75930-derive-cfg.rs:59:32: 59:35 (#0), + span: $DIR/issue-75930-derive-cfg.rs:89:32: 89:35 (#0), }, Punct { ch: ',', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:59:35: 59:36 (#0), + span: $DIR/issue-75930-derive-cfg.rs:89:35: 89:36 (#0), }, Ident { ident: "u8", - span: $DIR/issue-75930-derive-cfg.rs:61:13: 61:15 (#0), + span: $DIR/issue-75930-derive-cfg.rs:91:13: 91:15 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:57:27: 62:10 (#0), + span: $DIR/issue-75930-derive-cfg.rs:87:27: 92:10 (#0), }, Punct { ch: ';', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:62:10: 62:11 (#0), + span: $DIR/issue-75930-derive-cfg.rs:92:10: 92:11 (#0), }, Literal { kind: Integer, symbol: "0", suffix: None, - span: $DIR/issue-75930-derive-cfg.rs:68:9: 68:10 (#0), + span: $DIR/issue-75930-derive-cfg.rs:98:9: 98:10 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:28:17: 69:6 (#0), + span: $DIR/issue-75930-derive-cfg.rs:58:17: 99:6 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:28:12: 69:7 (#0), + span: $DIR/issue-75930-derive-cfg.rs:58:12: 99:7 (#0), }, Punct { ch: ',', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:69:7: 69:8 (#0), + span: $DIR/issue-75930-derive-cfg.rs:99:7: 99:8 (#0), }, Punct { ch: '#', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:70:5: 70:6 (#0), + span: $DIR/issue-75930-derive-cfg.rs:100:5: 100:6 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "print_helper", - span: $DIR/issue-75930-derive-cfg.rs:70:7: 70:19 (#0), + span: $DIR/issue-75930-derive-cfg.rs:100:7: 100:19 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "d", - span: $DIR/issue-75930-derive-cfg.rs:70:20: 70:21 (#0), + span: $DIR/issue-75930-derive-cfg.rs:100:20: 100:21 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:70:19: 70:22 (#0), + span: $DIR/issue-75930-derive-cfg.rs:100:19: 100:22 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:70:6: 70:23 (#0), + span: $DIR/issue-75930-derive-cfg.rs:100:6: 100:23 (#0), }, Ident { ident: "fourth", - span: $DIR/issue-75930-derive-cfg.rs:71:5: 71:11 (#0), + span: $DIR/issue-75930-derive-cfg.rs:101:5: 101:11 (#0), }, Punct { ch: ':', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:71:11: 71:12 (#0), + span: $DIR/issue-75930-derive-cfg.rs:101:11: 101:12 (#0), }, Ident { ident: "B", - span: $DIR/issue-75930-derive-cfg.rs:71:13: 71:14 (#0), + span: $DIR/issue-75930-derive-cfg.rs:101:13: 101:14 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:25:32: 72:2 (#0), + span: $DIR/issue-75930-derive-cfg.rs:55:32: 102:2 (#0), }, ] From bb9c2f50c378d494e14f5d3062ed88ea90749637 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 8 Aug 2023 11:42:46 +1000 Subject: [PATCH 26/50] Reorder an expression to improve readability. --- compiler/rustc_parse/src/lexer/tokentrees.rs | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_parse/src/lexer/tokentrees.rs b/compiler/rustc_parse/src/lexer/tokentrees.rs index 7cdb19704709..1d9dbfe4b89d 100644 --- a/compiler/rustc_parse/src/lexer/tokentrees.rs +++ b/compiler/rustc_parse/src/lexer/tokentrees.rs @@ -55,19 +55,14 @@ impl<'a> TokenTreesReader<'a> { let (this_spacing, next_tok) = loop { let (next_tok, is_next_tok_preceded_by_whitespace) = self.string_reader.next_token(); - if !is_next_tok_preceded_by_whitespace { - if let Some(glued) = self.token.glue(&next_tok) { - self.token = glued; - } else { - let this_spacing = if next_tok.is_punct() { - Spacing::Joint - } else { - Spacing::Alone - }; - break (this_spacing, next_tok); - } - } else { + if is_next_tok_preceded_by_whitespace { break (Spacing::Alone, next_tok); + } else if let Some(glued) = self.token.glue(&next_tok) { + self.token = glued; + } else { + let this_spacing = + if next_tok.is_punct() { Spacing::Joint } else { Spacing::Alone }; + break (this_spacing, next_tok); } }; let this_tok = std::mem::replace(&mut self.token, next_tok); From 33aff5b1523b64052ae580f9bb6c7a7de94f16c5 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 11 Oct 2023 17:16:04 +1100 Subject: [PATCH 27/50] Use `TokenStream::token_alone` in one place. --- compiler/rustc_ast/src/attr/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index db008ea139d5..7b7078fabbb7 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -197,10 +197,10 @@ impl Attribute { .unwrap_or_else(|| panic!("attribute is missing tokens: {self:?}")) .to_attr_token_stream() .to_tokenstream(), - &AttrKind::DocComment(comment_kind, data) => TokenStream::new(vec![TokenTree::Token( - Token::new(token::DocComment(comment_kind, self.style, data), self.span), - Spacing::Alone, - )]), + &AttrKind::DocComment(comment_kind, data) => TokenStream::token_alone( + token::DocComment(comment_kind, self.style, data), + self.span, + ), } } } From 66c2b77a4a3d0b46c1abd2d90007b28e5de1b93d Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 12 Oct 2023 08:50:42 +1100 Subject: [PATCH 28/50] Rename `tt_prepend_space` as `space_between`. And reorder the arguments. I find it easier to think about this way. --- compiler/rustc_ast_pretty/src/pprust/state.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 8b7e91882fcc..e71f421659e2 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -148,7 +148,7 @@ pub fn print_crate<'a>( /// This makes printed token streams look slightly nicer, /// and also addresses some specific regressions described in #63896 and #73345. -fn tt_prepend_space(tt: &TokenTree, prev: &TokenTree) -> bool { +fn space_between(prev: &TokenTree, curr: &TokenTree) -> bool { if let TokenTree::Token(token, _) = prev { // No space after these tokens, e.g. `x.y`, `$e` // (The carets point to `prev`.) ^ ^ @@ -159,9 +159,9 @@ fn tt_prepend_space(tt: &TokenTree, prev: &TokenTree) -> bool { return comment_kind != CommentKind::Line; } } - match tt { + match curr { // No space before these tokens, e.g. `foo,`, `println!`, `x.y` - // (The carets point to `token`.) ^ ^ ^ + // (The carets point to `curr`.) ^ ^ ^ // // FIXME: having `Not` here works well for macro invocations like // `println!()`, but is bad when `!` means "logical not" or "the never @@ -575,7 +575,7 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere while let Some(tt) = iter.next() { self.print_tt(tt, convert_dollar_crate); if let Some(next) = iter.peek() { - if tt_prepend_space(next, tt) { + if space_between(tt, next) { self.space(); } } From 66e643d0f8a6406525ecbf61f8d99005208f97f4 Mon Sep 17 00:00:00 2001 From: Gurinder Singh Date: Thu, 12 Oct 2023 07:22:41 +0530 Subject: [PATCH 29/50] Fix duplicate note on internal feature gate The BuiltinInternalFeatures gate already has a struct level #[note] attribute. The additional note field in it caused a duplicate to be displayed when it was set to Some(...) which happened when the feature had an associated issue --- compiler/rustc_lint/src/builtin.rs | 12 ++++-------- compiler/rustc_lint/src/lints.rs | 2 -- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 536f78a73edb..be9465ba23d2 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -2258,23 +2258,19 @@ impl EarlyLintPass for IncompleteInternalFeatures { .chain(features.declared_lib_features.iter().map(|(name, span)| (name, span))) .filter(|(&name, _)| features.incomplete(name) || features.internal(name)) .for_each(|(&name, &span)| { - let note = rustc_feature::find_feature_issue(name, GateIssue::Language) - .map(|n| BuiltinFeatureIssueNote { n }); - if features.incomplete(name) { + let note = rustc_feature::find_feature_issue(name, GateIssue::Language) + .map(|n| BuiltinFeatureIssueNote { n }); let help = HAS_MIN_FEATURES.contains(&name).then_some(BuiltinIncompleteFeaturesHelp); + cx.emit_spanned_lint( INCOMPLETE_FEATURES, span, BuiltinIncompleteFeatures { name, note, help }, ); } else { - cx.emit_spanned_lint( - INTERNAL_FEATURES, - span, - BuiltinInternalFeatures { name, note }, - ); + cx.emit_spanned_lint(INTERNAL_FEATURES, span, BuiltinInternalFeatures { name }); } }); } diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index c776d3bb7fed..594ef97b3ffb 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -412,8 +412,6 @@ pub struct BuiltinIncompleteFeatures { #[note] pub struct BuiltinInternalFeatures { pub name: Symbol, - #[subdiagnostic] - pub note: Option, } #[derive(Subdiagnostic)] From a7ae2a6e6c68f0af5c3afcac015eea2bd18f6e27 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Thu, 12 Oct 2023 17:41:11 +1100 Subject: [PATCH 30/50] coverage: Simplify the detection of reloop edges to be given expressions --- .../src/coverage/counters.rs | 121 +++++++----------- .../rustc_mir_transform/src/coverage/graph.rs | 18 ++- 2 files changed, 57 insertions(+), 82 deletions(-) diff --git a/compiler/rustc_mir_transform/src/coverage/counters.rs b/compiler/rustc_mir_transform/src/coverage/counters.rs index 78845af01627..06770dafbaa0 100644 --- a/compiler/rustc_mir_transform/src/coverage/counters.rs +++ b/compiler/rustc_mir_transform/src/coverage/counters.rs @@ -510,18 +510,11 @@ impl<'a> MakeBcbCounters<'a> { traversal: &TraverseCoverageGraphWithLoops, branches: &[BcbBranch], ) -> BcbBranch { - let branch_needs_a_counter = |branch: &BcbBranch| self.branch_has_no_counter(branch); - - let some_reloop_branch = self.find_some_reloop_branch(traversal, &branches); - if let Some(reloop_branch_without_counter) = - some_reloop_branch.filter(branch_needs_a_counter) - { - debug!( - "Selecting reloop_branch={:?} that still needs a counter, to get the \ - `Expression`", - reloop_branch_without_counter - ); - reloop_branch_without_counter + let good_reloop_branch = self.find_good_reloop_branch(traversal, &branches); + if let Some(reloop_branch) = good_reloop_branch { + assert!(self.branch_has_no_counter(&reloop_branch)); + debug!("Selecting reloop branch {reloop_branch:?} to get an expression"); + reloop_branch } else { let &branch_without_counter = branches.iter().find(|&branch| self.branch_has_no_counter(branch)).expect( @@ -538,75 +531,52 @@ impl<'a> MakeBcbCounters<'a> { } } - /// At most, one of the branches (or its edge, from the branching_bcb, if the branch has - /// multiple incoming edges) can have a counter computed by expression. - /// - /// If at least one of the branches leads outside of a loop (`found_loop_exit` is - /// true), and at least one other branch does not exit the loop (the first of which - /// is captured in `some_reloop_branch`), it's likely any reloop branch will be - /// executed far more often than loop exit branch, making the reloop branch a better - /// candidate for an expression. - fn find_some_reloop_branch( + /// Tries to find a branch that leads back to the top of a loop, and that + /// doesn't already have a counter. Such branches are good candidates to + /// be given an expression (instead of a physical counter), because they + /// will tend to be executed more times than a loop-exit branch. + fn find_good_reloop_branch( &self, traversal: &TraverseCoverageGraphWithLoops, branches: &[BcbBranch], ) -> Option { - let branch_needs_a_counter = |branch: &BcbBranch| self.branch_has_no_counter(branch); - - let mut some_reloop_branch: Option = None; - for context in traversal.context_stack.iter().rev() { - if let Some((backedge_from_bcbs, _)) = &context.loop_backedges { - let mut found_loop_exit = false; - for &branch in branches.iter() { - if backedge_from_bcbs.iter().any(|&backedge_from_bcb| { - self.bcb_dominates(branch.target_bcb, backedge_from_bcb) - }) { - if let Some(reloop_branch) = some_reloop_branch { - if self.branch_has_no_counter(&reloop_branch) { - // we already found a candidate reloop_branch that still - // needs a counter - continue; - } - } - // The path from branch leads back to the top of the loop. Set this - // branch as the `reloop_branch`. If this branch already has a - // counter, and we find another reloop branch that doesn't have a - // counter yet, that branch will be selected as the `reloop_branch` - // instead. - some_reloop_branch = Some(branch); - } else { - // The path from branch leads outside this loop - found_loop_exit = true; - } - if found_loop_exit - && some_reloop_branch.filter(branch_needs_a_counter).is_some() - { - // Found both a branch that exits the loop and a branch that returns - // to the top of the loop (`reloop_branch`), and the `reloop_branch` - // doesn't already have a counter. - break; + // Consider each loop on the current traversal context stack, top-down. + for reloop_bcbs in traversal.reloop_bcbs_per_loop() { + let mut all_branches_exit_this_loop = true; + + // Try to find a branch that doesn't exit this loop and doesn't + // already have a counter. + for &branch in branches { + // A branch is a reloop branch if it dominates any BCB that has + // an edge back to the loop header. (Other branches are exits.) + let is_reloop_branch = reloop_bcbs.iter().any(|&reloop_bcb| { + self.basic_coverage_blocks.dominates(branch.target_bcb, reloop_bcb) + }); + + if is_reloop_branch { + all_branches_exit_this_loop = false; + if self.branch_has_no_counter(&branch) { + // We found a good branch to be given an expression. + return Some(branch); } + // Keep looking for another reloop branch without a counter. + } else { + // This branch exits the loop. } - if !found_loop_exit { - debug!( - "No branches exit the loop, so any branch without an existing \ - counter can have the `Expression`." - ); - break; - } - if some_reloop_branch.is_some() { - debug!( - "Found a branch that exits the loop and a branch the loops back to \ - the top of the loop (`reloop_branch`). The `reloop_branch` will \ - get the `Expression`, as long as it still needs a counter." - ); - break; - } - // else all branches exited this loop context, so run the same checks with - // the outer loop(s) } + + if !all_branches_exit_this_loop { + // We found one or more reloop branches, but all of them already + // have counters. Let the caller choose one of the exit branches. + debug!("All reloop branches had counters; skip checking the other loops"); + return None; + } + + // All of the branches exit this loop, so keep looking for a good + // reloop branch for one of the outer loops. } - some_reloop_branch + + None } #[inline] @@ -652,9 +622,4 @@ impl<'a> MakeBcbCounters<'a> { fn bcb_has_one_path_to_target(&self, bcb: BasicCoverageBlock) -> bool { self.bcb_predecessors(bcb).len() <= 1 } - - #[inline] - fn bcb_dominates(&self, dom: BasicCoverageBlock, node: BasicCoverageBlock) -> bool { - self.basic_coverage_blocks.dominates(dom, node) - } } diff --git a/compiler/rustc_mir_transform/src/coverage/graph.rs b/compiler/rustc_mir_transform/src/coverage/graph.rs index 39027d21f066..cf917ecee866 100644 --- a/compiler/rustc_mir_transform/src/coverage/graph.rs +++ b/compiler/rustc_mir_transform/src/coverage/graph.rs @@ -386,17 +386,17 @@ fn bcb_filtered_successors<'a, 'tcx>( #[derive(Debug)] pub(super) struct TraversalContext { /// From one or more backedges returning to a loop header. - pub loop_backedges: Option<(Vec, BasicCoverageBlock)>, + loop_backedges: Option<(Vec, BasicCoverageBlock)>, /// worklist, to be traversed, of CoverageGraph in the loop with the given loop /// backedges, such that the loop is the inner inner-most loop containing these /// CoverageGraph - pub worklist: Vec, + worklist: Vec, } pub(super) struct TraverseCoverageGraphWithLoops { - pub backedges: IndexVec>, - pub context_stack: Vec, + backedges: IndexVec>, + context_stack: Vec, visited: BitSet, } @@ -414,6 +414,16 @@ impl TraverseCoverageGraphWithLoops { Self { backedges, context_stack, visited } } + /// For each loop on the loop context stack (top-down), yields a list of BCBs + /// within that loop that have an outgoing edge back to the loop header. + pub(super) fn reloop_bcbs_per_loop(&self) -> impl Iterator { + self.context_stack + .iter() + .rev() + .filter_map(|context| context.loop_backedges.as_ref()) + .map(|(from_bcbs, _to_bcb)| from_bcbs.as_slice()) + } + pub fn next(&mut self, basic_coverage_blocks: &CoverageGraph) -> Option { debug!( "TraverseCoverageGraphWithLoops::next - context_stack: {:?}", From d1920c518151b29e3326cdacc757a219817f3c73 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Thu, 12 Oct 2023 12:59:11 +1100 Subject: [PATCH 31/50] coverage: Rename `next_bcb` to just `bcb` This is the only BCB that `TraverseCoverageGraphWithLoops::next` works with, so calling it `next_bcb` just makes the code less clear. --- .../rustc_mir_transform/src/coverage/graph.rs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_mir_transform/src/coverage/graph.rs b/compiler/rustc_mir_transform/src/coverage/graph.rs index cf917ecee866..12fb897bd79c 100644 --- a/compiler/rustc_mir_transform/src/coverage/graph.rs +++ b/compiler/rustc_mir_transform/src/coverage/graph.rs @@ -431,21 +431,22 @@ impl TraverseCoverageGraphWithLoops { ); while let Some(context) = self.context_stack.last_mut() { - if let Some(next_bcb) = context.worklist.pop() { - if !self.visited.insert(next_bcb) { - debug!("Already visited: {:?}", next_bcb); + if let Some(bcb) = context.worklist.pop() { + if !self.visited.insert(bcb) { + debug!("Already visited: {bcb:?}"); continue; } - debug!("Visiting {:?}", next_bcb); - if self.backedges[next_bcb].len() > 0 { - debug!("{:?} is a loop header! Start a new TraversalContext...", next_bcb); + debug!("Visiting {bcb:?}"); + + if self.backedges[bcb].len() > 0 { + debug!("{bcb:?} is a loop header! Start a new TraversalContext..."); self.context_stack.push(TraversalContext { - loop_backedges: Some((self.backedges[next_bcb].clone(), next_bcb)), + loop_backedges: Some((self.backedges[bcb].clone(), bcb)), worklist: Vec::new(), }); } - self.extend_worklist(basic_coverage_blocks, next_bcb); - return Some(next_bcb); + self.extend_worklist(basic_coverage_blocks, bcb); + return Some(bcb); } else { // Strip contexts with empty worklists from the top of the stack self.context_stack.pop(); From ea3fb7bc2cd64fc124209e6f4ffcda8d053fd7ae Mon Sep 17 00:00:00 2001 From: Zalathar Date: Thu, 12 Oct 2023 12:32:21 +1100 Subject: [PATCH 32/50] coverage: Use a `VecDeque` for loop traversal worklists The previous code was storing the worklist in a vector, and then selectively adding items to the start or end of the vector. That's a perfect use-case for a double-ended queue. This change also reveals that the existing code was a bit confused about which end of the worklist is the front or back. For now, items are always removed from the front of the queue (instead of the back), and code that adds items to the queue has been flipped, to preserve the existing behaviour. --- .../rustc_mir_transform/src/coverage/graph.rs | 49 +++++++------------ 1 file changed, 18 insertions(+), 31 deletions(-) diff --git a/compiler/rustc_mir_transform/src/coverage/graph.rs b/compiler/rustc_mir_transform/src/coverage/graph.rs index 12fb897bd79c..8dc13117b9f4 100644 --- a/compiler/rustc_mir_transform/src/coverage/graph.rs +++ b/compiler/rustc_mir_transform/src/coverage/graph.rs @@ -6,6 +6,7 @@ use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::mir::{self, BasicBlock, TerminatorKind}; use std::cmp::Ordering; +use std::collections::VecDeque; use std::ops::{Index, IndexMut}; /// A coverage-specific simplification of the MIR control flow graph (CFG). The `CoverageGraph`s @@ -388,10 +389,8 @@ pub(super) struct TraversalContext { /// From one or more backedges returning to a loop header. loop_backedges: Option<(Vec, BasicCoverageBlock)>, - /// worklist, to be traversed, of CoverageGraph in the loop with the given loop - /// backedges, such that the loop is the inner inner-most loop containing these - /// CoverageGraph - worklist: Vec, + /// Worklist of BCBs to be processed in this context. + worklist: VecDeque, } pub(super) struct TraverseCoverageGraphWithLoops { @@ -402,10 +401,11 @@ pub(super) struct TraverseCoverageGraphWithLoops { impl TraverseCoverageGraphWithLoops { pub fn new(basic_coverage_blocks: &CoverageGraph) -> Self { - let start_bcb = basic_coverage_blocks.start_node(); let backedges = find_loop_backedges(basic_coverage_blocks); - let context_stack = - vec![TraversalContext { loop_backedges: None, worklist: vec![start_bcb] }]; + + let worklist = VecDeque::from([basic_coverage_blocks.start_node()]); + let context_stack = vec![TraversalContext { loop_backedges: None, worklist }]; + // `context_stack` starts with a `TraversalContext` for the main function context (beginning // with the `start` BasicCoverageBlock of the function). New worklists are pushed to the top // of the stack as loops are entered, and popped off of the stack when a loop's worklist is @@ -431,7 +431,7 @@ impl TraverseCoverageGraphWithLoops { ); while let Some(context) = self.context_stack.last_mut() { - if let Some(bcb) = context.worklist.pop() { + if let Some(bcb) = context.worklist.pop_front() { if !self.visited.insert(bcb) { debug!("Already visited: {bcb:?}"); continue; @@ -442,7 +442,7 @@ impl TraverseCoverageGraphWithLoops { debug!("{bcb:?} is a loop header! Start a new TraversalContext..."); self.context_stack.push(TraversalContext { loop_backedges: Some((self.backedges[bcb].clone(), bcb)), - worklist: Vec::new(), + worklist: VecDeque::new(), }); } self.extend_worklist(basic_coverage_blocks, bcb); @@ -484,7 +484,7 @@ impl TraverseCoverageGraphWithLoops { // blocks with only one successor, to prevent unnecessarily complicating // `Expression`s by creating a Counter in a `BasicCoverageBlock` that the // branching block would have given an `Expression` (or vice versa). - let (some_successor_to_add, some_loop_header) = + let (some_successor_to_add, _) = if let Some((_, loop_header)) = context.loop_backedges { if basic_coverage_blocks.dominates(loop_header, successor) { (Some(successor), Some(loop_header)) @@ -494,30 +494,17 @@ impl TraverseCoverageGraphWithLoops { } else { (Some(successor), None) }; + + // FIXME: The code below had debug messages claiming to add items to a + // particular end of the worklist, but was confused about which end was + // which. The existing behaviour has been preserved for now, but it's + // unclear what the intended behaviour was. + if let Some(successor_to_add) = some_successor_to_add { if basic_coverage_blocks.successors[successor_to_add].len() > 1 { - debug!( - "{:?} successor is branching. Prioritize it at the beginning of \ - the {}", - successor_to_add, - if let Some(loop_header) = some_loop_header { - format!("worklist for the loop headed by {loop_header:?}") - } else { - String::from("non-loop worklist") - }, - ); - context.worklist.insert(0, successor_to_add); + context.worklist.push_back(successor_to_add); } else { - debug!( - "{:?} successor is non-branching. Defer it to the end of the {}", - successor_to_add, - if let Some(loop_header) = some_loop_header { - format!("worklist for the loop headed by {loop_header:?}") - } else { - String::from("non-loop worklist") - }, - ); - context.worklist.push(successor_to_add); + context.worklist.push_front(successor_to_add); } break; } From 15360b3bc8f75c33af8a41da5dc9a1cab19691ba Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 11 Oct 2023 17:40:37 +1100 Subject: [PATCH 33/50] coverage: Store a graph reference in the graph traversal struct Having to keep passing in a graph reference was a holdover from when the graph was partly mutated during traversal. As of #114354 that is no longer necessary, so we can simplify the traversal code by storing a graph reference as a field in `TraverseCoverageGraphWithLoops`. --- .../src/coverage/counters.rs | 10 ++++----- .../rustc_mir_transform/src/coverage/graph.rs | 21 +++++++++---------- .../rustc_mir_transform/src/coverage/tests.rs | 2 +- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_mir_transform/src/coverage/counters.rs b/compiler/rustc_mir_transform/src/coverage/counters.rs index 06770dafbaa0..77e3dee1fefa 100644 --- a/compiler/rustc_mir_transform/src/coverage/counters.rs +++ b/compiler/rustc_mir_transform/src/coverage/counters.rs @@ -245,13 +245,13 @@ impl<'a> MakeBcbCounters<'a> { // the loop. The `traversal` state includes a `context_stack`, providing a way to know if // the current BCB is in one or more nested loops or not. let mut traversal = TraverseCoverageGraphWithLoops::new(&self.basic_coverage_blocks); - while let Some(bcb) = traversal.next(self.basic_coverage_blocks) { + while let Some(bcb) = traversal.next() { if bcb_has_coverage_spans(bcb) { debug!("{:?} has at least one coverage span. Get or make its counter", bcb); let branching_counter_operand = self.get_or_make_counter_operand(bcb)?; if self.bcb_needs_branch_counters(bcb) { - self.make_branch_counters(&mut traversal, bcb, branching_counter_operand)?; + self.make_branch_counters(&traversal, bcb, branching_counter_operand)?; } } else { debug!( @@ -274,7 +274,7 @@ impl<'a> MakeBcbCounters<'a> { fn make_branch_counters( &mut self, - traversal: &mut TraverseCoverageGraphWithLoops, + traversal: &TraverseCoverageGraphWithLoops<'_>, branching_bcb: BasicCoverageBlock, branching_counter_operand: Operand, ) -> Result<(), Error> { @@ -507,7 +507,7 @@ impl<'a> MakeBcbCounters<'a> { /// found, select any branch. fn choose_preferred_expression_branch( &self, - traversal: &TraverseCoverageGraphWithLoops, + traversal: &TraverseCoverageGraphWithLoops<'_>, branches: &[BcbBranch], ) -> BcbBranch { let good_reloop_branch = self.find_good_reloop_branch(traversal, &branches); @@ -537,7 +537,7 @@ impl<'a> MakeBcbCounters<'a> { /// will tend to be executed more times than a loop-exit branch. fn find_good_reloop_branch( &self, - traversal: &TraverseCoverageGraphWithLoops, + traversal: &TraverseCoverageGraphWithLoops<'_>, branches: &[BcbBranch], ) -> Option { // Consider each loop on the current traversal context stack, top-down. diff --git a/compiler/rustc_mir_transform/src/coverage/graph.rs b/compiler/rustc_mir_transform/src/coverage/graph.rs index 8dc13117b9f4..02bc62a7d266 100644 --- a/compiler/rustc_mir_transform/src/coverage/graph.rs +++ b/compiler/rustc_mir_transform/src/coverage/graph.rs @@ -393,14 +393,16 @@ pub(super) struct TraversalContext { worklist: VecDeque, } -pub(super) struct TraverseCoverageGraphWithLoops { +pub(super) struct TraverseCoverageGraphWithLoops<'a> { + basic_coverage_blocks: &'a CoverageGraph, + backedges: IndexVec>, context_stack: Vec, visited: BitSet, } -impl TraverseCoverageGraphWithLoops { - pub fn new(basic_coverage_blocks: &CoverageGraph) -> Self { +impl<'a> TraverseCoverageGraphWithLoops<'a> { + pub(super) fn new(basic_coverage_blocks: &'a CoverageGraph) -> Self { let backedges = find_loop_backedges(basic_coverage_blocks); let worklist = VecDeque::from([basic_coverage_blocks.start_node()]); @@ -411,7 +413,7 @@ impl TraverseCoverageGraphWithLoops { // of the stack as loops are entered, and popped off of the stack when a loop's worklist is // exhausted. let visited = BitSet::new_empty(basic_coverage_blocks.num_nodes()); - Self { backedges, context_stack, visited } + Self { basic_coverage_blocks, backedges, context_stack, visited } } /// For each loop on the loop context stack (top-down), yields a list of BCBs @@ -424,7 +426,7 @@ impl TraverseCoverageGraphWithLoops { .map(|(from_bcbs, _to_bcb)| from_bcbs.as_slice()) } - pub fn next(&mut self, basic_coverage_blocks: &CoverageGraph) -> Option { + pub(super) fn next(&mut self) -> Option { debug!( "TraverseCoverageGraphWithLoops::next - context_stack: {:?}", self.context_stack.iter().rev().collect::>() @@ -445,7 +447,7 @@ impl TraverseCoverageGraphWithLoops { worklist: VecDeque::new(), }); } - self.extend_worklist(basic_coverage_blocks, bcb); + self.extend_worklist(bcb); return Some(bcb); } else { // Strip contexts with empty worklists from the top of the stack @@ -456,11 +458,8 @@ impl TraverseCoverageGraphWithLoops { None } - pub fn extend_worklist( - &mut self, - basic_coverage_blocks: &CoverageGraph, - bcb: BasicCoverageBlock, - ) { + pub fn extend_worklist(&mut self, bcb: BasicCoverageBlock) { + let Self { basic_coverage_blocks, .. } = *self; let successors = &basic_coverage_blocks.successors[bcb]; debug!("{:?} has {} successors:", bcb, successors.len()); for &successor in successors { diff --git a/compiler/rustc_mir_transform/src/coverage/tests.rs b/compiler/rustc_mir_transform/src/coverage/tests.rs index ee7cb791c818..487d22823644 100644 --- a/compiler/rustc_mir_transform/src/coverage/tests.rs +++ b/compiler/rustc_mir_transform/src/coverage/tests.rs @@ -628,7 +628,7 @@ fn test_traverse_coverage_with_loops() { let basic_coverage_blocks = graph::CoverageGraph::from_mir(&mir_body); let mut traversed_in_order = Vec::new(); let mut traversal = graph::TraverseCoverageGraphWithLoops::new(&basic_coverage_blocks); - while let Some(bcb) = traversal.next(&basic_coverage_blocks) { + while let Some(bcb) = traversal.next() { traversed_in_order.push(bcb); } From 59f4f1c89d035bffbb6455f1dc25a45f09c837a5 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 11 Oct 2023 20:33:26 +1100 Subject: [PATCH 34/50] coverage: Don't store loop backedges in the traversal context As long as we store the loop header BCB, we can look up its incoming loop backedges as needed. --- .../rustc_mir_transform/src/coverage/graph.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_mir_transform/src/coverage/graph.rs b/compiler/rustc_mir_transform/src/coverage/graph.rs index 02bc62a7d266..2a88a5f7f44e 100644 --- a/compiler/rustc_mir_transform/src/coverage/graph.rs +++ b/compiler/rustc_mir_transform/src/coverage/graph.rs @@ -386,8 +386,11 @@ fn bcb_filtered_successors<'a, 'tcx>( /// ensures a loop is completely traversed before processing Blocks after the end of the loop. #[derive(Debug)] pub(super) struct TraversalContext { - /// From one or more backedges returning to a loop header. - loop_backedges: Option<(Vec, BasicCoverageBlock)>, + /// BCB with one or more incoming loop backedges, indicating which loop + /// this context is for. + /// + /// If `None`, this is the non-loop context for the function as a whole. + loop_header: Option, /// Worklist of BCBs to be processed in this context. worklist: VecDeque, @@ -406,7 +409,7 @@ impl<'a> TraverseCoverageGraphWithLoops<'a> { let backedges = find_loop_backedges(basic_coverage_blocks); let worklist = VecDeque::from([basic_coverage_blocks.start_node()]); - let context_stack = vec![TraversalContext { loop_backedges: None, worklist }]; + let context_stack = vec![TraversalContext { loop_header: None, worklist }]; // `context_stack` starts with a `TraversalContext` for the main function context (beginning // with the `start` BasicCoverageBlock of the function). New worklists are pushed to the top @@ -422,8 +425,8 @@ impl<'a> TraverseCoverageGraphWithLoops<'a> { self.context_stack .iter() .rev() - .filter_map(|context| context.loop_backedges.as_ref()) - .map(|(from_bcbs, _to_bcb)| from_bcbs.as_slice()) + .filter_map(|context| context.loop_header) + .map(|header_bcb| self.backedges[header_bcb].as_slice()) } pub(super) fn next(&mut self) -> Option { @@ -443,7 +446,7 @@ impl<'a> TraverseCoverageGraphWithLoops<'a> { if self.backedges[bcb].len() > 0 { debug!("{bcb:?} is a loop header! Start a new TraversalContext..."); self.context_stack.push(TraversalContext { - loop_backedges: Some((self.backedges[bcb].clone(), bcb)), + loop_header: Some(bcb), worklist: VecDeque::new(), }); } @@ -484,7 +487,7 @@ impl<'a> TraverseCoverageGraphWithLoops<'a> { // `Expression`s by creating a Counter in a `BasicCoverageBlock` that the // branching block would have given an `Expression` (or vice versa). let (some_successor_to_add, _) = - if let Some((_, loop_header)) = context.loop_backedges { + if let Some(loop_header) = context.loop_header { if basic_coverage_blocks.dominates(loop_header, successor) { (Some(successor), Some(loop_header)) } else { From d99ab97b027917b434790b76492386310b47978d Mon Sep 17 00:00:00 2001 From: Zalathar Date: Thu, 12 Oct 2023 13:31:35 +1100 Subject: [PATCH 35/50] coverage: Simplify adding BCB successors to the traversal worklists --- .../rustc_mir_transform/src/coverage/graph.rs | 77 ++++++++++--------- 1 file changed, 39 insertions(+), 38 deletions(-) diff --git a/compiler/rustc_mir_transform/src/coverage/graph.rs b/compiler/rustc_mir_transform/src/coverage/graph.rs index 2a88a5f7f44e..9a7adaada09f 100644 --- a/compiler/rustc_mir_transform/src/coverage/graph.rs +++ b/compiler/rustc_mir_transform/src/coverage/graph.rs @@ -450,7 +450,7 @@ impl<'a> TraverseCoverageGraphWithLoops<'a> { worklist: VecDeque::new(), }); } - self.extend_worklist(bcb); + self.add_successors_to_worklists(bcb); return Some(bcb); } else { // Strip contexts with empty worklists from the top of the stack @@ -461,10 +461,10 @@ impl<'a> TraverseCoverageGraphWithLoops<'a> { None } - pub fn extend_worklist(&mut self, bcb: BasicCoverageBlock) { - let Self { basic_coverage_blocks, .. } = *self; - let successors = &basic_coverage_blocks.successors[bcb]; + pub fn add_successors_to_worklists(&mut self, bcb: BasicCoverageBlock) { + let successors = &self.basic_coverage_blocks.successors[bcb]; debug!("{:?} has {} successors:", bcb, successors.len()); + for &successor in successors { if successor == bcb { debug!( @@ -473,43 +473,44 @@ impl<'a> TraverseCoverageGraphWithLoops<'a> { bcb ); // Don't re-add this successor to the worklist. We are already processing it. + // FIXME: This claims to skip just the self-successor, but it actually skips + // all other successors as well. Does that matter? break; } - for context in self.context_stack.iter_mut().rev() { - // Add successors of the current BCB to the appropriate context. Successors that - // stay within a loop are added to the BCBs context worklist. Successors that - // exit the loop (they are not dominated by the loop header) must be reachable - // from other BCBs outside the loop, and they will be added to a different - // worklist. - // - // Branching blocks (with more than one successor) must be processed before - // blocks with only one successor, to prevent unnecessarily complicating - // `Expression`s by creating a Counter in a `BasicCoverageBlock` that the - // branching block would have given an `Expression` (or vice versa). - let (some_successor_to_add, _) = - if let Some(loop_header) = context.loop_header { - if basic_coverage_blocks.dominates(loop_header, successor) { - (Some(successor), Some(loop_header)) - } else { - (None, None) - } - } else { - (Some(successor), None) - }; - - // FIXME: The code below had debug messages claiming to add items to a - // particular end of the worklist, but was confused about which end was - // which. The existing behaviour has been preserved for now, but it's - // unclear what the intended behaviour was. - - if let Some(successor_to_add) = some_successor_to_add { - if basic_coverage_blocks.successors[successor_to_add].len() > 1 { - context.worklist.push_back(successor_to_add); - } else { - context.worklist.push_front(successor_to_add); + + // Add successors of the current BCB to the appropriate context. Successors that + // stay within a loop are added to the BCBs context worklist. Successors that + // exit the loop (they are not dominated by the loop header) must be reachable + // from other BCBs outside the loop, and they will be added to a different + // worklist. + // + // Branching blocks (with more than one successor) must be processed before + // blocks with only one successor, to prevent unnecessarily complicating + // `Expression`s by creating a Counter in a `BasicCoverageBlock` that the + // branching block would have given an `Expression` (or vice versa). + + let context = self + .context_stack + .iter_mut() + .rev() + .find(|context| match context.loop_header { + Some(loop_header) => { + self.basic_coverage_blocks.dominates(loop_header, successor) } - break; - } + None => true, + }) + .unwrap_or_else(|| bug!("should always fall back to the root non-loop context")); + debug!("adding to worklist for {:?}", context.loop_header); + + // FIXME: The code below had debug messages claiming to add items to a + // particular end of the worklist, but was confused about which end was + // which. The existing behaviour has been preserved for now, but it's + // unclear what the intended behaviour was. + + if self.basic_coverage_blocks.successors[successor].len() > 1 { + context.worklist.push_back(successor); + } else { + context.worklist.push_front(successor); } } } From 8309097163103910a08c0ed79def88ae178699ac Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Thu, 12 Oct 2023 08:45:02 -0700 Subject: [PATCH 36/50] Fix mips platform support entries. --- src/doc/rustc/src/platform-support.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index d25fa661c3f3..1fb5e56db5d7 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -286,10 +286,6 @@ target | std | host | notes `mipsel-unknown-linux-musl` | ✓ | | MIPS (little endian) Linux with musl libc `mipsel-sony-psp` | * | | MIPS (LE) Sony PlayStation Portable (PSP) [`mipsel-sony-psx`](platform-support/mipsel-sony-psx.md) | * | | MIPS (LE) Sony PlayStation 1 (PSX) -`mips-unknown-linux-gnu` | MIPS Linux (kernel 4.4, glibc 2.23) -`mips64-unknown-linux-gnuabi64` | MIPS64 Linux, n64 ABI (kernel 4.4, glibc 2.23) -`mips64el-unknown-linux-gnuabi64` | MIPS64 (LE) Linux, n64 ABI (kernel 4.4, glibc 2.23) -`mipsel-unknown-linux-gnu` | MIPS (LE) Linux (kernel 4.4, glibc 2.23) `mipsel-unknown-linux-uclibc` | ✓ | | MIPS (LE) Linux with uClibc `mipsel-unknown-none` | * | | Bare MIPS (LE) softfloat [`mipsisa32r6-unknown-linux-gnu`](platform-support/mips-release-6.md) | ? | | 32-bit MIPS Release 6 Big Endian From f5cdd3e130dce081a72735eeeb0eca283912f48b Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Thu, 12 Oct 2023 11:03:02 -0700 Subject: [PATCH 37/50] Exclude apple from assembly test --- tests/assembly/x86_64-array-pair-load-store-merge.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/assembly/x86_64-array-pair-load-store-merge.rs b/tests/assembly/x86_64-array-pair-load-store-merge.rs index 4a8e40f85300..55e317e91bf0 100644 --- a/tests/assembly/x86_64-array-pair-load-store-merge.rs +++ b/tests/assembly/x86_64-array-pair-load-store-merge.rs @@ -2,6 +2,7 @@ // compile-flags: --crate-type=lib -O -C llvm-args=-x86-asm-syntax=intel // only-x86_64 // ignore-sgx +// ignore-macos (manipulates rsp too) // Depending on various codegen choices, this might end up copying // a `<2 x i8>`, an `i16`, or two `i8`s. From ef8701a4a02e21230401ace80a19169f9f9a6ff8 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 10 Oct 2023 10:01:52 +1100 Subject: [PATCH 38/50] Rename some things. - Rename `pprust` as `pprust_ast`, to align with `pprust_hir`. - Rename `PrinterSupport` as `AstPrinterSupport`, to align with `HirPrinterSupport`. --- compiler/rustc_driver_impl/src/pretty.rs | 70 ++++++++++++------------ 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs index 222c7b5d6a72..5d49c78dea46 100644 --- a/compiler/rustc_driver_impl/src/pretty.rs +++ b/compiler/rustc_driver_impl/src/pretty.rs @@ -1,7 +1,7 @@ //! The various pretty-printing routines. use rustc_ast as ast; -use rustc_ast_pretty::pprust; +use rustc_ast_pretty::pprust as pprust_ast; use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; use rustc_hir_pretty as pprust_hir; @@ -26,26 +26,25 @@ use crate::abort_on_err; // analysis results) on to the chosen pretty-printer, along with the // `&PpAnn` object. // -// Note that since the `&PrinterSupport` is freshly constructed on each +// Note that since the `&AstPrinterSupport` is freshly constructed on each // call, it would not make sense to try to attach the lifetime of `self` // to the lifetime of the `&PrinterObject`. -/// Constructs a `PrinterSupport` object and passes it to `f`. -fn call_with_pp_support<'tcx, A, F>( +/// Constructs an `AstPrinterSupport` object and passes it to `f`. +fn call_with_pp_support_ast<'tcx, A, F>( ppmode: &PpSourceMode, sess: &'tcx Session, tcx: Option>, f: F, ) -> A where - F: FnOnce(&dyn PrinterSupport) -> A, + F: FnOnce(&dyn AstPrinterSupport) -> A, { match *ppmode { Normal | Expanded => { let annotation = NoAnn { sess, tcx }; f(&annotation) } - Identified | ExpandedIdentified => { let annotation = IdentifiedAnnotation { sess, tcx }; f(&annotation) @@ -65,7 +64,6 @@ where let annotation = NoAnn { sess: tcx.sess, tcx: Some(tcx) }; f(&annotation, tcx.hir()) } - PpHirMode::Identified => { let annotation = IdentifiedAnnotation { sess: tcx.sess, tcx: Some(tcx) }; f(&annotation, tcx.hir()) @@ -79,7 +77,7 @@ where } } -trait PrinterSupport: pprust::PpAnn { +trait AstPrinterSupport: pprust_ast::PpAnn { /// Provides a uniform interface for re-extracting a reference to a /// `Session` from a value that now owns it. fn sess(&self) -> &Session; @@ -88,7 +86,7 @@ trait PrinterSupport: pprust::PpAnn { /// /// (Rust does not yet support upcasting from a trait object to /// an object for one of its supertraits.) - fn pp_ann(&self) -> &dyn pprust::PpAnn; + fn pp_ann(&self) -> &dyn pprust_ast::PpAnn; } trait HirPrinterSupport<'hir>: pprust_hir::PpAnn { @@ -112,12 +110,12 @@ struct NoAnn<'hir> { tcx: Option>, } -impl<'hir> PrinterSupport for NoAnn<'hir> { +impl<'hir> AstPrinterSupport for NoAnn<'hir> { fn sess(&self) -> &Session { self.sess } - fn pp_ann(&self) -> &dyn pprust::PpAnn { + fn pp_ann(&self) -> &dyn pprust_ast::PpAnn { self } } @@ -136,7 +134,7 @@ impl<'hir> HirPrinterSupport<'hir> for NoAnn<'hir> { } } -impl<'hir> pprust::PpAnn for NoAnn<'hir> {} +impl<'hir> pprust_ast::PpAnn for NoAnn<'hir> {} impl<'hir> pprust_hir::PpAnn for NoAnn<'hir> { fn nested(&self, state: &mut pprust_hir::State<'_>, nested: pprust_hir::Nested) { if let Some(tcx) = self.tcx { @@ -150,44 +148,46 @@ struct IdentifiedAnnotation<'hir> { tcx: Option>, } -impl<'hir> PrinterSupport for IdentifiedAnnotation<'hir> { +impl<'hir> AstPrinterSupport for IdentifiedAnnotation<'hir> { fn sess(&self) -> &Session { self.sess } - fn pp_ann(&self) -> &dyn pprust::PpAnn { + fn pp_ann(&self) -> &dyn pprust_ast::PpAnn { self } } -impl<'hir> pprust::PpAnn for IdentifiedAnnotation<'hir> { - fn pre(&self, s: &mut pprust::State<'_>, node: pprust::AnnNode<'_>) { - if let pprust::AnnNode::Expr(_) = node { +impl<'hir> pprust_ast::PpAnn for IdentifiedAnnotation<'hir> { + fn pre(&self, s: &mut pprust_ast::State<'_>, node: pprust_ast::AnnNode<'_>) { + if let pprust_ast::AnnNode::Expr(_) = node { s.popen(); } } - fn post(&self, s: &mut pprust::State<'_>, node: pprust::AnnNode<'_>) { + fn post(&self, s: &mut pprust_ast::State<'_>, node: pprust_ast::AnnNode<'_>) { match node { - pprust::AnnNode::Crate(_) | pprust::AnnNode::Ident(_) | pprust::AnnNode::Name(_) => {} + pprust_ast::AnnNode::Crate(_) + | pprust_ast::AnnNode::Ident(_) + | pprust_ast::AnnNode::Name(_) => {} - pprust::AnnNode::Item(item) => { + pprust_ast::AnnNode::Item(item) => { s.s.space(); s.synth_comment(item.id.to_string()) } - pprust::AnnNode::SubItem(id) => { + pprust_ast::AnnNode::SubItem(id) => { s.s.space(); s.synth_comment(id.to_string()) } - pprust::AnnNode::Block(blk) => { + pprust_ast::AnnNode::Block(blk) => { s.s.space(); s.synth_comment(format!("block {}", blk.id)) } - pprust::AnnNode::Expr(expr) => { + pprust_ast::AnnNode::Expr(expr) => { s.s.space(); s.synth_comment(expr.id.to_string()); s.pclose() } - pprust::AnnNode::Pat(pat) => { + pprust_ast::AnnNode::Pat(pat) => { s.s.space(); s.synth_comment(format!("pat {}", pat.id)); } @@ -256,28 +256,28 @@ struct HygieneAnnotation<'a> { sess: &'a Session, } -impl<'a> PrinterSupport for HygieneAnnotation<'a> { +impl<'a> AstPrinterSupport for HygieneAnnotation<'a> { fn sess(&self) -> &Session { self.sess } - fn pp_ann(&self) -> &dyn pprust::PpAnn { + fn pp_ann(&self) -> &dyn pprust_ast::PpAnn { self } } -impl<'a> pprust::PpAnn for HygieneAnnotation<'a> { - fn post(&self, s: &mut pprust::State<'_>, node: pprust::AnnNode<'_>) { +impl<'a> pprust_ast::PpAnn for HygieneAnnotation<'a> { + fn post(&self, s: &mut pprust_ast::State<'_>, node: pprust_ast::AnnNode<'_>) { match node { - pprust::AnnNode::Ident(&Ident { name, span }) => { + pprust_ast::AnnNode::Ident(&Ident { name, span }) => { s.s.space(); s.synth_comment(format!("{}{:?}", name.as_u32(), span.ctxt())) } - pprust::AnnNode::Name(&name) => { + pprust_ast::AnnNode::Name(&name) => { s.s.space(); s.synth_comment(name.as_u32().to_string()) } - pprust::AnnNode::Crate(_) => { + pprust_ast::AnnNode::Crate(_) => { s.s.hardbreak(); let verbose = self.sess.verbose(); s.synth_comment(rustc_span::hygiene::debug_hygiene_data(verbose)); @@ -366,11 +366,11 @@ pub fn print_after_parsing(sess: &Session, krate: &ast::Crate, ppm: PpMode) { let out = match ppm { Source(s) => { // Silently ignores an identified node. - call_with_pp_support(&s, sess, None, move |annotation| { + call_with_pp_support_ast(&s, sess, None, move |annotation| { debug!("pretty printing source code {:?}", s); let sess = annotation.sess(); let parse = &sess.parse_sess; - pprust::print_crate( + pprust_ast::print_crate( sess.source_map(), krate, src_name, @@ -403,11 +403,11 @@ pub fn print_after_hir_lowering<'tcx>(tcx: TyCtxt<'tcx>, ppm: PpMode) { let out = match ppm { Source(s) => { // Silently ignores an identified node. - call_with_pp_support(&s, tcx.sess, Some(tcx), move |annotation| { + call_with_pp_support_ast(&s, tcx.sess, Some(tcx), move |annotation| { debug!("pretty printing source code {:?}", s); let sess = annotation.sess(); let parse = &sess.parse_sess; - pprust::print_crate( + pprust_ast::print_crate( sess.source_map(), &tcx.resolver_for_lowering(()).borrow().1, src_name, From c5cfcdc4ac0880b171dc0004c660e3a6fd315ee0 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 10 Oct 2023 10:53:12 +1100 Subject: [PATCH 39/50] Remove unnecessary call to `call_with_pp_support_hir`. The callback is trivial and no pp support is actually needed. This makes the `HirTree` case more like the `AstTree` case above. --- compiler/rustc_driver_impl/src/pretty.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs index 5d49c78dea46..bae0d3dd6a61 100644 --- a/compiler/rustc_driver_impl/src/pretty.rs +++ b/compiler/rustc_driver_impl/src/pretty.rs @@ -441,10 +441,8 @@ pub fn print_after_hir_lowering<'tcx>(tcx: TyCtxt<'tcx>, ppm: PpMode) { }), HirTree => { - call_with_pp_support_hir(&PpHirMode::Normal, tcx, move |_annotation, hir_map| { - debug!("pretty printing HIR tree"); - format!("{:#?}", hir_map.krate()) - }) + debug!("pretty printing HIR tree"); + format!("{:#?}", tcx.hir().krate()) } _ => unreachable!(), From 87090a97e3de431bf15832d9389bf07a969e2791 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 10 Oct 2023 10:54:36 +1100 Subject: [PATCH 40/50] Remove an outdated comment. `phase_3_run_analysis_passes` no longer exists, and AFAICT this code has been refactored so much since this comment was written that it no longer has any useful meaning. --- compiler/rustc_driver_impl/src/pretty.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs index bae0d3dd6a61..4a5198080a20 100644 --- a/compiler/rustc_driver_impl/src/pretty.rs +++ b/compiler/rustc_driver_impl/src/pretty.rs @@ -451,10 +451,6 @@ pub fn print_after_hir_lowering<'tcx>(tcx: TyCtxt<'tcx>, ppm: PpMode) { write_or_print(&out, tcx.sess); } -// In an ideal world, this would be a public function called by the driver after -// analysis is performed. However, we want to call `phase_3_run_analysis_passes` -// with a different callback than the standard driver, so that isn't easy. -// Instead, we call that function ourselves. fn print_with_analysis(tcx: TyCtxt<'_>, ppm: PpMode) -> Result<(), ErrorGuaranteed> { tcx.analysis(())?; let out = match ppm { From 1467ba06b6b50633541dca9ddebcdacd16a499b1 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 10 Oct 2023 12:17:06 +1100 Subject: [PATCH 41/50] Remove PpAstTreeMode. It's simpler to distinguish the two AST modes directly in `PpMode`. --- compiler/rustc_driver_impl/src/pretty.rs | 6 +++--- compiler/rustc_session/src/config.rs | 23 +++++++++-------------- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs index 4a5198080a20..b258643e97c1 100644 --- a/compiler/rustc_driver_impl/src/pretty.rs +++ b/compiler/rustc_driver_impl/src/pretty.rs @@ -8,7 +8,7 @@ use rustc_hir_pretty as pprust_hir; use rustc_middle::hir::map as hir_map; use rustc_middle::mir::{write_mir_graphviz, write_mir_pretty}; use rustc_middle::ty::{self, TyCtxt}; -use rustc_session::config::{OutFileName, PpAstTreeMode, PpHirMode, PpMode, PpSourceMode}; +use rustc_session::config::{OutFileName, PpHirMode, PpMode, PpSourceMode}; use rustc_session::Session; use rustc_span::symbol::Ident; use rustc_span::FileName; @@ -382,7 +382,7 @@ pub fn print_after_parsing(sess: &Session, krate: &ast::Crate, ppm: PpMode) { ) }) } - AstTree(PpAstTreeMode::Normal) => { + AstTree => { debug!("pretty printing AST tree"); format!("{krate:#?}") } @@ -420,7 +420,7 @@ pub fn print_after_hir_lowering<'tcx>(tcx: TyCtxt<'tcx>, ppm: PpMode) { }) } - AstTree(PpAstTreeMode::Expanded) => { + AstTreeExpanded => { debug!("pretty-printing expanded AST"); format!("{:#?}", tcx.resolver_for_lowering(()).borrow().1) } diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 58461856eb1e..056986a81441 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -2925,8 +2925,8 @@ fn parse_pretty(handler: &EarlyErrorHandler, unstable_opts: &UnstableOptions) -> "expanded" => Source(PpSourceMode::Expanded), "expanded,identified" => Source(PpSourceMode::ExpandedIdentified), "expanded,hygiene" => Source(PpSourceMode::ExpandedHygiene), - "ast-tree" => AstTree(PpAstTreeMode::Normal), - "ast-tree,expanded" => AstTree(PpAstTreeMode::Expanded), + "ast-tree" => AstTree, + "ast-tree,expanded" => AstTreeExpanded, "hir" => Hir(PpHirMode::Normal), "hir,identified" => Hir(PpHirMode::Identified), "hir,typed" => Hir(PpHirMode::Typed), @@ -3083,14 +3083,6 @@ pub enum PpSourceMode { ExpandedHygiene, } -#[derive(Copy, Clone, PartialEq, Debug)] -pub enum PpAstTreeMode { - /// `-Zunpretty=ast` - Normal, - /// `-Zunpretty=ast,expanded` - Expanded, -} - #[derive(Copy, Clone, PartialEq, Debug)] pub enum PpHirMode { /// `-Zunpretty=hir` @@ -3106,7 +3098,10 @@ pub enum PpMode { /// Options that print the source code, i.e. /// `-Zunpretty=normal` and `-Zunpretty=expanded` Source(PpSourceMode), - AstTree(PpAstTreeMode), + /// `-Zunpretty=ast-tree` + AstTree, + /// `-Zunpretty=ast-tree,expanded` + AstTreeExpanded, /// Options that print the HIR, i.e. `-Zunpretty=hir` Hir(PpHirMode), /// `-Zunpretty=hir-tree` @@ -3126,10 +3121,10 @@ impl PpMode { use PpMode::*; use PpSourceMode::*; match *self { - Source(Normal | Identified) | AstTree(PpAstTreeMode::Normal) => false, + Source(Normal | Identified) | AstTree => false, Source(Expanded | ExpandedIdentified | ExpandedHygiene) - | AstTree(PpAstTreeMode::Expanded) + | AstTreeExpanded | Hir(_) | HirTree | ThirTree @@ -3141,7 +3136,7 @@ impl PpMode { pub fn needs_hir(&self) -> bool { use PpMode::*; match *self { - Source(_) | AstTree(_) => false, + Source(_) | AstTree | AstTreeExpanded => false, Hir(_) | HirTree | ThirTree | ThirFlat | Mir | MirCFG => true, } From d5e7c5f3cc9919bf1ad0b61568d74c65639d4e4e Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 10 Oct 2023 12:22:22 +1100 Subject: [PATCH 42/50] Remove unused `PrinterSupport::hir_map` method. --- compiler/rustc_driver_impl/src/pretty.rs | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs index b258643e97c1..b647bf1c3139 100644 --- a/compiler/rustc_driver_impl/src/pretty.rs +++ b/compiler/rustc_driver_impl/src/pretty.rs @@ -94,10 +94,6 @@ trait HirPrinterSupport<'hir>: pprust_hir::PpAnn { /// `Session` from a value that now owns it. fn sess(&self) -> &Session; - /// Provides a uniform interface for re-extracting a reference to an - /// `hir_map::Map` from a value that now owns it. - fn hir_map(&self) -> Option>; - /// Produces the pretty-print annotation object. /// /// (Rust does not yet support upcasting from a trait object to @@ -125,10 +121,6 @@ impl<'hir> HirPrinterSupport<'hir> for NoAnn<'hir> { self.sess } - fn hir_map(&self) -> Option> { - self.tcx.map(|tcx| tcx.hir()) - } - fn pp_ann(&self) -> &dyn pprust_hir::PpAnn { self } @@ -200,10 +192,6 @@ impl<'hir> HirPrinterSupport<'hir> for IdentifiedAnnotation<'hir> { self.sess } - fn hir_map(&self) -> Option> { - self.tcx.map(|tcx| tcx.hir()) - } - fn pp_ann(&self) -> &dyn pprust_hir::PpAnn { self } @@ -298,10 +286,6 @@ impl<'tcx> HirPrinterSupport<'tcx> for TypedAnnotation<'tcx> { self.tcx.sess } - fn hir_map(&self) -> Option> { - Some(self.tcx.hir()) - } - fn pp_ann(&self) -> &dyn pprust_hir::PpAnn { self } From e3d8bbbfe29ab73afe1d258d6f69c2d6840a30ff Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 10 Oct 2023 12:58:12 +1100 Subject: [PATCH 43/50] Simplify support traits. First, both `AstPrinterSupport` and `HirPrinterSupport` have a `sess` method. This commit introduces a `Sess` trait and makes the support traits be subtraits of `Sess`, to avoid some duplication. Second, both support traits have a `pp_ann` method that isn't needed if we enable `trait_upcasting`. This commit removes those methods. (Both of these traits will be removed in a subsequent commit, as will the `trait_upcasting` use.) --- compiler/rustc_driver_impl/src/lib.rs | 5 +- compiler/rustc_driver_impl/src/pretty.rs | 95 +++++++----------------- 2 files changed, 30 insertions(+), 70 deletions(-) diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 17556c45296e..bbecf1a1093f 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -8,10 +8,11 @@ #![cfg_attr(not(bootstrap), doc(rust_logo))] #![cfg_attr(not(bootstrap), feature(rustdoc_internals))] #![cfg_attr(not(bootstrap), allow(internal_features))] -#![feature(lazy_cell)] #![feature(decl_macro)] -#![feature(panic_update_hook)] +#![feature(lazy_cell)] #![feature(let_chains)] +#![feature(panic_update_hook)] +#![feature(trait_upcasting)] #![recursion_limit = "256"] #![allow(rustc::potential_query_instability)] #![deny(rustc::untranslatable_diagnostic)] diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs index b647bf1c3139..ec118bd33eb9 100644 --- a/compiler/rustc_driver_impl/src/pretty.rs +++ b/compiler/rustc_driver_impl/src/pretty.rs @@ -55,9 +55,10 @@ where } } } + fn call_with_pp_support_hir(ppmode: &PpHirMode, tcx: TyCtxt<'_>, f: F) -> A where - F: FnOnce(&dyn HirPrinterSupport<'_>, hir_map::Map<'_>) -> A, + F: FnOnce(&dyn HirPrinterSupport, hir_map::Map<'_>) -> A, { match *ppmode { PpHirMode::Normal => { @@ -77,54 +78,28 @@ where } } -trait AstPrinterSupport: pprust_ast::PpAnn { +trait Sess { /// Provides a uniform interface for re-extracting a reference to a - /// `Session` from a value that now owns it. + /// `Session`. fn sess(&self) -> &Session; - - /// Produces the pretty-print annotation object. - /// - /// (Rust does not yet support upcasting from a trait object to - /// an object for one of its supertraits.) - fn pp_ann(&self) -> &dyn pprust_ast::PpAnn; } -trait HirPrinterSupport<'hir>: pprust_hir::PpAnn { - /// Provides a uniform interface for re-extracting a reference to a - /// `Session` from a value that now owns it. - fn sess(&self) -> &Session; - - /// Produces the pretty-print annotation object. - /// - /// (Rust does not yet support upcasting from a trait object to - /// an object for one of its supertraits.) - fn pp_ann(&self) -> &dyn pprust_hir::PpAnn; -} +trait AstPrinterSupport: pprust_ast::PpAnn + Sess {} +trait HirPrinterSupport: pprust_hir::PpAnn + Sess {} struct NoAnn<'hir> { sess: &'hir Session, tcx: Option>, } -impl<'hir> AstPrinterSupport for NoAnn<'hir> { +impl<'hir> Sess for NoAnn<'hir> { fn sess(&self) -> &Session { self.sess } - - fn pp_ann(&self) -> &dyn pprust_ast::PpAnn { - self - } } -impl<'hir> HirPrinterSupport<'hir> for NoAnn<'hir> { - fn sess(&self) -> &Session { - self.sess - } - - fn pp_ann(&self) -> &dyn pprust_hir::PpAnn { - self - } -} +impl<'tcx> AstPrinterSupport for NoAnn<'tcx> {} +impl<'hir> HirPrinterSupport for NoAnn<'hir> {} impl<'hir> pprust_ast::PpAnn for NoAnn<'hir> {} impl<'hir> pprust_hir::PpAnn for NoAnn<'hir> { @@ -140,22 +115,21 @@ struct IdentifiedAnnotation<'hir> { tcx: Option>, } -impl<'hir> AstPrinterSupport for IdentifiedAnnotation<'hir> { +impl<'hir> Sess for IdentifiedAnnotation<'hir> { fn sess(&self) -> &Session { self.sess } - - fn pp_ann(&self) -> &dyn pprust_ast::PpAnn { - self - } } +impl<'hir> AstPrinterSupport for IdentifiedAnnotation<'hir> {} + impl<'hir> pprust_ast::PpAnn for IdentifiedAnnotation<'hir> { fn pre(&self, s: &mut pprust_ast::State<'_>, node: pprust_ast::AnnNode<'_>) { if let pprust_ast::AnnNode::Expr(_) = node { s.popen(); } } + fn post(&self, s: &mut pprust_ast::State<'_>, node: pprust_ast::AnnNode<'_>) { match node { pprust_ast::AnnNode::Crate(_) @@ -187,15 +161,7 @@ impl<'hir> pprust_ast::PpAnn for IdentifiedAnnotation<'hir> { } } -impl<'hir> HirPrinterSupport<'hir> for IdentifiedAnnotation<'hir> { - fn sess(&self) -> &Session { - self.sess - } - - fn pp_ann(&self) -> &dyn pprust_hir::PpAnn { - self - } -} +impl<'hir> HirPrinterSupport for IdentifiedAnnotation<'hir> {} impl<'hir> pprust_hir::PpAnn for IdentifiedAnnotation<'hir> { fn nested(&self, state: &mut pprust_hir::State<'_>, nested: pprust_hir::Nested) { @@ -203,11 +169,13 @@ impl<'hir> pprust_hir::PpAnn for IdentifiedAnnotation<'hir> { pprust_hir::PpAnn::nested(&(&tcx.hir() as &dyn hir::intravisit::Map<'_>), state, nested) } } + fn pre(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) { if let pprust_hir::AnnNode::Expr(_) = node { s.popen(); } } + fn post(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) { match node { pprust_hir::AnnNode::Name(_) => {} @@ -244,16 +212,14 @@ struct HygieneAnnotation<'a> { sess: &'a Session, } -impl<'a> AstPrinterSupport for HygieneAnnotation<'a> { +impl<'a> Sess for HygieneAnnotation<'a> { fn sess(&self) -> &Session { self.sess } - - fn pp_ann(&self) -> &dyn pprust_ast::PpAnn { - self - } } +impl<'a> AstPrinterSupport for HygieneAnnotation<'a> {} + impl<'a> pprust_ast::PpAnn for HygieneAnnotation<'a> { fn post(&self, s: &mut pprust_ast::State<'_>, node: pprust_ast::AnnNode<'_>) { match node { @@ -281,16 +247,14 @@ struct TypedAnnotation<'tcx> { maybe_typeck_results: Cell>>, } -impl<'tcx> HirPrinterSupport<'tcx> for TypedAnnotation<'tcx> { +impl<'tcx> Sess for TypedAnnotation<'tcx> { fn sess(&self) -> &Session { self.tcx.sess } - - fn pp_ann(&self) -> &dyn pprust_hir::PpAnn { - self - } } +impl<'tcx> HirPrinterSupport for TypedAnnotation<'tcx> {} + impl<'tcx> pprust_hir::PpAnn for TypedAnnotation<'tcx> { fn nested(&self, state: &mut pprust_hir::State<'_>, nested: pprust_hir::Nested) { let old_maybe_typeck_results = self.maybe_typeck_results.get(); @@ -301,11 +265,13 @@ impl<'tcx> pprust_hir::PpAnn for TypedAnnotation<'tcx> { pprust_hir::PpAnn::nested(pp_ann, state, nested); self.maybe_typeck_results.set(old_maybe_typeck_results); } + fn pre(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) { if let pprust_hir::AnnNode::Expr(_) = node { s.popen(); } } + fn post(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) { if let pprust_hir::AnnNode::Expr(expr) = node { let typeck_results = self.maybe_typeck_results.get().or_else(|| { @@ -359,7 +325,7 @@ pub fn print_after_parsing(sess: &Session, krate: &ast::Crate, ppm: PpMode) { krate, src_name, src, - annotation.pp_ann(), + annotation, false, parse.edition, &sess.parse_sess.attr_id_generator, @@ -396,7 +362,7 @@ pub fn print_after_hir_lowering<'tcx>(tcx: TyCtxt<'tcx>, ppm: PpMode) { &tcx.resolver_for_lowering(()).borrow().1, src_name, src, - annotation.pp_ann(), + annotation, true, parse.edition, &sess.parse_sess.attr_id_generator, @@ -414,14 +380,7 @@ pub fn print_after_hir_lowering<'tcx>(tcx: TyCtxt<'tcx>, ppm: PpMode) { let sess = annotation.sess(); let sm = sess.source_map(); let attrs = |id| hir_map.attrs(id); - pprust_hir::print_crate( - sm, - hir_map.root_module(), - src_name, - src, - &attrs, - annotation.pp_ann(), - ) + pprust_hir::print_crate(sm, hir_map.root_module(), src_name, src, &attrs, annotation) }), HirTree => { From 7d145a0fde3771662648df2de63e8f64033bf598 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 11 Oct 2023 08:49:24 +1100 Subject: [PATCH 44/50] Merge `print_*` functions. The handling of the `PpMode` variants is currently spread across three functions: `print_after_parsing`, `print_after_hir_lowering`, and `print_with_analysis`. Each one handles some of the variants. This split is primarily because `print_after_parsing` has slightly different arguments to the other two. This commit changes the structure. It merges the three functions into a single `print` function, and encapsulates the different arguments in a new enum `PrintExtra`. Benefits: - The code is a little shorter. - All the `PpMode` variants are handled in a single `match`, with no need for `unreachable!` arms. - It enables the trait removal in the subsequent commit by reducing the number of `call_with_pp_support_ast` call sites from two to one. --- compiler/rustc_driver_impl/src/lib.rs | 4 +- compiler/rustc_driver_impl/src/pretty.rs | 118 ++++++++++------------- 2 files changed, 52 insertions(+), 70 deletions(-) diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index bbecf1a1093f..1cddd561ded0 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -396,7 +396,7 @@ fn run_compiler( if ppm.needs_ast_map() { queries.global_ctxt()?.enter(|tcx| { tcx.ensure().early_lint_checks(()); - pretty::print_after_hir_lowering(tcx, *ppm); + pretty::print(sess, *ppm, pretty::PrintExtra::NeedsAstMap { tcx }); Ok(()) })?; @@ -405,7 +405,7 @@ fn run_compiler( queries.global_ctxt()?.enter(|tcx| tcx.output_filenames(())); } else { let krate = queries.parse()?.steal(); - pretty::print_after_parsing(sess, &krate, *ppm); + pretty::print(sess, *ppm, pretty::PrintExtra::AfterParsing { krate }); } trace!("finished pretty-printing"); return early_exit(); diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs index ec118bd33eb9..837f725abe92 100644 --- a/compiler/rustc_driver_impl/src/pretty.rs +++ b/compiler/rustc_driver_impl/src/pretty.rs @@ -2,9 +2,9 @@ use rustc_ast as ast; use rustc_ast_pretty::pprust as pprust_ast; -use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; use rustc_hir_pretty as pprust_hir; +use rustc_middle::bug; use rustc_middle::hir::map as hir_map; use rustc_middle::mir::{write_mir_graphviz, write_mir_pretty}; use rustc_middle::ty::{self, TyCtxt}; @@ -310,106 +310,92 @@ fn write_or_print(out: &str, sess: &Session) { sess.io.output_file.as_ref().unwrap_or(&OutFileName::Stdout).overwrite(out, sess); } -pub fn print_after_parsing(sess: &Session, krate: &ast::Crate, ppm: PpMode) { - let (src, src_name) = get_source(sess); +// Extra data for pretty-printing, the form of which depends on what kind of +// pretty-printing we are doing. +pub enum PrintExtra<'tcx> { + AfterParsing { krate: ast::Crate }, + NeedsAstMap { tcx: TyCtxt<'tcx> }, +} - let out = match ppm { - Source(s) => { - // Silently ignores an identified node. - call_with_pp_support_ast(&s, sess, None, move |annotation| { - debug!("pretty printing source code {:?}", s); - let sess = annotation.sess(); - let parse = &sess.parse_sess; - pprust_ast::print_crate( - sess.source_map(), - krate, - src_name, - src, - annotation, - false, - parse.edition, - &sess.parse_sess.attr_id_generator, - ) - }) +impl<'tcx> PrintExtra<'tcx> { + fn with_krate(&self, f: F) -> R + where + F: FnOnce(&ast::Crate) -> R + { + match self { + PrintExtra::AfterParsing { krate, .. } => f(krate), + PrintExtra::NeedsAstMap { tcx } => f(&tcx.resolver_for_lowering(()).borrow().1), } - AstTree => { - debug!("pretty printing AST tree"); - format!("{krate:#?}") - } - _ => unreachable!(), - }; + } - write_or_print(&out, sess); + fn tcx(&self) -> TyCtxt<'tcx> { + match self { + PrintExtra::AfterParsing { .. } => bug!("PrintExtra::tcx"), + PrintExtra::NeedsAstMap { tcx } => *tcx, + } + } } -pub fn print_after_hir_lowering<'tcx>(tcx: TyCtxt<'tcx>, ppm: PpMode) { +pub fn print<'tcx>(sess: &Session, ppm: PpMode, ex: PrintExtra<'tcx>) { if ppm.needs_analysis() { - abort_on_err(print_with_analysis(tcx, ppm), tcx.sess); - return; + abort_on_err(ex.tcx().analysis(()), sess); } - let (src, src_name) = get_source(tcx.sess); + let (src, src_name) = get_source(sess); let out = match ppm { Source(s) => { // Silently ignores an identified node. - call_with_pp_support_ast(&s, tcx.sess, Some(tcx), move |annotation| { + call_with_pp_support_ast(&s, sess, None, move |annotation| { debug!("pretty printing source code {:?}", s); let sess = annotation.sess(); let parse = &sess.parse_sess; - pprust_ast::print_crate( - sess.source_map(), - &tcx.resolver_for_lowering(()).borrow().1, - src_name, - src, - annotation, - true, - parse.edition, - &sess.parse_sess.attr_id_generator, + let is_expanded = ppm.needs_ast_map(); + ex.with_krate(|krate| + pprust_ast::print_crate( + sess.source_map(), + krate, + src_name, + src, + annotation, + is_expanded, + parse.edition, + &sess.parse_sess.attr_id_generator, + ) ) }) } - + AstTree => { + debug!("pretty printing AST tree"); + ex.with_krate(|krate| format!("{krate:#?}")) + } AstTreeExpanded => { debug!("pretty-printing expanded AST"); - format!("{:#?}", tcx.resolver_for_lowering(()).borrow().1) + format!("{:#?}", ex.tcx().resolver_for_lowering(()).borrow().1) } - - Hir(s) => call_with_pp_support_hir(&s, tcx, move |annotation, hir_map| { + Hir(s) => call_with_pp_support_hir(&s, ex.tcx(), move |annotation, hir_map| { debug!("pretty printing HIR {:?}", s); let sess = annotation.sess(); let sm = sess.source_map(); let attrs = |id| hir_map.attrs(id); pprust_hir::print_crate(sm, hir_map.root_module(), src_name, src, &attrs, annotation) }), - HirTree => { debug!("pretty printing HIR tree"); - format!("{:#?}", tcx.hir().krate()) + format!("{:#?}", ex.tcx().hir().krate()) } - - _ => unreachable!(), - }; - - write_or_print(&out, tcx.sess); -} - -fn print_with_analysis(tcx: TyCtxt<'_>, ppm: PpMode) -> Result<(), ErrorGuaranteed> { - tcx.analysis(())?; - let out = match ppm { Mir => { let mut out = Vec::new(); - write_mir_pretty(tcx, None, &mut out).unwrap(); + write_mir_pretty(ex.tcx(), None, &mut out).unwrap(); String::from_utf8(out).unwrap() } - MirCFG => { let mut out = Vec::new(); - write_mir_graphviz(tcx, None, &mut out).unwrap(); + write_mir_graphviz(ex.tcx(), None, &mut out).unwrap(); String::from_utf8(out).unwrap() } - ThirTree => { + let tcx = ex.tcx(); let mut out = String::new(); abort_on_err(rustc_hir_analysis::check_crate(tcx), tcx.sess); debug!("pretty printing THIR tree"); @@ -418,8 +404,8 @@ fn print_with_analysis(tcx: TyCtxt<'_>, ppm: PpMode) -> Result<(), ErrorGuarante } out } - ThirFlat => { + let tcx = ex.tcx(); let mut out = String::new(); abort_on_err(rustc_hir_analysis::check_crate(tcx), tcx.sess); debug!("pretty printing THIR flat"); @@ -428,11 +414,7 @@ fn print_with_analysis(tcx: TyCtxt<'_>, ppm: PpMode) -> Result<(), ErrorGuarante } out } - - _ => unreachable!(), }; - write_or_print(&out, tcx.sess); - - Ok(()) + write_or_print(&out, sess); } From 060851b7646dff523c25958930b2a7cbe6ce91a1 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 11 Oct 2023 08:55:41 +1100 Subject: [PATCH 45/50] Remove pretty-printing traits. `call_with_pp_support_ast` and `call_with_pp_support_hir` how each have a single call site. This commit inlines and removes them, which also removes the need for all the supporting traits: `Sess`, `AstPrinterSupport`, and `HirPrinterSupport`. The `sess` member is also removed from several structs. --- compiler/rustc_driver_impl/src/lib.rs | 1 - compiler/rustc_driver_impl/src/pretty.rs | 181 +++++++---------------- 2 files changed, 52 insertions(+), 130 deletions(-) diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 1cddd561ded0..4074d57433ef 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -12,7 +12,6 @@ #![feature(lazy_cell)] #![feature(let_chains)] #![feature(panic_update_hook)] -#![feature(trait_upcasting)] #![recursion_limit = "256"] #![allow(rustc::potential_query_instability)] #![deny(rustc::untranslatable_diagnostic)] diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs index 837f725abe92..4145b5baeb01 100644 --- a/compiler/rustc_driver_impl/src/pretty.rs +++ b/compiler/rustc_driver_impl/src/pretty.rs @@ -5,7 +5,6 @@ use rustc_ast_pretty::pprust as pprust_ast; use rustc_hir as hir; use rustc_hir_pretty as pprust_hir; use rustc_middle::bug; -use rustc_middle::hir::map as hir_map; use rustc_middle::mir::{write_mir_graphviz, write_mir_pretty}; use rustc_middle::ty::{self, TyCtxt}; use rustc_session::config::{OutFileName, PpHirMode, PpMode, PpSourceMode}; @@ -20,87 +19,10 @@ pub use self::PpMode::*; pub use self::PpSourceMode::*; use crate::abort_on_err; -// This slightly awkward construction is to allow for each PpMode to -// choose whether it needs to do analyses (which can consume the -// Session) and then pass through the session (now attached to the -// analysis results) on to the chosen pretty-printer, along with the -// `&PpAnn` object. -// -// Note that since the `&AstPrinterSupport` is freshly constructed on each -// call, it would not make sense to try to attach the lifetime of `self` -// to the lifetime of the `&PrinterObject`. - -/// Constructs an `AstPrinterSupport` object and passes it to `f`. -fn call_with_pp_support_ast<'tcx, A, F>( - ppmode: &PpSourceMode, - sess: &'tcx Session, - tcx: Option>, - f: F, -) -> A -where - F: FnOnce(&dyn AstPrinterSupport) -> A, -{ - match *ppmode { - Normal | Expanded => { - let annotation = NoAnn { sess, tcx }; - f(&annotation) - } - Identified | ExpandedIdentified => { - let annotation = IdentifiedAnnotation { sess, tcx }; - f(&annotation) - } - ExpandedHygiene => { - let annotation = HygieneAnnotation { sess }; - f(&annotation) - } - } -} - -fn call_with_pp_support_hir(ppmode: &PpHirMode, tcx: TyCtxt<'_>, f: F) -> A -where - F: FnOnce(&dyn HirPrinterSupport, hir_map::Map<'_>) -> A, -{ - match *ppmode { - PpHirMode::Normal => { - let annotation = NoAnn { sess: tcx.sess, tcx: Some(tcx) }; - f(&annotation, tcx.hir()) - } - PpHirMode::Identified => { - let annotation = IdentifiedAnnotation { sess: tcx.sess, tcx: Some(tcx) }; - f(&annotation, tcx.hir()) - } - PpHirMode::Typed => { - abort_on_err(tcx.analysis(()), tcx.sess); - - let annotation = TypedAnnotation { tcx, maybe_typeck_results: Cell::new(None) }; - tcx.dep_graph.with_ignore(|| f(&annotation, tcx.hir())) - } - } -} - -trait Sess { - /// Provides a uniform interface for re-extracting a reference to a - /// `Session`. - fn sess(&self) -> &Session; -} - -trait AstPrinterSupport: pprust_ast::PpAnn + Sess {} -trait HirPrinterSupport: pprust_hir::PpAnn + Sess {} - struct NoAnn<'hir> { - sess: &'hir Session, tcx: Option>, } -impl<'hir> Sess for NoAnn<'hir> { - fn sess(&self) -> &Session { - self.sess - } -} - -impl<'tcx> AstPrinterSupport for NoAnn<'tcx> {} -impl<'hir> HirPrinterSupport for NoAnn<'hir> {} - impl<'hir> pprust_ast::PpAnn for NoAnn<'hir> {} impl<'hir> pprust_hir::PpAnn for NoAnn<'hir> { fn nested(&self, state: &mut pprust_hir::State<'_>, nested: pprust_hir::Nested) { @@ -111,18 +33,9 @@ impl<'hir> pprust_hir::PpAnn for NoAnn<'hir> { } struct IdentifiedAnnotation<'hir> { - sess: &'hir Session, tcx: Option>, } -impl<'hir> Sess for IdentifiedAnnotation<'hir> { - fn sess(&self) -> &Session { - self.sess - } -} - -impl<'hir> AstPrinterSupport for IdentifiedAnnotation<'hir> {} - impl<'hir> pprust_ast::PpAnn for IdentifiedAnnotation<'hir> { fn pre(&self, s: &mut pprust_ast::State<'_>, node: pprust_ast::AnnNode<'_>) { if let pprust_ast::AnnNode::Expr(_) = node { @@ -161,8 +74,6 @@ impl<'hir> pprust_ast::PpAnn for IdentifiedAnnotation<'hir> { } } -impl<'hir> HirPrinterSupport for IdentifiedAnnotation<'hir> {} - impl<'hir> pprust_hir::PpAnn for IdentifiedAnnotation<'hir> { fn nested(&self, state: &mut pprust_hir::State<'_>, nested: pprust_hir::Nested) { if let Some(ref tcx) = self.tcx { @@ -212,14 +123,6 @@ struct HygieneAnnotation<'a> { sess: &'a Session, } -impl<'a> Sess for HygieneAnnotation<'a> { - fn sess(&self) -> &Session { - self.sess - } -} - -impl<'a> AstPrinterSupport for HygieneAnnotation<'a> {} - impl<'a> pprust_ast::PpAnn for HygieneAnnotation<'a> { fn post(&self, s: &mut pprust_ast::State<'_>, node: pprust_ast::AnnNode<'_>) { match node { @@ -247,14 +150,6 @@ struct TypedAnnotation<'tcx> { maybe_typeck_results: Cell>>, } -impl<'tcx> Sess for TypedAnnotation<'tcx> { - fn sess(&self) -> &Session { - self.tcx.sess - } -} - -impl<'tcx> HirPrinterSupport for TypedAnnotation<'tcx> {} - impl<'tcx> pprust_hir::PpAnn for TypedAnnotation<'tcx> { fn nested(&self, state: &mut pprust_hir::State<'_>, nested: pprust_hir::Nested) { let old_maybe_typeck_results = self.maybe_typeck_results.get(); @@ -320,7 +215,7 @@ pub enum PrintExtra<'tcx> { impl<'tcx> PrintExtra<'tcx> { fn with_krate(&self, f: F) -> R where - F: FnOnce(&ast::Crate) -> R + F: FnOnce(&ast::Crate) -> R, { match self { PrintExtra::AfterParsing { krate, .. } => f(krate), @@ -345,23 +240,26 @@ pub fn print<'tcx>(sess: &Session, ppm: PpMode, ex: PrintExtra<'tcx>) { let out = match ppm { Source(s) => { - // Silently ignores an identified node. - call_with_pp_support_ast(&s, sess, None, move |annotation| { - debug!("pretty printing source code {:?}", s); - let sess = annotation.sess(); - let parse = &sess.parse_sess; - let is_expanded = ppm.needs_ast_map(); - ex.with_krate(|krate| - pprust_ast::print_crate( - sess.source_map(), - krate, - src_name, - src, - annotation, - is_expanded, - parse.edition, - &sess.parse_sess.attr_id_generator, - ) + debug!("pretty printing source code {:?}", s); + let annotation: Box = match s { + Normal => Box::new(NoAnn { tcx: None }), + Expanded => Box::new(NoAnn { tcx: Some(ex.tcx()) }), + Identified => Box::new(IdentifiedAnnotation { tcx: None }), + ExpandedIdentified => Box::new(IdentifiedAnnotation { tcx: Some(ex.tcx()) }), + ExpandedHygiene => Box::new(HygieneAnnotation { sess }), + }; + let parse = &sess.parse_sess; + let is_expanded = ppm.needs_ast_map(); + ex.with_krate(|krate| { + pprust_ast::print_crate( + sess.source_map(), + krate, + src_name, + src, + &*annotation, + is_expanded, + parse.edition, + &sess.parse_sess.attr_id_generator, ) }) } @@ -373,13 +271,38 @@ pub fn print<'tcx>(sess: &Session, ppm: PpMode, ex: PrintExtra<'tcx>) { debug!("pretty-printing expanded AST"); format!("{:#?}", ex.tcx().resolver_for_lowering(()).borrow().1) } - Hir(s) => call_with_pp_support_hir(&s, ex.tcx(), move |annotation, hir_map| { + Hir(s) => { debug!("pretty printing HIR {:?}", s); - let sess = annotation.sess(); - let sm = sess.source_map(); - let attrs = |id| hir_map.attrs(id); - pprust_hir::print_crate(sm, hir_map.root_module(), src_name, src, &attrs, annotation) - }), + let tcx = ex.tcx(); + let f = |annotation: &dyn pprust_hir::PpAnn| { + let sm = sess.source_map(); + let hir_map = tcx.hir(); + let attrs = |id| hir_map.attrs(id); + pprust_hir::print_crate( + sm, + hir_map.root_module(), + src_name, + src, + &attrs, + annotation, + ) + }; + match s { + PpHirMode::Normal => { + let annotation = NoAnn { tcx: Some(tcx) }; + f(&annotation) + } + PpHirMode::Identified => { + let annotation = IdentifiedAnnotation { tcx: Some(tcx) }; + f(&annotation) + } + PpHirMode::Typed => { + abort_on_err(tcx.analysis(()), tcx.sess); + let annotation = TypedAnnotation { tcx, maybe_typeck_results: Cell::new(None) }; + tcx.dep_graph.with_ignore(|| f(&annotation)) + } + } + } HirTree => { debug!("pretty printing HIR tree"); format!("{:#?}", ex.tcx().hir().krate()) From ba58e3213db9626381f5fd014e569f7d2335fa03 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 11 Oct 2023 08:58:27 +1100 Subject: [PATCH 46/50] Rename some `'hir` lifetimes as `'tcx`. Because they all end up within a `TyCtxt`. --- compiler/rustc_driver_impl/src/pretty.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs index 4145b5baeb01..daba78612f5c 100644 --- a/compiler/rustc_driver_impl/src/pretty.rs +++ b/compiler/rustc_driver_impl/src/pretty.rs @@ -19,12 +19,12 @@ pub use self::PpMode::*; pub use self::PpSourceMode::*; use crate::abort_on_err; -struct NoAnn<'hir> { - tcx: Option>, +struct NoAnn<'tcx> { + tcx: Option>, } -impl<'hir> pprust_ast::PpAnn for NoAnn<'hir> {} -impl<'hir> pprust_hir::PpAnn for NoAnn<'hir> { +impl<'tcx> pprust_ast::PpAnn for NoAnn<'tcx> {} +impl<'tcx> pprust_hir::PpAnn for NoAnn<'tcx> { fn nested(&self, state: &mut pprust_hir::State<'_>, nested: pprust_hir::Nested) { if let Some(tcx) = self.tcx { pprust_hir::PpAnn::nested(&(&tcx.hir() as &dyn hir::intravisit::Map<'_>), state, nested) @@ -32,11 +32,11 @@ impl<'hir> pprust_hir::PpAnn for NoAnn<'hir> { } } -struct IdentifiedAnnotation<'hir> { - tcx: Option>, +struct IdentifiedAnnotation<'tcx> { + tcx: Option>, } -impl<'hir> pprust_ast::PpAnn for IdentifiedAnnotation<'hir> { +impl<'tcx> pprust_ast::PpAnn for IdentifiedAnnotation<'tcx> { fn pre(&self, s: &mut pprust_ast::State<'_>, node: pprust_ast::AnnNode<'_>) { if let pprust_ast::AnnNode::Expr(_) = node { s.popen(); @@ -74,7 +74,7 @@ impl<'hir> pprust_ast::PpAnn for IdentifiedAnnotation<'hir> { } } -impl<'hir> pprust_hir::PpAnn for IdentifiedAnnotation<'hir> { +impl<'tcx> pprust_hir::PpAnn for IdentifiedAnnotation<'tcx> { fn nested(&self, state: &mut pprust_hir::State<'_>, nested: pprust_hir::Nested) { if let Some(ref tcx) = self.tcx { pprust_hir::PpAnn::nested(&(&tcx.hir() as &dyn hir::intravisit::Map<'_>), state, nested) From b65227a9ee38cd21e0b4ffbec7542d2638b661a2 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 11 Oct 2023 09:31:43 +1100 Subject: [PATCH 47/50] Make `needs_analysis` true for `PpHirMode::Typed`. This avoids the need for a bespoke `tcx.analysis()` call. --- compiler/rustc_driver_impl/src/pretty.rs | 1 - compiler/rustc_session/src/config.rs | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs index daba78612f5c..87e3af2f9d9c 100644 --- a/compiler/rustc_driver_impl/src/pretty.rs +++ b/compiler/rustc_driver_impl/src/pretty.rs @@ -297,7 +297,6 @@ pub fn print<'tcx>(sess: &Session, ppm: PpMode, ex: PrintExtra<'tcx>) { f(&annotation) } PpHirMode::Typed => { - abort_on_err(tcx.analysis(()), tcx.sess); let annotation = TypedAnnotation { tcx, maybe_typeck_results: Cell::new(None) }; tcx.dep_graph.with_ignore(|| f(&annotation)) } diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 056986a81441..2a6f5994c490 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -3144,7 +3144,7 @@ impl PpMode { pub fn needs_analysis(&self) -> bool { use PpMode::*; - matches!(*self, Mir | MirCFG | ThirTree | ThirFlat) + matches!(*self, Hir(PpHirMode::Typed) | Mir | MirCFG | ThirTree | ThirFlat) } } From 2e2924f2631bebbf2e0f5f40e26bf5d8d032c6d4 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 11 Oct 2023 09:47:15 +1100 Subject: [PATCH 48/50] Split and rename the annotation structs. `NoAnn` and `IdentifiedAnnotation` impl both `pprust_ast::PpAnn` and `pprust_hir::PpAnn`, which is a bit confusing, because the optional `tcx` is only needed for the HIR cases. (Currently the `tcx` is unnecessarily provided in the `expanded` AST cases.) This commit splits each one into `Ast` and `Hir` versions, which makes things clear about where the `tcx` is needed. The commit also renames all the traits so they consistently end with `Ann`. --- compiler/rustc_driver_impl/src/pretty.rs | 63 ++++++++++++++---------- 1 file changed, 36 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs index 87e3af2f9d9c..8c6fee830130 100644 --- a/compiler/rustc_driver_impl/src/pretty.rs +++ b/compiler/rustc_driver_impl/src/pretty.rs @@ -19,24 +19,27 @@ pub use self::PpMode::*; pub use self::PpSourceMode::*; use crate::abort_on_err; -struct NoAnn<'tcx> { - tcx: Option>, +struct AstNoAnn; + +impl pprust_ast::PpAnn for AstNoAnn {} + +struct HirNoAnn<'tcx> { + tcx: TyCtxt<'tcx>, } -impl<'tcx> pprust_ast::PpAnn for NoAnn<'tcx> {} -impl<'tcx> pprust_hir::PpAnn for NoAnn<'tcx> { +impl<'tcx> pprust_hir::PpAnn for HirNoAnn<'tcx> { fn nested(&self, state: &mut pprust_hir::State<'_>, nested: pprust_hir::Nested) { - if let Some(tcx) = self.tcx { - pprust_hir::PpAnn::nested(&(&tcx.hir() as &dyn hir::intravisit::Map<'_>), state, nested) - } + pprust_hir::PpAnn::nested( + &(&self.tcx.hir() as &dyn hir::intravisit::Map<'_>), + state, + nested, + ) } } -struct IdentifiedAnnotation<'tcx> { - tcx: Option>, -} +struct AstIdentifiedAnn; -impl<'tcx> pprust_ast::PpAnn for IdentifiedAnnotation<'tcx> { +impl pprust_ast::PpAnn for AstIdentifiedAnn { fn pre(&self, s: &mut pprust_ast::State<'_>, node: pprust_ast::AnnNode<'_>) { if let pprust_ast::AnnNode::Expr(_) = node { s.popen(); @@ -74,11 +77,17 @@ impl<'tcx> pprust_ast::PpAnn for IdentifiedAnnotation<'tcx> { } } -impl<'tcx> pprust_hir::PpAnn for IdentifiedAnnotation<'tcx> { +struct HirIdentifiedAnn<'tcx> { + tcx: TyCtxt<'tcx>, +} + +impl<'tcx> pprust_hir::PpAnn for HirIdentifiedAnn<'tcx> { fn nested(&self, state: &mut pprust_hir::State<'_>, nested: pprust_hir::Nested) { - if let Some(ref tcx) = self.tcx { - pprust_hir::PpAnn::nested(&(&tcx.hir() as &dyn hir::intravisit::Map<'_>), state, nested) - } + pprust_hir::PpAnn::nested( + &(&self.tcx.hir() as &dyn hir::intravisit::Map<'_>), + state, + nested, + ) } fn pre(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) { @@ -119,11 +128,11 @@ impl<'tcx> pprust_hir::PpAnn for IdentifiedAnnotation<'tcx> { } } -struct HygieneAnnotation<'a> { +struct AstHygieneAnn<'a> { sess: &'a Session, } -impl<'a> pprust_ast::PpAnn for HygieneAnnotation<'a> { +impl<'a> pprust_ast::PpAnn for AstHygieneAnn<'a> { fn post(&self, s: &mut pprust_ast::State<'_>, node: pprust_ast::AnnNode<'_>) { match node { pprust_ast::AnnNode::Ident(&Ident { name, span }) => { @@ -145,12 +154,12 @@ impl<'a> pprust_ast::PpAnn for HygieneAnnotation<'a> { } } -struct TypedAnnotation<'tcx> { +struct HirTypedAnn<'tcx> { tcx: TyCtxt<'tcx>, maybe_typeck_results: Cell>>, } -impl<'tcx> pprust_hir::PpAnn for TypedAnnotation<'tcx> { +impl<'tcx> pprust_hir::PpAnn for HirTypedAnn<'tcx> { fn nested(&self, state: &mut pprust_hir::State<'_>, nested: pprust_hir::Nested) { let old_maybe_typeck_results = self.maybe_typeck_results.get(); if let pprust_hir::Nested::Body(id) = nested { @@ -242,11 +251,11 @@ pub fn print<'tcx>(sess: &Session, ppm: PpMode, ex: PrintExtra<'tcx>) { Source(s) => { debug!("pretty printing source code {:?}", s); let annotation: Box = match s { - Normal => Box::new(NoAnn { tcx: None }), - Expanded => Box::new(NoAnn { tcx: Some(ex.tcx()) }), - Identified => Box::new(IdentifiedAnnotation { tcx: None }), - ExpandedIdentified => Box::new(IdentifiedAnnotation { tcx: Some(ex.tcx()) }), - ExpandedHygiene => Box::new(HygieneAnnotation { sess }), + Normal => Box::new(AstNoAnn), + Expanded => Box::new(AstNoAnn), + Identified => Box::new(AstIdentifiedAnn), + ExpandedIdentified => Box::new(AstIdentifiedAnn), + ExpandedHygiene => Box::new(AstHygieneAnn { sess }), }; let parse = &sess.parse_sess; let is_expanded = ppm.needs_ast_map(); @@ -289,15 +298,15 @@ pub fn print<'tcx>(sess: &Session, ppm: PpMode, ex: PrintExtra<'tcx>) { }; match s { PpHirMode::Normal => { - let annotation = NoAnn { tcx: Some(tcx) }; + let annotation = HirNoAnn { tcx }; f(&annotation) } PpHirMode::Identified => { - let annotation = IdentifiedAnnotation { tcx: Some(tcx) }; + let annotation = HirIdentifiedAnn { tcx }; f(&annotation) } PpHirMode::Typed => { - let annotation = TypedAnnotation { tcx, maybe_typeck_results: Cell::new(None) }; + let annotation = HirTypedAnn { tcx, maybe_typeck_results: Cell::new(None) }; tcx.dep_graph.with_ignore(|| f(&annotation)) } } From 2b4c33817a5aaecabf4c6598d41e190080ec119e Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 6 Oct 2023 18:15:46 +1100 Subject: [PATCH 49/50] Remove unneeded `pub`s. --- compiler/rustc_driver_impl/src/lib.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 4074d57433ef..7a45ac10f0ba 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -545,7 +545,7 @@ pub enum Compilation { } impl Compilation { - pub fn and_then Compilation>(self, next: F) -> Compilation { + fn and_then Compilation>(self, next: F) -> Compilation { match self { Compilation::Stop => Compilation::Stop, Compilation::Continue => next(), @@ -657,7 +657,7 @@ fn show_md_content_with_pager(content: &str, color: ColorConfig) { } } -pub fn try_process_rlink(sess: &Session, compiler: &interface::Compiler) -> Compilation { +fn try_process_rlink(sess: &Session, compiler: &interface::Compiler) -> Compilation { if sess.opts.unstable_opts.link_only { if let Input::File(file) = &sess.io.input { let outputs = compiler.build_output_filenames(sess, &[]); @@ -698,7 +698,7 @@ pub fn try_process_rlink(sess: &Session, compiler: &interface::Compiler) -> Comp } } -pub fn list_metadata( +fn list_metadata( handler: &EarlyErrorHandler, sess: &Session, metadata_loader: &dyn MetadataLoader, @@ -1184,7 +1184,7 @@ fn print_flag_list( /// /// So with all that in mind, the comments below have some more detail about the /// contortions done here to get things to work out correctly. -pub fn handle_options(handler: &EarlyErrorHandler, args: &[String]) -> Option { +fn handle_options(handler: &EarlyErrorHandler, args: &[String]) -> Option { if args.is_empty() { // user did not write `-v` nor `-Z unstable-options`, so do not // include that extra information. @@ -1283,9 +1283,9 @@ pub fn catch_with_exit_code(f: impl FnOnce() -> interface::Result<()>) -> i32 { } } -pub static ICE_PATH: OnceLock> = OnceLock::new(); +static ICE_PATH: OnceLock> = OnceLock::new(); -pub fn ice_path() -> &'static Option { +fn ice_path() -> &'static Option { ICE_PATH.get_or_init(|| { if !rustc_feature::UnstableFeatures::from_environment(None).is_nightly_build() { return None; @@ -1394,7 +1394,7 @@ pub fn install_ice_hook(bug_report_url: &'static str, extra_info: fn(&Handler)) /// /// When `install_ice_hook` is called, this function will be called as the panic /// hook. -pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str, extra_info: fn(&Handler)) { +fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str, extra_info: fn(&Handler)) { let fallback_bundle = rustc_errors::fallback_fluent_bundle(crate::DEFAULT_LOCALE_RESOURCES.to_vec(), false); let emitter = Box::new(rustc_errors::emitter::EmitterWriter::stderr( From 7b89422ff5059eb3ab27d9bdc6c0b8d7164d3b1e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 13 Oct 2023 09:00:10 +0000 Subject: [PATCH 50/50] remove excluded files from upstream This commit is generated by `ferrocene/tools/pull-upstream/pull.sh`. The list of excluded files is defined in `.gitattributes`. --- .github/ISSUE_TEMPLATE/blank_issue.md | 4 - .github/ISSUE_TEMPLATE/bug_report.md | 44 - .github/ISSUE_TEMPLATE/config.yml | 11 - .github/ISSUE_TEMPLATE/diagnostics.yaml | 65 -- .github/ISSUE_TEMPLATE/documentation.yaml | 38 - .github/ISSUE_TEMPLATE/ice.md | 49 -- .github/ISSUE_TEMPLATE/ice.yaml | 82 -- .../ISSUE_TEMPLATE/library_tracking_issue.md | 85 -- .github/ISSUE_TEMPLATE/regression.md | 68 -- .github/ISSUE_TEMPLATE/tracking_issue.md | 63 -- .github/workflows/ci.yml | 711 ---------------- .github/workflows/dependencies.yml | 142 ---- CODE_OF_CONDUCT.md | 3 - CONTRIBUTING.md | 42 - README.md | 301 ------- .../.github/actions/github-release/README.md | 18 - .../.github/actions/github-release/action.yml | 13 - .../.github/actions/github-release/main.js | 162 ---- .../actions/github-release/package-lock.json | 571 ------------- .../actions/github-release/package.json | 11 - .../.github/workflows/abi-cafe.yml | 57 -- .../.github/workflows/audit.yml | 19 - .../.github/workflows/main.yml | 292 ------- .../.github/workflows/rustc.yml | 44 - .../.github/workflows/ci.yml | 154 ---- .../.github/workflows/release.yml | 113 --- .../.github/workflows/stdarch.yml | 140 ---- .../.github/ISSUE_TEMPLATE/blank_issue.md | 4 - .../.github/ISSUE_TEMPLATE/bug_report.md | 50 -- .../.github/ISSUE_TEMPLATE/config.yml | 10 - .../.github/ISSUE_TEMPLATE/feature_request.md | 14 - .../.github/PULL_REQUEST_TEMPLATE.md | 18 - .../portable-simd/.github/workflows/ci.yml | 265 ------ .../portable-simd/.github/workflows/doc.yml | 30 - .../.github/ISSUE_TEMPLATE/blank_issue.yml | 44 - .../.github/ISSUE_TEMPLATE/bug_report.yml | 57 -- .../clippy/.github/ISSUE_TEMPLATE/config.yml | 5 - .../.github/ISSUE_TEMPLATE/false_negative.yml | 50 -- .../.github/ISSUE_TEMPLATE/false_positive.yml | 68 -- .../clippy/.github/ISSUE_TEMPLATE/ice.yml | 48 -- .../.github/ISSUE_TEMPLATE/new_lint.yml | 48 -- .../clippy/.github/PULL_REQUEST_TEMPLATE.md | 39 - src/tools/clippy/.github/deploy.sh | 67 -- src/tools/clippy/.github/driver.sh | 46 -- src/tools/clippy/.github/workflows/clippy.yml | 77 -- .../clippy/.github/workflows/clippy_bors.yml | 282 ------- .../clippy/.github/workflows/clippy_dev.yml | 71 -- src/tools/clippy/.github/workflows/deploy.yml | 64 -- src/tools/clippy/.github/workflows/remark.yml | 72 -- src/tools/miri/.github/workflows/ci.yml | 218 ----- .../.github/ISSUE_TEMPLATE/bug_report.md | 25 - .../critical_nightly_regression.md | 16 - .../.github/ISSUE_TEMPLATE/feature_request.md | 8 - .../.github/ISSUE_TEMPLATE/question.md | 8 - .../.github/actions/github-release/Dockerfile | 8 - .../.github/actions/github-release/README.md | 21 - .../.github/actions/github-release/action.yml | 15 - .../.github/actions/github-release/main.js | 144 ---- .../actions/github-release/package.json | 10 - .../.github/workflows/autopublish.yaml | 56 -- .../rust-analyzer/.github/workflows/ci.yaml | 221 ----- .../rust-analyzer/.github/workflows/fuzz.yml | 43 - .../.github/workflows/metrics.yaml | 150 ---- .../.github/workflows/publish-libs.yaml | 35 - .../.github/workflows/release.yaml | 281 ------- .../.github/workflows/rustdoc.yaml | 34 - .../rustfmt/.github/workflows/check_diff.yml | 33 - .../rustfmt/.github/workflows/integration.yml | 81 -- src/tools/rustfmt/.github/workflows/linux.yml | 39 - src/tools/rustfmt/.github/workflows/mac.yml | 36 - .../.github/workflows/rustdoc_check.yml | 25 - .../.github/workflows/upload-assets.yml | 78 -- .../rustfmt/.github/workflows/windows.yml | 62 -- triagebot.toml | 761 ------------------ 74 files changed, 7139 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/blank_issue.md delete mode 100644 .github/ISSUE_TEMPLATE/bug_report.md delete mode 100644 .github/ISSUE_TEMPLATE/config.yml delete mode 100644 .github/ISSUE_TEMPLATE/diagnostics.yaml delete mode 100644 .github/ISSUE_TEMPLATE/documentation.yaml delete mode 100644 .github/ISSUE_TEMPLATE/ice.md delete mode 100644 .github/ISSUE_TEMPLATE/ice.yaml delete mode 100644 .github/ISSUE_TEMPLATE/library_tracking_issue.md delete mode 100644 .github/ISSUE_TEMPLATE/regression.md delete mode 100644 .github/ISSUE_TEMPLATE/tracking_issue.md delete mode 100644 .github/workflows/ci.yml delete mode 100644 .github/workflows/dependencies.yml delete mode 100644 CODE_OF_CONDUCT.md delete mode 100644 CONTRIBUTING.md delete mode 100644 README.md delete mode 100644 compiler/rustc_codegen_cranelift/.github/actions/github-release/README.md delete mode 100644 compiler/rustc_codegen_cranelift/.github/actions/github-release/action.yml delete mode 100644 compiler/rustc_codegen_cranelift/.github/actions/github-release/main.js delete mode 100644 compiler/rustc_codegen_cranelift/.github/actions/github-release/package-lock.json delete mode 100644 compiler/rustc_codegen_cranelift/.github/actions/github-release/package.json delete mode 100644 compiler/rustc_codegen_cranelift/.github/workflows/abi-cafe.yml delete mode 100644 compiler/rustc_codegen_cranelift/.github/workflows/audit.yml delete mode 100644 compiler/rustc_codegen_cranelift/.github/workflows/main.yml delete mode 100644 compiler/rustc_codegen_cranelift/.github/workflows/rustc.yml delete mode 100644 compiler/rustc_codegen_gcc/.github/workflows/ci.yml delete mode 100644 compiler/rustc_codegen_gcc/.github/workflows/release.yml delete mode 100644 compiler/rustc_codegen_gcc/.github/workflows/stdarch.yml delete mode 100644 library/portable-simd/.github/ISSUE_TEMPLATE/blank_issue.md delete mode 100644 library/portable-simd/.github/ISSUE_TEMPLATE/bug_report.md delete mode 100644 library/portable-simd/.github/ISSUE_TEMPLATE/config.yml delete mode 100644 library/portable-simd/.github/ISSUE_TEMPLATE/feature_request.md delete mode 100644 library/portable-simd/.github/PULL_REQUEST_TEMPLATE.md delete mode 100644 library/portable-simd/.github/workflows/ci.yml delete mode 100644 library/portable-simd/.github/workflows/doc.yml delete mode 100644 src/tools/clippy/.github/ISSUE_TEMPLATE/blank_issue.yml delete mode 100644 src/tools/clippy/.github/ISSUE_TEMPLATE/bug_report.yml delete mode 100644 src/tools/clippy/.github/ISSUE_TEMPLATE/config.yml delete mode 100644 src/tools/clippy/.github/ISSUE_TEMPLATE/false_negative.yml delete mode 100644 src/tools/clippy/.github/ISSUE_TEMPLATE/false_positive.yml delete mode 100644 src/tools/clippy/.github/ISSUE_TEMPLATE/ice.yml delete mode 100644 src/tools/clippy/.github/ISSUE_TEMPLATE/new_lint.yml delete mode 100644 src/tools/clippy/.github/PULL_REQUEST_TEMPLATE.md delete mode 100644 src/tools/clippy/.github/deploy.sh delete mode 100644 src/tools/clippy/.github/driver.sh delete mode 100644 src/tools/clippy/.github/workflows/clippy.yml delete mode 100644 src/tools/clippy/.github/workflows/clippy_bors.yml delete mode 100644 src/tools/clippy/.github/workflows/clippy_dev.yml delete mode 100644 src/tools/clippy/.github/workflows/deploy.yml delete mode 100644 src/tools/clippy/.github/workflows/remark.yml delete mode 100644 src/tools/miri/.github/workflows/ci.yml delete mode 100644 src/tools/rust-analyzer/.github/ISSUE_TEMPLATE/bug_report.md delete mode 100644 src/tools/rust-analyzer/.github/ISSUE_TEMPLATE/critical_nightly_regression.md delete mode 100644 src/tools/rust-analyzer/.github/ISSUE_TEMPLATE/feature_request.md delete mode 100644 src/tools/rust-analyzer/.github/ISSUE_TEMPLATE/question.md delete mode 100644 src/tools/rust-analyzer/.github/actions/github-release/Dockerfile delete mode 100644 src/tools/rust-analyzer/.github/actions/github-release/README.md delete mode 100644 src/tools/rust-analyzer/.github/actions/github-release/action.yml delete mode 100644 src/tools/rust-analyzer/.github/actions/github-release/main.js delete mode 100644 src/tools/rust-analyzer/.github/actions/github-release/package.json delete mode 100644 src/tools/rust-analyzer/.github/workflows/autopublish.yaml delete mode 100644 src/tools/rust-analyzer/.github/workflows/ci.yaml delete mode 100644 src/tools/rust-analyzer/.github/workflows/fuzz.yml delete mode 100644 src/tools/rust-analyzer/.github/workflows/metrics.yaml delete mode 100644 src/tools/rust-analyzer/.github/workflows/publish-libs.yaml delete mode 100644 src/tools/rust-analyzer/.github/workflows/release.yaml delete mode 100644 src/tools/rust-analyzer/.github/workflows/rustdoc.yaml delete mode 100644 src/tools/rustfmt/.github/workflows/check_diff.yml delete mode 100644 src/tools/rustfmt/.github/workflows/integration.yml delete mode 100644 src/tools/rustfmt/.github/workflows/linux.yml delete mode 100644 src/tools/rustfmt/.github/workflows/mac.yml delete mode 100644 src/tools/rustfmt/.github/workflows/rustdoc_check.yml delete mode 100644 src/tools/rustfmt/.github/workflows/upload-assets.yml delete mode 100644 src/tools/rustfmt/.github/workflows/windows.yml delete mode 100644 triagebot.toml diff --git a/.github/ISSUE_TEMPLATE/blank_issue.md b/.github/ISSUE_TEMPLATE/blank_issue.md deleted file mode 100644 index 9aef3ebe637a..000000000000 --- a/.github/ISSUE_TEMPLATE/blank_issue.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -name: Blank Issue -about: Create a blank issue. ---- diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 5675579bc964..000000000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -name: Bug Report -about: Create a bug report for Rust. -labels: C-bug ---- - - -I tried this code: - -```rust - -``` - -I expected to see this happen: *explanation* - -Instead, this happened: *explanation* - -### Meta - - -`rustc --version --verbose`: -``` - -``` - - -
Backtrace -

- -``` - -``` - -

-
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml deleted file mode 100644 index a2878a0e0120..000000000000 --- a/.github/ISSUE_TEMPLATE/config.yml +++ /dev/null @@ -1,11 +0,0 @@ -blank_issues_enabled: true -contact_links: - - name: Question - url: https://users.rust-lang.org - about: Please ask and answer questions about Rust on the user forum. - - name: Feature Request - url: https://internals.rust-lang.org/ - about: Please discuss language feature requests on the internals forum. - - name: Clippy Bug - url: https://github.com/rust-lang/rust-clippy/issues/new/choose - about: Please report Clippy bugs such as false positives in the Clippy repo. diff --git a/.github/ISSUE_TEMPLATE/diagnostics.yaml b/.github/ISSUE_TEMPLATE/diagnostics.yaml deleted file mode 100644 index 873fbaaf654f..000000000000 --- a/.github/ISSUE_TEMPLATE/diagnostics.yaml +++ /dev/null @@ -1,65 +0,0 @@ -name: Diagnostic issue -description: Create a bug report or feature request for a change to `rustc`'s error output -labels: ["A-diagnostics", "T-compiler"] -body: - - type: markdown - attributes: - value: | - Thank you for filing a diagnostics bug report! 🐛 - - Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. - - If you cannot produce a minimal reproduction case (something that would work in isolation), please provide the steps or even link to a repository that causes the problematic output to occur. - - type: textarea - id: code - attributes: - label: Code - description: Please provide code that can reproduce the problem - placeholder: code - render: Rust - validations: - required: true - - type: textarea - id: output - attributes: - label: Current output - description: Please provide the `rustc` output you see - placeholder: rustc output - render: Shell - validations: - required: true - - type: textarea - id: desired-output - attributes: - label: Desired output - description: Please provide what the output *should* be - placeholder: proposed output - render: Shell - validations: - required: false - - type: textarea - id: rationale - attributes: - label: Rationale and extra context - description: If the problem is not self-explanatory, please provide a rationale for the change. - validations: - required: false - - type: textarea - id: other-output - attributes: - label: Other cases - description: If dramatically different output is caused by small changes, consider also adding them here. - render: Rust - validations: - required: false - - type: markdown - attributes: - value: | - If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. The output might also be different depending on the Edition. - - type: textarea - id: extra - attributes: - label: Anything else? - description: If you have more details you want to give us to reproduce this issue, please add it here - validations: - required: false \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/documentation.yaml b/.github/ISSUE_TEMPLATE/documentation.yaml deleted file mode 100644 index 712b32759ae0..000000000000 --- a/.github/ISSUE_TEMPLATE/documentation.yaml +++ /dev/null @@ -1,38 +0,0 @@ -name: Documentation problem -description: Create a report for a documentation problem. -labels: ["A-docs"] -body: - - type: markdown - attributes: - value: | - Thank you for finding a documentation problem! 📚 - - Documentation problems might be grammatical issues, typos, or unclear wording, please provide details regarding the documentation including where it is present. - - Note: If your issue is for one of these, please use their dedicated issue tracker instead: - - [The Rust Book](https://github.com/rust-lang/book/issues) - - [Rust by Example](https://github.com/rust-lang/rust-by-example/issues) - - [The Edition Guide](https://github.com/rust-lang/edition-guide/issues) - - [The Cargo Book](https://github.com/rust-lang/cargo/issues) - - [The Clippy Book](https://github.com/rust-lang/rust-clippy/issues) - - [The Reference](https://github.com/rust-lang/reference/issues) - - [The Rustonomicon](https://github.com/rust-lang/nomicon/issues) - - [The Embedded Book](https://github.com/rust-embedded/book/issues) - - All other documentation issues should be filed here. - - Or, if you find an issue related to rustdoc (e.g. doctest, rustdoc UI), please use the bug report or blank issue template instead. - - - type: textarea - id: location - attributes: - label: Location - validations: - required: true - - - type: textarea - id: summary - attributes: - label: Summary - validations: - required: true \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/ice.md b/.github/ISSUE_TEMPLATE/ice.md deleted file mode 100644 index 2afcd210a6eb..000000000000 --- a/.github/ISSUE_TEMPLATE/ice.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -name: Internal Compiler Error -about: Create a report for an internal compiler error in rustc. -labels: C-bug, I-ICE, T-compiler ---- - - -### Code - -```Rust - -``` - - -### Meta - - -`rustc --version --verbose`: -``` - -``` - -### Error output - -``` - -``` - - -
Backtrace -

- -``` - -``` - -

-
diff --git a/.github/ISSUE_TEMPLATE/ice.yaml b/.github/ISSUE_TEMPLATE/ice.yaml deleted file mode 100644 index 7bec05cc575a..000000000000 --- a/.github/ISSUE_TEMPLATE/ice.yaml +++ /dev/null @@ -1,82 +0,0 @@ -name: Internal Compiler Error (for use by automated tooling) -description: For now, you'll want to use the other ICE template, as GitHub forms have strict limits on the size of fields so backtraces cannot be pasted directly. -labels: ["C-bug", "I-ICE", "T-compiler"] -title: "[ICE]: " -body: - - type: markdown - attributes: - value: | - Thank you for finding an Internal Compiler Error! 🧊 - - If possible, try to provide a minimal verifiable example. - - You can read "[Rust Bug Minimization Patterns](http://blog.pnkfx.org/blog/2019/11/18/rust-bug-minimization-patterns/)" for how to create smaller examples. - - - type: textarea - id: code - attributes: - label: Code - description: Please provide code or a link to a repository that can reproduce the problem - placeholder: code - render: Rust - validations: - required: false - - - type: checkboxes - attributes: - label: Affected release channels - description: If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions - options: - - label: Previous Stable - required: false - - label: Current Stable - required: false - - label: Current Beta - required: false - - label: Current Nightly - required: false - - - type: textarea - id: version - attributes: - label: Rust Version - description: Please provide the `rustc` version, `rustc --version --verbose` - placeholder: | - $ rustc --version --verbose - rustc 1.XX.Y (SHORTHASH DATE) - binary: rustc - commit-hash: LONGHASHVALUE - commit-date: DATE - host: PLATFORMTRIPLE - release: 1.XX.Y - LLVM version: XX.YY.ZZ - render: Shell - validations: - required: true - - - type: textarea - id: output - attributes: - label: Current error output - description: Please provide the `rustc` output you see - placeholder: output - render: Shell - validations: - required: false - - - type: textarea - id: backtrace - attributes: - label: Backtrace - description: Include a backtrace in the code block by setting `RUST_BACKTRACE=full` in your environment, e.g. `RUST_BACKTRACE=full cargo build` - render: Shell - validations: - required: true - - - type: textarea - id: extra - attributes: - label: Anything else? - description: If you have more details you want to give us to reproduce this issue, please add it here - validations: - required: false diff --git a/.github/ISSUE_TEMPLATE/library_tracking_issue.md b/.github/ISSUE_TEMPLATE/library_tracking_issue.md deleted file mode 100644 index 934312662beb..000000000000 --- a/.github/ISSUE_TEMPLATE/library_tracking_issue.md +++ /dev/null @@ -1,85 +0,0 @@ ---- -name: Library Tracking Issue -about: A tracking issue for an unstable library feature. -title: Tracking Issue for XXX -labels: C-tracking-issue, T-libs-api ---- - - -Feature gate: `#![feature(...)]` - -This is a tracking issue for ... - - - -### Public API - - - -```rust -// core::magic - -pub struct Magic; - -impl Magic { - pub fn magic(self); -} -``` - -### Steps / History - - - -- [ ] Implementation: #... -- [ ] Final comment period (FCP)[^1] -- [ ] Stabilization PR - - - -### Unresolved Questions - - - -- None yet. - -[^1]: https://std-dev-guide.rust-lang.org/feature-lifecycle/stabilization.html diff --git a/.github/ISSUE_TEMPLATE/regression.md b/.github/ISSUE_TEMPLATE/regression.md deleted file mode 100644 index c0e90824a710..000000000000 --- a/.github/ISSUE_TEMPLATE/regression.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -name: Regression -about: Report something that unexpectedly changed between Rust versions. -labels: C-bug, regression-untriaged ---- - - -### Code - -I tried this code: - -```rust - -``` - -I expected to see this happen: *explanation* - -Instead, this happened: *explanation* - -### Version it worked on - - - -It most recently worked on: - -### Version with regression - - - -`rustc --version --verbose`: -``` - -``` - - - -### Backtrace - -
Backtrace -

- -``` - -``` - -

-
- - diff --git a/.github/ISSUE_TEMPLATE/tracking_issue.md b/.github/ISSUE_TEMPLATE/tracking_issue.md deleted file mode 100644 index 5f17f30b3b0b..000000000000 --- a/.github/ISSUE_TEMPLATE/tracking_issue.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -name: Tracking Issue -about: A tracking issue for an accepted feature or RFC in Rust. -title: Tracking Issue for XXX -labels: C-tracking-issue ---- - - -This is a tracking issue for the RFC "XXX" (rust-lang/rfcs#NNN). -The feature gate for the issue is `#![feature(FFF)]`. - -### About tracking issues - -Tracking issues are used to record the overall progress of implementation. -They are also used as hubs connecting to other relevant issues, e.g., bugs or open design questions. -A tracking issue is however *not* meant for large scale discussion, questions, or bug reports about a feature. -Instead, open a dedicated issue for the specific matter and add the relevant feature gate label. - -### Steps - - -- [ ] Implement the RFC (cc @rust-lang/XXX -- can anyone write up mentoring - instructions?) -- [ ] Adjust documentation ([see instructions on rustc-dev-guide][doc-guide]) -- [ ] Formatting for new syntax has been added to the [Style Guide] ([nightly-style-procedure]) -- [ ] Stabilization PR ([see instructions on rustc-dev-guide][stabilization-guide]) - -[stabilization-guide]: https://rustc-dev-guide.rust-lang.org/stabilization_guide.html#stabilization-pr -[doc-guide]: https://rustc-dev-guide.rust-lang.org/stabilization_guide.html#documentation-prs -[nightly-style-procedure]: https://github.com/rust-lang/style-team/blob/master/nightly-style-procedure.md -[Style Guide]: https://github.com/rust-lang/rust/tree/master/src/doc/style-guide - -### Unresolved Questions - - -XXX --- list all the "unresolved questions" found in the RFC to ensure they are -not forgotten - -### Implementation history - - diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index 8c207e7ea115..000000000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,711 +0,0 @@ -############################################################# -# WARNING: automatically generated file, DO NOT CHANGE! # -############################################################# - -# This file was automatically generated by the expand-yaml-anchors tool. The -# source file that generated this one is: -# -# src/ci/github-actions/ci.yml -# -# Once you make changes to that file you need to run: -# -# ./x.py run src/tools/expand-yaml-anchors/ -# -# The CI build will fail if the tool is not run after changes to this file. - ---- -name: CI -"on": - push: - branches: - - auto - - try - - try-perf - - automation/bors/try - - master - pull_request: - branches: - - "**" -permissions: - contents: read -defaults: - run: - shell: bash -concurrency: - group: "${{ github.workflow }}-${{ ((github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.sha) || github.ref }}" - cancel-in-progress: true -jobs: - pr: - name: "PR - ${{ matrix.name }}" - env: - PR_CI_JOB: 1 - CI_JOB_NAME: "${{ matrix.name }}" - CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse - HEAD_SHA: "${{ github.event.pull_request.head.sha || github.sha }}" - SCCACHE_BUCKET: rust-lang-ci-sccache2 - TOOLSTATE_REPO: "https://github.com/rust-lang-nursery/rust-toolstate" - CACHE_DOMAIN: ci-caches.rust-lang.org - if: "github.event_name == 'pull_request'" - continue-on-error: "${{ matrix.name == 'mingw-check-tidy' }}" - strategy: - matrix: - include: - - name: mingw-check - os: ubuntu-20.04-4core-16gb - env: {} - - name: mingw-check-tidy - os: ubuntu-20.04-4core-16gb - env: {} - - name: x86_64-gnu-llvm-15 - os: ubuntu-20.04-16core-64gb - env: {} - - name: x86_64-gnu-tools - os: ubuntu-20.04-16core-64gb - env: {} - timeout-minutes: 600 - runs-on: "${{ matrix.os }}" - steps: - - name: disable git crlf conversion - run: git config --global core.autocrlf false - - name: checkout the source code - uses: actions/checkout@v4 - with: - fetch-depth: 2 - - name: configure the PR in which the error message will be posted - run: "echo \"[CI_PR_NUMBER=$num]\"" - env: - num: "${{ github.event.number }}" - if: "success() && !env.SKIP_JOB && github.event_name == 'pull_request'" - - name: add extra environment variables - run: src/ci/scripts/setup-environment.sh - env: - EXTRA_VARIABLES: "${{ toJson(matrix.env) }}" - if: success() && !env.SKIP_JOB - - name: decide whether to skip this job - run: src/ci/scripts/should-skip-this.sh - if: success() && !env.SKIP_JOB - - name: ensure the channel matches the target branch - run: src/ci/scripts/verify-channel.sh - if: success() && !env.SKIP_JOB - - name: collect CPU statistics - run: src/ci/scripts/collect-cpu-stats.sh - if: success() && !env.SKIP_JOB - - name: show the current environment - run: src/ci/scripts/dump-environment.sh - if: success() && !env.SKIP_JOB - - name: install sccache - run: src/ci/scripts/install-sccache.sh - if: success() && !env.SKIP_JOB - - name: select Xcode - run: src/ci/scripts/select-xcode.sh - if: success() && !env.SKIP_JOB - - name: install clang - run: src/ci/scripts/install-clang.sh - if: success() && !env.SKIP_JOB - - name: install WIX - run: src/ci/scripts/install-wix.sh - if: success() && !env.SKIP_JOB - - name: disable git crlf conversion - run: src/ci/scripts/disable-git-crlf-conversion.sh - if: success() && !env.SKIP_JOB - - name: checkout submodules - run: src/ci/scripts/checkout-submodules.sh - if: success() && !env.SKIP_JOB - - name: install MSYS2 - run: src/ci/scripts/install-msys2.sh - if: success() && !env.SKIP_JOB - - name: install MinGW - run: src/ci/scripts/install-mingw.sh - if: success() && !env.SKIP_JOB - - name: install ninja - run: src/ci/scripts/install-ninja.sh - if: success() && !env.SKIP_JOB - - name: enable ipv6 on Docker - run: src/ci/scripts/enable-docker-ipv6.sh - if: success() && !env.SKIP_JOB - - name: disable git crlf conversion - run: src/ci/scripts/disable-git-crlf-conversion.sh - if: success() && !env.SKIP_JOB - - name: ensure line endings are correct - run: src/ci/scripts/verify-line-endings.sh - if: success() && !env.SKIP_JOB - - name: ensure backported commits are in upstream branches - run: src/ci/scripts/verify-backported-commits.sh - if: success() && !env.SKIP_JOB - - name: ensure the stable version number is correct - run: src/ci/scripts/verify-stable-version-number.sh - if: success() && !env.SKIP_JOB - - name: run the build - run: src/ci/scripts/run-build-from-ci.sh - env: - AWS_ACCESS_KEY_ID: "${{ env.CACHES_AWS_ACCESS_KEY_ID }}" - AWS_SECRET_ACCESS_KEY: "${{ secrets[format('AWS_SECRET_ACCESS_KEY_{0}', env.CACHES_AWS_ACCESS_KEY_ID)] }}" - TOOLSTATE_REPO_ACCESS_TOKEN: "${{ secrets.TOOLSTATE_REPO_ACCESS_TOKEN }}" - if: success() && !env.SKIP_JOB - - name: create github artifacts - run: src/ci/scripts/create-doc-artifacts.sh - if: success() && !env.SKIP_JOB - - name: upload artifacts to github - uses: actions/upload-artifact@v3 - with: - name: "${{ env.DOC_ARTIFACT_NAME }}" - path: obj/artifacts/doc - if-no-files-found: ignore - retention-days: 5 - if: success() && !env.SKIP_JOB - - name: upload artifacts to S3 - run: src/ci/scripts/upload-artifacts.sh - env: - AWS_ACCESS_KEY_ID: "${{ env.ARTIFACTS_AWS_ACCESS_KEY_ID }}" - AWS_SECRET_ACCESS_KEY: "${{ secrets[format('AWS_SECRET_ACCESS_KEY_{0}', env.ARTIFACTS_AWS_ACCESS_KEY_ID)] }}" - if: "success() && !env.SKIP_JOB && (github.event_name == 'push' || env.DEPLOY == '1' || env.DEPLOY_ALT == '1')" - auto: - name: "auto - ${{ matrix.name }}" - env: - CI_JOB_NAME: "${{ matrix.name }}" - CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse - HEAD_SHA: "${{ github.event.pull_request.head.sha || github.sha }}" - SCCACHE_BUCKET: rust-lang-ci-sccache2 - DEPLOY_BUCKET: rust-lang-ci2 - TOOLSTATE_REPO: "https://github.com/rust-lang-nursery/rust-toolstate" - TOOLSTATE_ISSUES_API_URL: "https://api.github.com/repos/rust-lang/rust/issues" - TOOLSTATE_PUBLISH: 1 - CACHES_AWS_ACCESS_KEY_ID: AKIA46X5W6CZI5DHEBFL - ARTIFACTS_AWS_ACCESS_KEY_ID: AKIA46X5W6CZN24CBO55 - AWS_REGION: us-west-1 - CACHE_DOMAIN: ci-caches.rust-lang.org - if: "github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust'" - strategy: - matrix: - include: - - name: aarch64-gnu - os: - - self-hosted - - ARM64 - - linux - - name: arm-android - os: ubuntu-20.04-8core-32gb - env: {} - - name: armhf-gnu - os: ubuntu-20.04-8core-32gb - env: {} - - name: dist-aarch64-linux - os: ubuntu-20.04-8core-32gb - env: {} - - name: dist-android - os: ubuntu-20.04-8core-32gb - env: {} - - name: dist-arm-linux - os: ubuntu-20.04-16core-64gb - env: {} - - name: dist-armhf-linux - os: ubuntu-20.04-8core-32gb - env: {} - - name: dist-armv7-linux - os: ubuntu-20.04-8core-32gb - env: {} - - name: dist-i586-gnu-i586-i686-musl - os: ubuntu-20.04-8core-32gb - env: {} - - name: dist-i686-linux - os: ubuntu-20.04-8core-32gb - env: {} - - name: dist-loongarch64-linux - os: ubuntu-20.04-8core-32gb - env: {} - - name: dist-powerpc-linux - os: ubuntu-20.04-8core-32gb - env: {} - - name: dist-powerpc64-linux - os: ubuntu-20.04-8core-32gb - env: {} - - name: dist-powerpc64le-linux - os: ubuntu-20.04-8core-32gb - env: {} - - name: dist-riscv64-linux - os: ubuntu-20.04-8core-32gb - env: {} - - name: dist-s390x-linux - os: ubuntu-20.04-8core-32gb - env: {} - - name: dist-various-1 - os: ubuntu-20.04-8core-32gb - env: {} - - name: dist-various-2 - os: ubuntu-20.04-8core-32gb - env: {} - - name: dist-x86_64-freebsd - os: ubuntu-20.04-8core-32gb - env: {} - - name: dist-x86_64-illumos - os: ubuntu-20.04-8core-32gb - env: {} - - name: dist-x86_64-linux - os: ubuntu-20.04-16core-64gb - env: {} - - name: dist-x86_64-linux-alt - env: - IMAGE: dist-x86_64-linux - os: ubuntu-20.04-16core-64gb - - name: dist-x86_64-musl - os: ubuntu-20.04-8core-32gb - env: {} - - name: dist-x86_64-netbsd - os: ubuntu-20.04-8core-32gb - env: {} - - name: i686-gnu - os: ubuntu-20.04-8core-32gb - env: {} - - name: i686-gnu-nopt - os: ubuntu-20.04-8core-32gb - env: {} - - name: mingw-check - os: ubuntu-20.04-4core-16gb - env: {} - - name: test-various - os: ubuntu-20.04-8core-32gb - env: {} - - name: x86_64-gnu - os: ubuntu-20.04-4core-16gb - env: {} - - name: x86_64-gnu-stable - env: - IMAGE: x86_64-gnu - RUST_CI_OVERRIDE_RELEASE_CHANNEL: stable - CI_ONLY_WHEN_CHANNEL: nightly - os: ubuntu-20.04-4core-16gb - - name: x86_64-gnu-aux - os: ubuntu-20.04-4core-16gb - env: {} - - name: x86_64-gnu-debug - os: ubuntu-20.04-8core-32gb - env: {} - - name: x86_64-gnu-distcheck - os: ubuntu-20.04-8core-32gb - env: {} - - name: x86_64-gnu-llvm-16 - env: - RUST_BACKTRACE: 1 - os: ubuntu-20.04-8core-32gb - - name: x86_64-gnu-llvm-15 - env: - RUST_BACKTRACE: 1 - os: ubuntu-20.04-8core-32gb - - name: x86_64-gnu-nopt - os: ubuntu-20.04-4core-16gb - env: {} - - name: x86_64-gnu-tools - env: - DEPLOY_TOOLSTATES_JSON: toolstates-linux.json - os: ubuntu-20.04-8core-32gb - - name: dist-x86_64-apple - env: - SCRIPT: "./x.py dist bootstrap --include-default-paths --host=x86_64-apple-darwin --target=x86_64-apple-darwin" - RUST_CONFIGURE_ARGS: "--enable-full-tools --enable-sanitizers --enable-profiler --set rust.jemalloc --set llvm.ninja=false --set rust.lto=thin" - RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 - MACOSX_DEPLOYMENT_TARGET: 10.12 - SELECT_XCODE: /Applications/Xcode_13.4.1.app - NO_LLVM_ASSERTIONS: 1 - NO_DEBUG_ASSERTIONS: 1 - NO_OVERFLOW_CHECKS: 1 - DIST_REQUIRE_ALL_TOOLS: 1 - os: macos-13 - - name: dist-apple-various - env: - SCRIPT: "./x.py dist bootstrap --include-default-paths --host='' --target=aarch64-apple-ios,x86_64-apple-ios,aarch64-apple-ios-sim" - RUST_CONFIGURE_ARGS: "--enable-sanitizers --enable-profiler --set rust.jemalloc --set llvm.ninja=false" - RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 - MACOSX_DEPLOYMENT_TARGET: 10.12 - SELECT_XCODE: /Applications/Xcode_13.4.1.app - NO_LLVM_ASSERTIONS: 1 - NO_DEBUG_ASSERTIONS: 1 - NO_OVERFLOW_CHECKS: 1 - os: macos-13 - - name: x86_64-apple-1 - env: - SCRIPT: "./x.py --stage 2 test --skip tests/ui --skip tests/rustdoc --skip tests/run-make-fulldeps" - RUST_CONFIGURE_ARGS: "--build=x86_64-apple-darwin --enable-sanitizers --enable-profiler --set rust.jemalloc --set llvm.ninja=false" - RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 - MACOSX_DEPLOYMENT_TARGET: 10.12 - MACOSX_STD_DEPLOYMENT_TARGET: 10.12 - NO_LLVM_ASSERTIONS: 1 - NO_DEBUG_ASSERTIONS: 1 - NO_OVERFLOW_CHECKS: 1 - os: macos-13 - - name: x86_64-apple-2 - env: - SCRIPT: "./x.py --stage 2 test tests/ui tests/rustdoc tests/run-make-fulldeps" - RUST_CONFIGURE_ARGS: "--build=x86_64-apple-darwin --enable-sanitizers --enable-profiler --set rust.jemalloc --set llvm.ninja=false" - RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 - MACOSX_DEPLOYMENT_TARGET: 10.12 - MACOSX_STD_DEPLOYMENT_TARGET: 10.12 - NO_LLVM_ASSERTIONS: 1 - NO_DEBUG_ASSERTIONS: 1 - NO_OVERFLOW_CHECKS: 1 - os: macos-13 - - name: dist-aarch64-apple - env: - SCRIPT: "./x.py dist bootstrap --include-default-paths --stage 2" - RUST_CONFIGURE_ARGS: "--build=x86_64-apple-darwin --host=aarch64-apple-darwin --target=aarch64-apple-darwin --enable-full-tools --enable-sanitizers --enable-profiler --disable-docs --set rust.jemalloc --set llvm.ninja=false" - RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 - SELECT_XCODE: /Applications/Xcode_13.4.1.app - USE_XCODE_CLANG: 1 - MACOSX_DEPLOYMENT_TARGET: 11.0 - MACOSX_STD_DEPLOYMENT_TARGET: 11.0 - NO_LLVM_ASSERTIONS: 1 - NO_DEBUG_ASSERTIONS: 1 - NO_OVERFLOW_CHECKS: 1 - DIST_REQUIRE_ALL_TOOLS: 1 - JEMALLOC_SYS_WITH_LG_PAGE: 14 - os: macos-13 - - name: x86_64-msvc - env: - RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-msvc --enable-profiler" - SCRIPT: make ci-msvc - os: windows-2019-8core-32gb - - name: i686-msvc - env: - RUST_CONFIGURE_ARGS: "--build=i686-pc-windows-msvc" - SCRIPT: make ci-msvc - os: windows-2019-8core-32gb - - name: x86_64-msvc-ext - env: - SCRIPT: python x.py --stage 2 test src/tools/cargotest src/tools/cargo && src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh x.py /tmp/toolstate/toolstates.json windows - RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-msvc --enable-lld --save-toolstates=/tmp/toolstate/toolstates.json" - DEPLOY_TOOLSTATES_JSON: toolstates-windows.json - os: windows-2019-8core-32gb - - name: i686-mingw - env: - RUST_CONFIGURE_ARGS: "--build=i686-pc-windows-gnu" - SCRIPT: make ci-mingw - NO_DOWNLOAD_CI_LLVM: 1 - CUSTOM_MINGW: 1 - os: windows-2019-8core-32gb - - name: x86_64-mingw - env: - SCRIPT: make ci-mingw - RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-gnu --enable-profiler" - NO_DOWNLOAD_CI_LLVM: 1 - CUSTOM_MINGW: 1 - os: windows-2019-8core-32gb - - name: dist-x86_64-msvc - env: - RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-msvc --host=x86_64-pc-windows-msvc --target=x86_64-pc-windows-msvc --enable-full-tools --enable-profiler" - SCRIPT: python x.py build --set rust.debug=true opt-dist && PGO_HOST=x86_64-pc-windows-msvc ./build/x86_64-pc-windows-msvc/stage0-tools-bin/opt-dist windows-ci -- python x.py dist bootstrap --include-default-paths - DIST_REQUIRE_ALL_TOOLS: 1 - os: windows-2019-8core-32gb - - name: dist-i686-msvc - env: - RUST_CONFIGURE_ARGS: "--build=i686-pc-windows-msvc --host=i686-pc-windows-msvc --target=i686-pc-windows-msvc,i586-pc-windows-msvc --enable-full-tools --enable-profiler" - SCRIPT: python x.py dist bootstrap --include-default-paths - DIST_REQUIRE_ALL_TOOLS: 1 - os: windows-2019-8core-32gb - - name: dist-aarch64-msvc - env: - RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-msvc --host=aarch64-pc-windows-msvc --enable-full-tools --enable-profiler" - SCRIPT: python x.py dist bootstrap --include-default-paths - DIST_REQUIRE_ALL_TOOLS: 1 - os: windows-2019-8core-32gb - - name: dist-i686-mingw - env: - RUST_CONFIGURE_ARGS: "--build=i686-pc-windows-gnu --enable-full-tools --enable-profiler" - NO_DOWNLOAD_CI_LLVM: 1 - SCRIPT: python x.py dist bootstrap --include-default-paths - CUSTOM_MINGW: 1 - DIST_REQUIRE_ALL_TOOLS: 1 - os: windows-2019-8core-32gb - - name: dist-x86_64-mingw - env: - SCRIPT: python x.py dist bootstrap --include-default-paths - RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-gnu --enable-full-tools --enable-profiler" - NO_DOWNLOAD_CI_LLVM: 1 - CUSTOM_MINGW: 1 - DIST_REQUIRE_ALL_TOOLS: 1 - os: windows-2019-8core-32gb - - name: dist-x86_64-msvc-alt - env: - RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-msvc --enable-extended --enable-profiler" - SCRIPT: python x.py dist bootstrap --include-default-paths - os: windows-2019-8core-32gb - timeout-minutes: 600 - runs-on: "${{ matrix.os }}" - steps: - - name: disable git crlf conversion - run: git config --global core.autocrlf false - - name: checkout the source code - uses: actions/checkout@v4 - with: - fetch-depth: 2 - - name: configure the PR in which the error message will be posted - run: "echo \"[CI_PR_NUMBER=$num]\"" - env: - num: "${{ github.event.number }}" - if: "success() && !env.SKIP_JOB && github.event_name == 'pull_request'" - - name: add extra environment variables - run: src/ci/scripts/setup-environment.sh - env: - EXTRA_VARIABLES: "${{ toJson(matrix.env) }}" - if: success() && !env.SKIP_JOB - - name: decide whether to skip this job - run: src/ci/scripts/should-skip-this.sh - if: success() && !env.SKIP_JOB - - name: ensure the channel matches the target branch - run: src/ci/scripts/verify-channel.sh - if: success() && !env.SKIP_JOB - - name: collect CPU statistics - run: src/ci/scripts/collect-cpu-stats.sh - if: success() && !env.SKIP_JOB - - name: show the current environment - run: src/ci/scripts/dump-environment.sh - if: success() && !env.SKIP_JOB - - name: install sccache - run: src/ci/scripts/install-sccache.sh - if: success() && !env.SKIP_JOB - - name: select Xcode - run: src/ci/scripts/select-xcode.sh - if: success() && !env.SKIP_JOB - - name: install clang - run: src/ci/scripts/install-clang.sh - if: success() && !env.SKIP_JOB - - name: install WIX - run: src/ci/scripts/install-wix.sh - if: success() && !env.SKIP_JOB - - name: disable git crlf conversion - run: src/ci/scripts/disable-git-crlf-conversion.sh - if: success() && !env.SKIP_JOB - - name: checkout submodules - run: src/ci/scripts/checkout-submodules.sh - if: success() && !env.SKIP_JOB - - name: install MSYS2 - run: src/ci/scripts/install-msys2.sh - if: success() && !env.SKIP_JOB - - name: install MinGW - run: src/ci/scripts/install-mingw.sh - if: success() && !env.SKIP_JOB - - name: install ninja - run: src/ci/scripts/install-ninja.sh - if: success() && !env.SKIP_JOB - - name: enable ipv6 on Docker - run: src/ci/scripts/enable-docker-ipv6.sh - if: success() && !env.SKIP_JOB - - name: disable git crlf conversion - run: src/ci/scripts/disable-git-crlf-conversion.sh - if: success() && !env.SKIP_JOB - - name: ensure line endings are correct - run: src/ci/scripts/verify-line-endings.sh - if: success() && !env.SKIP_JOB - - name: ensure backported commits are in upstream branches - run: src/ci/scripts/verify-backported-commits.sh - if: success() && !env.SKIP_JOB - - name: ensure the stable version number is correct - run: src/ci/scripts/verify-stable-version-number.sh - if: success() && !env.SKIP_JOB - - name: run the build - run: src/ci/scripts/run-build-from-ci.sh - env: - AWS_ACCESS_KEY_ID: "${{ env.CACHES_AWS_ACCESS_KEY_ID }}" - AWS_SECRET_ACCESS_KEY: "${{ secrets[format('AWS_SECRET_ACCESS_KEY_{0}', env.CACHES_AWS_ACCESS_KEY_ID)] }}" - TOOLSTATE_REPO_ACCESS_TOKEN: "${{ secrets.TOOLSTATE_REPO_ACCESS_TOKEN }}" - if: success() && !env.SKIP_JOB - - name: create github artifacts - run: src/ci/scripts/create-doc-artifacts.sh - if: success() && !env.SKIP_JOB - - name: upload artifacts to github - uses: actions/upload-artifact@v3 - with: - name: "${{ env.DOC_ARTIFACT_NAME }}" - path: obj/artifacts/doc - if-no-files-found: ignore - retention-days: 5 - if: success() && !env.SKIP_JOB - - name: upload artifacts to S3 - run: src/ci/scripts/upload-artifacts.sh - env: - AWS_ACCESS_KEY_ID: "${{ env.ARTIFACTS_AWS_ACCESS_KEY_ID }}" - AWS_SECRET_ACCESS_KEY: "${{ secrets[format('AWS_SECRET_ACCESS_KEY_{0}', env.ARTIFACTS_AWS_ACCESS_KEY_ID)] }}" - if: "success() && !env.SKIP_JOB && (github.event_name == 'push' || env.DEPLOY == '1' || env.DEPLOY_ALT == '1')" - try: - name: "try - ${{ matrix.name }}" - env: - DIST_TRY_BUILD: 1 - CI_JOB_NAME: "${{ matrix.name }}" - CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse - HEAD_SHA: "${{ github.event.pull_request.head.sha || github.sha }}" - SCCACHE_BUCKET: rust-lang-ci-sccache2 - DEPLOY_BUCKET: rust-lang-ci2 - TOOLSTATE_REPO: "https://github.com/rust-lang-nursery/rust-toolstate" - TOOLSTATE_ISSUES_API_URL: "https://api.github.com/repos/rust-lang/rust/issues" - TOOLSTATE_PUBLISH: 1 - CACHES_AWS_ACCESS_KEY_ID: AKIA46X5W6CZI5DHEBFL - ARTIFACTS_AWS_ACCESS_KEY_ID: AKIA46X5W6CZN24CBO55 - AWS_REGION: us-west-1 - CACHE_DOMAIN: ci-caches.rust-lang.org - if: "github.event_name == 'push' && (((github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.repository == 'rust-lang-ci/rust') || ((github.ref == 'refs/heads/automation/bors/try') && github.repository == 'rust-lang/rust'))" - strategy: - matrix: - include: - - name: dist-x86_64-linux - os: ubuntu-20.04-16core-64gb - env: {} - timeout-minutes: 600 - runs-on: "${{ matrix.os }}" - steps: - - name: disable git crlf conversion - run: git config --global core.autocrlf false - - name: checkout the source code - uses: actions/checkout@v4 - with: - fetch-depth: 2 - - name: configure the PR in which the error message will be posted - run: "echo \"[CI_PR_NUMBER=$num]\"" - env: - num: "${{ github.event.number }}" - if: "success() && !env.SKIP_JOB && github.event_name == 'pull_request'" - - name: add extra environment variables - run: src/ci/scripts/setup-environment.sh - env: - EXTRA_VARIABLES: "${{ toJson(matrix.env) }}" - if: success() && !env.SKIP_JOB - - name: decide whether to skip this job - run: src/ci/scripts/should-skip-this.sh - if: success() && !env.SKIP_JOB - - name: ensure the channel matches the target branch - run: src/ci/scripts/verify-channel.sh - if: success() && !env.SKIP_JOB - - name: collect CPU statistics - run: src/ci/scripts/collect-cpu-stats.sh - if: success() && !env.SKIP_JOB - - name: show the current environment - run: src/ci/scripts/dump-environment.sh - if: success() && !env.SKIP_JOB - - name: install sccache - run: src/ci/scripts/install-sccache.sh - if: success() && !env.SKIP_JOB - - name: select Xcode - run: src/ci/scripts/select-xcode.sh - if: success() && !env.SKIP_JOB - - name: install clang - run: src/ci/scripts/install-clang.sh - if: success() && !env.SKIP_JOB - - name: install WIX - run: src/ci/scripts/install-wix.sh - if: success() && !env.SKIP_JOB - - name: disable git crlf conversion - run: src/ci/scripts/disable-git-crlf-conversion.sh - if: success() && !env.SKIP_JOB - - name: checkout submodules - run: src/ci/scripts/checkout-submodules.sh - if: success() && !env.SKIP_JOB - - name: install MSYS2 - run: src/ci/scripts/install-msys2.sh - if: success() && !env.SKIP_JOB - - name: install MinGW - run: src/ci/scripts/install-mingw.sh - if: success() && !env.SKIP_JOB - - name: install ninja - run: src/ci/scripts/install-ninja.sh - if: success() && !env.SKIP_JOB - - name: enable ipv6 on Docker - run: src/ci/scripts/enable-docker-ipv6.sh - if: success() && !env.SKIP_JOB - - name: disable git crlf conversion - run: src/ci/scripts/disable-git-crlf-conversion.sh - if: success() && !env.SKIP_JOB - - name: ensure line endings are correct - run: src/ci/scripts/verify-line-endings.sh - if: success() && !env.SKIP_JOB - - name: ensure backported commits are in upstream branches - run: src/ci/scripts/verify-backported-commits.sh - if: success() && !env.SKIP_JOB - - name: ensure the stable version number is correct - run: src/ci/scripts/verify-stable-version-number.sh - if: success() && !env.SKIP_JOB - - name: run the build - run: src/ci/scripts/run-build-from-ci.sh - env: - AWS_ACCESS_KEY_ID: "${{ env.CACHES_AWS_ACCESS_KEY_ID }}" - AWS_SECRET_ACCESS_KEY: "${{ secrets[format('AWS_SECRET_ACCESS_KEY_{0}', env.CACHES_AWS_ACCESS_KEY_ID)] }}" - TOOLSTATE_REPO_ACCESS_TOKEN: "${{ secrets.TOOLSTATE_REPO_ACCESS_TOKEN }}" - if: success() && !env.SKIP_JOB - - name: create github artifacts - run: src/ci/scripts/create-doc-artifacts.sh - if: success() && !env.SKIP_JOB - - name: upload artifacts to github - uses: actions/upload-artifact@v3 - with: - name: "${{ env.DOC_ARTIFACT_NAME }}" - path: obj/artifacts/doc - if-no-files-found: ignore - retention-days: 5 - if: success() && !env.SKIP_JOB - - name: upload artifacts to S3 - run: src/ci/scripts/upload-artifacts.sh - env: - AWS_ACCESS_KEY_ID: "${{ env.ARTIFACTS_AWS_ACCESS_KEY_ID }}" - AWS_SECRET_ACCESS_KEY: "${{ secrets[format('AWS_SECRET_ACCESS_KEY_{0}', env.ARTIFACTS_AWS_ACCESS_KEY_ID)] }}" - if: "success() && !env.SKIP_JOB && (github.event_name == 'push' || env.DEPLOY == '1' || env.DEPLOY_ALT == '1')" - master: - name: master - runs-on: ubuntu-latest - env: - SCCACHE_BUCKET: rust-lang-ci-sccache2 - DEPLOY_BUCKET: rust-lang-ci2 - TOOLSTATE_REPO: "https://github.com/rust-lang-nursery/rust-toolstate" - TOOLSTATE_ISSUES_API_URL: "https://api.github.com/repos/rust-lang/rust/issues" - TOOLSTATE_PUBLISH: 1 - CACHES_AWS_ACCESS_KEY_ID: AKIA46X5W6CZI5DHEBFL - ARTIFACTS_AWS_ACCESS_KEY_ID: AKIA46X5W6CZN24CBO55 - AWS_REGION: us-west-1 - CACHE_DOMAIN: ci-caches.rust-lang.org - if: "github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'rust-lang-ci/rust'" - steps: - - name: checkout the source code - uses: actions/checkout@v4 - with: - fetch-depth: 2 - - name: publish toolstate - run: src/ci/publish_toolstate.sh - shell: bash - env: - TOOLSTATE_REPO_ACCESS_TOKEN: "${{ secrets.TOOLSTATE_REPO_ACCESS_TOKEN }}" - if: success() && !env.SKIP_JOB - try-success: - needs: - - try - if: "success() && github.event_name == 'push' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.repository == 'rust-lang-ci/rust'" - steps: - - name: mark the job as a success - run: exit 0 - shell: bash - name: bors build finished - runs-on: ubuntu-latest - try-failure: - needs: - - try - if: "!success() && github.event_name == 'push' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.repository == 'rust-lang-ci/rust'" - steps: - - name: mark the job as a failure - run: exit 1 - shell: bash - name: bors build finished - runs-on: ubuntu-latest - auto-success: - needs: - - auto - if: "success() && github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust'" - steps: - - name: mark the job as a success - run: exit 0 - shell: bash - name: bors build finished - runs-on: ubuntu-latest - auto-failure: - needs: - - auto - if: "!success() && github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust'" - steps: - - name: mark the job as a failure - run: exit 1 - shell: bash - name: bors build finished - runs-on: ubuntu-latest diff --git a/.github/workflows/dependencies.yml b/.github/workflows/dependencies.yml deleted file mode 100644 index 97ed891c491d..000000000000 --- a/.github/workflows/dependencies.yml +++ /dev/null @@ -1,142 +0,0 @@ -# Automatically run `cargo update` periodically - ---- -name: Bump dependencies in Cargo.lock -on: - schedule: - # Run weekly - - cron: '0 0 * * Sun' - workflow_dispatch: - # Needed so we can run it manually -permissions: - contents: read -defaults: - run: - shell: bash -env: - # So cargo doesn't complain about unstable features - RUSTC_BOOTSTRAP: 1 - PR_TITLE: Weekly `cargo update` - PR_MESSAGE: | - Automation to keep dependencies in `Cargo.lock` current. - - The following is the output from `cargo update`: - COMMIT_MESSAGE: "cargo update \n\n" - -jobs: - not-waiting-on-bors: - if: github.repository_owner == 'rust-lang' - name: skip if S-waiting-on-bors - runs-on: ubuntu-latest - steps: - - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - # Fetch state and labels of PR - # Or exit successfully if PR does not exist - JSON=$(gh pr view cargo_update --repo $GITHUB_REPOSITORY --json labels,state || exit 0) - STATE=$(echo "$JSON" | jq -r '.state') - WAITING_ON_BORS=$(echo "$JSON" | jq '.labels[] | any(.name == "S-waiting-on-bors"; .)') - - # Exit with error if open and S-waiting-on-bors - if [[ "$STATE" == "OPEN" && "$WAITING_ON_BORS" == "true" ]]; then - exit 1 - fi - - update: - if: github.repository_owner == 'rust-lang' - name: update dependencies - needs: not-waiting-on-bors - runs-on: ubuntu-latest - steps: - - name: checkout the source code - uses: actions/checkout@v4 - with: - submodules: recursive - - name: install the bootstrap toolchain - run: | - # Extract the stage0 version - TOOLCHAIN=$(jq -r '.compiler | {version,date} | join("-")' -- src/stage0.json) - # Install and set as default - rustup toolchain install --no-self-update --profile minimal $TOOLCHAIN - rustup default $TOOLCHAIN - - - name: cargo update - # Remove first line that always just says "Updating crates.io index" - run: cargo update 2>&1 | sed '/crates.io index/d' | tee -a cargo_update.log - - name: upload Cargo.lock artifact for use in PR - uses: actions/upload-artifact@v3 - with: - name: Cargo-lock - path: Cargo.lock - retention-days: 1 - - name: upload cargo-update log artifact for use in PR - uses: actions/upload-artifact@v3 - with: - name: cargo-updates - path: cargo_update.log - retention-days: 1 - - pr: - if: github.repository_owner == 'rust-lang' - name: amend PR - needs: update - runs-on: ubuntu-latest - permissions: - contents: write - pull-requests: write - steps: - - name: checkout the source code - uses: actions/checkout@v4 - - - name: download Cargo.lock from update job - uses: actions/download-artifact@v3 - with: - name: Cargo-lock - - name: download cargo-update log from update job - uses: actions/download-artifact@v3 - with: - name: cargo-updates - - - name: craft PR body and commit message - run: | - echo "${COMMIT_MESSAGE}" > commit.txt - cat cargo_update.log >> commit.txt - - echo "${PR_MESSAGE}" > body.md - echo '```txt' >> body.md - cat cargo_update.log >> body.md - echo '```' >> body.md - - - name: commit - run: | - git config user.name github-actions - git config user.email github-actions@github.com - git switch --force-create cargo_update - git add ./Cargo.lock - git commit --no-verify --file=commit.txt - - - name: push - run: git push --no-verify --force --set-upstream origin cargo_update - - - name: edit existing open pull request - id: edit - # Don't fail job if we need to open new PR - continue-on-error: true - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - # Exit with error if PR is closed - STATE=$(gh pr view cargo_update --repo $GITHUB_REPOSITORY --json state --jq '.state') - if [[ "$STATE" != "OPEN" ]]; then - exit 1 - fi - - gh pr edit cargo_update --title "${PR_TITLE}" --body-file body.md --repo $GITHUB_REPOSITORY - - - name: open new pull request - # Only run if there wasn't an existing PR - if: steps.edit.outcome != 'success' - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: gh pr create --title "${PR_TITLE}" --body-file body.md --repo $GITHUB_REPOSITORY diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md deleted file mode 100644 index e3708bc48539..000000000000 --- a/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,3 +0,0 @@ -# The Rust Code of Conduct - -The Code of Conduct for this repository [can be found online](https://www.rust-lang.org/conduct.html). diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index dfaa70bb9db0..000000000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,42 +0,0 @@ -# Contributing to Rust - -Thank you for your interest in contributing to Rust! There are many ways to contribute -and we appreciate all of them. - -The best way to get started is by asking for help in the [#new -members](https://rust-lang.zulipchat.com/#narrow/stream/122652-new-members) -Zulip stream. We have lots of docs below of how to get started on your own, but -the Zulip stream is the best place to *ask* for help. - -Documentation for contributing to the compiler or tooling is located in the [Guide to Rustc -Development][rustc-dev-guide], commonly known as the [rustc-dev-guide]. Documentation for the -standard library in the [Standard library developers Guide][std-dev-guide], commonly known as the [std-dev-guide]. - -## About the [rustc-dev-guide] - -The [rustc-dev-guide] is meant to help document how rustc –the Rust compiler– works, -as well as to help new contributors get involved in rustc development. It is recommend -to read and understand the [rustc-dev-guide] before making a contribution. This guide -talks about the different bots in the Rust ecosystem, the Rust development tools, -bootstrapping, the compiler architecture, source code representation, and more. - -## [Getting help](https://rustc-dev-guide.rust-lang.org/getting-started.html#asking-questions) - -There are many ways you can get help when you're stuck. Rust has many platforms for this: -[internals], [rust-zulip], and [rust-discord]. It is recommended to ask for help on -the [rust-zulip], but any of these platforms are a great way to seek help and even -find a mentor! You can learn more about asking questions and getting help in the -[Asking Questions](https://rustc-dev-guide.rust-lang.org/getting-started.html#asking-questions) chapter of the [rustc-dev-guide]. - -## Bug reports - -Did a compiler error message tell you to come here? If you want to create an ICE report, -refer to [this section][contributing-bug-reports] and [open an issue][issue template]. - -[rustc-dev-guide]: https://rustc-dev-guide.rust-lang.org/ -[std-dev-guide]: https://std-dev-guide.rust-lang.org/ -[contributing-bug-reports]: https://rustc-dev-guide.rust-lang.org/contributing.html#bug-reports -[issue template]: https://github.com/rust-lang/rust/issues/new/choose -[internals]: https://internals.rust-lang.org -[rust-discord]: http://discord.gg/rust-lang -[rust-zulip]: https://rust-lang.zulipchat.com diff --git a/README.md b/README.md deleted file mode 100644 index f0c45f341d81..000000000000 --- a/README.md +++ /dev/null @@ -1,301 +0,0 @@ -# The Rust Programming Language - -[![Rust Community](https://img.shields.io/badge/Rust_Community%20-Join_us-brightgreen?style=plastic&logo=rust)](https://www.rust-lang.org/community) - -This is the main source code repository for [Rust]. It contains the compiler, -standard library, and documentation. - -[Rust]: https://www.rust-lang.org/ - -**Note: this README is for _users_ rather than _contributors_.** -If you wish to _contribute_ to the compiler, you should read -[CONTRIBUTING.md](CONTRIBUTING.md) instead. - -## Quick Start - -Read ["Installation"] from [The Book]. - -["Installation"]: https://doc.rust-lang.org/book/ch01-01-installation.html -[The Book]: https://doc.rust-lang.org/book/index.html - -## Installing from Source - -The Rust build system uses a Python script called `x.py` to build the compiler, -which manages the bootstrapping process. It lives at the root of the project. -It also uses a file named `config.toml` to determine various configuration -settings for the build. You can see a full list of options in -`config.example.toml`. - -The `x.py` command can be run directly on most Unix systems in the following -format: - -```sh -./x.py [flags] -``` - -This is how the documentation and examples assume you are running `x.py`. -See the [rustc dev guide][rustcguidebuild] if this does not work on your -platform. - -More information about `x.py` can be found by running it with the `--help` flag -or reading the [rustc dev guide][rustcguidebuild]. - -[gettingstarted]: https://rustc-dev-guide.rust-lang.org/getting-started.html -[rustcguidebuild]: https://rustc-dev-guide.rust-lang.org/building/how-to-build-and-run.html#what-is-xpy - -### Dependencies - -Make sure you have installed the dependencies: - -* `python` 3 or 2.7 -* `git` -* A C compiler (when building for the host, `cc` is enough; cross-compiling may - need additional compilers) -* `curl` (not needed on Windows) -* `pkg-config` if you are compiling on Linux and targeting Linux -* `libiconv` (already included with glibc on Debian-based distros) - -To build Cargo, you'll also need OpenSSL (`libssl-dev` or `openssl-devel` on -most Unix distros). - -If building LLVM from source, you'll need additional tools: - -* `g++`, `clang++`, or MSVC with versions listed on - [LLVM's documentation](https://llvm.org/docs/GettingStarted.html#host-c-toolchain-both-compiler-and-standard-library) -* `ninja`, or GNU `make` 3.81 or later (Ninja is recommended, especially on - Windows) -* `cmake` 3.13.4 or later -* `libstdc++-static` may be required on some Linux distributions such as Fedora - and Ubuntu - -On tier 1 or tier 2 with host tools platforms, you can also choose to download -LLVM by setting `llvm.download-ci-llvm = true`. -Otherwise, you'll need LLVM installed and `llvm-config` in your path. -See [the rustc-dev-guide for more info][sysllvm]. - -[sysllvm]: https://rustc-dev-guide.rust-lang.org/building/new-target.html#using-pre-built-llvm - - -### Building on a Unix-like system - -#### Build steps - -1. Clone the [source] with `git`: - - ```sh - git clone https://github.com/rust-lang/rust.git - cd rust - ``` - -[source]: https://github.com/rust-lang/rust - -2. Configure the build settings: - - ```sh - ./configure - ``` - - If you plan to use `x.py install` to create an installation, it is - recommended that you set the `prefix` value in the `[install]` section to a - directory: `./configure --set install.prefix=` - -3. Build and install: - - ```sh - ./x.py build && ./x.py install - ``` - - When complete, `./x.py install` will place several programs into - `$PREFIX/bin`: `rustc`, the Rust compiler, and `rustdoc`, the - API-documentation tool. By default, it will also include [Cargo], Rust's - package manager. You can disable this behavior by passing - `--set build.extended=false` to `./configure`. - -[Cargo]: https://github.com/rust-lang/cargo - -#### Configure and Make - -This project provides a configure script and makefile (the latter of which just -invokes `x.py`). `./configure` is the recommended way to programmatically -generate a `config.toml`. `make` is not recommended (we suggest using `x.py` -directly), but it is supported and we try not to break it unnecessarily. - -```sh -./configure -make && sudo make install -``` - -`configure` generates a `config.toml` which can also be used with normal `x.py` -invocations. - -### Building on Windows - -On Windows, we suggest using [winget] to install dependencies by running the -following in a terminal: - -```powershell -winget install -e Python.Python.3 -winget install -e Kitware.CMake -winget install -e Git.Git -``` - -Then edit your system's `PATH` variable and add: `C:\Program Files\CMake\bin`. -See -[this guide on editing the system `PATH`](https://www.java.com/en/download/help/path.html) -from the Java documentation. - -[winget]: https://github.com/microsoft/winget-cli - -There are two prominent ABIs in use on Windows: the native (MSVC) ABI used by -Visual Studio and the GNU ABI used by the GCC toolchain. Which version of Rust -you need depends largely on what C/C++ libraries you want to interoperate with. -Use the MSVC build of Rust to interop with software produced by Visual Studio -and the GNU build to interop with GNU software built using the MinGW/MSYS2 -toolchain. - -#### MinGW - -[MSYS2][msys2] can be used to easily build Rust on Windows: - -[msys2]: https://www.msys2.org/ - -1. Download the latest [MSYS2 installer][msys2] and go through the installer. - -2. Run `mingw32_shell.bat` or `mingw64_shell.bat` from the MSYS2 installation - directory (e.g. `C:\msys64`), depending on whether you want 32-bit or 64-bit - Rust. (As of the latest version of MSYS2 you have to run `msys2_shell.cmd - -mingw32` or `msys2_shell.cmd -mingw64` from the command line instead.) - -3. From this terminal, install the required tools: - - ```sh - # Update package mirrors (may be needed if you have a fresh install of MSYS2) - pacman -Sy pacman-mirrors - - # Install build tools needed for Rust. If you're building a 32-bit compiler, - # then replace "x86_64" below with "i686". If you've already got Git, Python, - # or CMake installed and in PATH you can remove them from this list. - # Note that it is important that you do **not** use the 'python2', 'cmake', - # and 'ninja' packages from the 'msys2' subsystem. - # The build has historically been known to fail with these packages. - pacman -S git \ - make \ - diffutils \ - tar \ - mingw-w64-x86_64-python \ - mingw-w64-x86_64-cmake \ - mingw-w64-x86_64-gcc \ - mingw-w64-x86_64-ninja - ``` - -4. Navigate to Rust's source code (or clone it), then build it: - - ```sh - python x.py setup user && python x.py build && python x.py install - ``` - -#### MSVC - -MSVC builds of Rust additionally require an installation of Visual Studio 2017 -(or later) so `rustc` can use its linker. The simplest way is to get -[Visual Studio], check the "C++ build tools" and "Windows 10 SDK" workload. - -[Visual Studio]: https://visualstudio.microsoft.com/downloads/ - -(If you're installing CMake yourself, be careful that "C++ CMake tools for -Windows" doesn't get included under "Individual components".) - -With these dependencies installed, you can build the compiler in a `cmd.exe` -shell with: - -```sh -python x.py setup user -python x.py build -``` - -Right now, building Rust only works with some known versions of Visual Studio. -If you have a more recent version installed and the build system doesn't -understand, you may need to force rustbuild to use an older version. -This can be done by manually calling the appropriate vcvars file before running -the bootstrap. - -```batch -CALL "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat" -python x.py build -``` - -#### Specifying an ABI - -Each specific ABI can also be used from either environment (for example, using -the GNU ABI in PowerShell) by using an explicit build triple. The available -Windows build triples are: -- GNU ABI (using GCC) - - `i686-pc-windows-gnu` - - `x86_64-pc-windows-gnu` -- The MSVC ABI - - `i686-pc-windows-msvc` - - `x86_64-pc-windows-msvc` - -The build triple can be specified by either specifying `--build=` when -invoking `x.py` commands, or by creating a `config.toml` file (as described in -[Building on a Unix-like system](#building-on-a-unix-like-system)), and passing -`--set build.build=` to `./configure`. - -## Building Documentation - -If you'd like to build the documentation, it's almost the same: - -```sh -./x.py doc -``` - -The generated documentation will appear under `doc` in the `build` directory for -the ABI used. That is, if the ABI was `x86_64-pc-windows-msvc`, the directory -will be `build\x86_64-pc-windows-msvc\doc`. - -## Notes - -Since the Rust compiler is written in Rust, it must be built by a precompiled -"snapshot" version of itself (made in an earlier stage of development). -As such, source builds require an Internet connection to fetch snapshots, and an -OS that can execute the available snapshot binaries. - -See https://doc.rust-lang.org/nightly/rustc/platform-support.html for a list of -supported platforms. -Only "host tools" platforms have a pre-compiled snapshot binary available; to -compile for a platform without host tools you must cross-compile. - -You may find that other platforms work, but these are our officially supported -build environments that are most likely to work. - -## Getting Help - -See https://www.rust-lang.org/community for a list of chat platforms and forums. - -## Contributing - -See [CONTRIBUTING.md](CONTRIBUTING.md). - -## License - -Rust is primarily distributed under the terms of both the MIT license and the -Apache License (Version 2.0), with portions covered by various BSD-like -licenses. - -See [LICENSE-APACHE](LICENSE-APACHE), [LICENSE-MIT](LICENSE-MIT), and -[COPYRIGHT](COPYRIGHT) for details. - -## Trademark - -[The Rust Foundation][rust-foundation] owns and protects the Rust and Cargo -trademarks and logos (the "Rust Trademarks"). - -If you want to use these names or brands, please read the -[media guide][media-guide]. - -Third-party logos may be subject to third-party copyrights and trademarks. See -[Licenses][policies-licenses] for details. - -[rust-foundation]: https://foundation.rust-lang.org/ -[media-guide]: https://foundation.rust-lang.org/policies/logo-policy-and-media-guide/ -[policies-licenses]: https://www.rust-lang.org/policies/licenses diff --git a/compiler/rustc_codegen_cranelift/.github/actions/github-release/README.md b/compiler/rustc_codegen_cranelift/.github/actions/github-release/README.md deleted file mode 100644 index c70ba8f49538..000000000000 --- a/compiler/rustc_codegen_cranelift/.github/actions/github-release/README.md +++ /dev/null @@ -1,18 +0,0 @@ -# github-release - -An action used to publish GitHub releases for `wasmtime`. - -As of the time of this writing there's a few actions floating around which -perform github releases but they all tend to have their set of drawbacks. -Additionally nothing handles deleting releases which we need for our rolling -`dev` release. - -To handle all this this action rolls-its-own implementation using the -actions/toolkit repository and packages published there. These run in a Docker -container and take various inputs to orchestrate the release from the build. - -More comments can be found in `main.js`. - -Testing this is really hard. If you want to try though run `npm install` and -then `node main.js`. You'll have to configure a bunch of env vars though to get -anything reasonably working. diff --git a/compiler/rustc_codegen_cranelift/.github/actions/github-release/action.yml b/compiler/rustc_codegen_cranelift/.github/actions/github-release/action.yml deleted file mode 100644 index 36e5209f50c3..000000000000 --- a/compiler/rustc_codegen_cranelift/.github/actions/github-release/action.yml +++ /dev/null @@ -1,13 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -name: 'rustc_codegen_cranelift github releases' -description: 'rustc_codegen_cranelift github releases' -inputs: - token: - description: '' - required: true - files: - description: '' - required: true -runs: - using: 'node16' - main: 'main.js' diff --git a/compiler/rustc_codegen_cranelift/.github/actions/github-release/main.js b/compiler/rustc_codegen_cranelift/.github/actions/github-release/main.js deleted file mode 100644 index 6fcfca34ea77..000000000000 --- a/compiler/rustc_codegen_cranelift/.github/actions/github-release/main.js +++ /dev/null @@ -1,162 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -const core = require('@actions/core'); -const path = require("path"); -const fs = require("fs"); -const github = require('@actions/github'); -const glob = require('glob'); - -function sleep(milliseconds) { - return new Promise(resolve => setTimeout(resolve, milliseconds)) -} - -async function runOnce() { - // Load all our inputs and env vars. Note that `getInput` reads from `INPUT_*` - const files = core.getInput('files'); - const token = core.getInput('token'); - const slug = process.env.GITHUB_REPOSITORY; - const owner = slug.split('/')[0]; - const repo = slug.split('/')[1]; - const sha = process.env.GITHUB_SHA; - let name = 'dev'; - if (process.env.GITHUB_REF.startsWith('refs/tags/v')) { - name = process.env.GITHUB_REF.substring(10); - } - - core.info(`files: ${files}`); - core.info(`name: ${name}`); - core.info(`token: ${token}`); - - const octokit = github.getOctokit(token); - - // For the `dev` release we may need to update the tag to point to the new - // commit on this branch. All other names should already have tags associated - // with them. - if (name == 'dev') { - let tag = null; - try { - tag = await octokit.request("GET /repos/:owner/:repo/git/refs/tags/:name", { owner, repo, name }); - core.info(`found existing tag`); - console.log("tag: ", JSON.stringify(tag.data, null, 2)); - } catch (e) { - // ignore if this tag doesn't exist - core.info(`no existing tag found`); - } - - if (tag === null || tag.data.object.sha !== sha) { - core.info(`updating existing tag or creating new one`); - - try { - core.info(`updating dev tag`); - await octokit.rest.git.updateRef({ - owner, - repo, - ref: 'tags/dev', - sha, - force: true, - }); - } catch (e) { - console.log("ERROR: ", JSON.stringify(e.data, null, 2)); - core.info(`creating dev tag`); - try { - await octokit.rest.git.createRef({ - owner, - repo, - ref: 'refs/tags/dev', - sha, - }); - } catch (e) { - // we might race with others, so assume someone else has created the - // tag by this point. - console.log("failed to create tag: ", JSON.stringify(e.data, null, 2)); - } - } - - console.log("double-checking tag is correct"); - tag = await octokit.request("GET /repos/:owner/:repo/git/refs/tags/:name", { owner, repo, name }); - if (tag.data.object.sha !== sha) { - console.log("tag: ", JSON.stringify(tag.data, null, 2)); - throw new Error("tag didn't work"); - } - } else { - core.info(`existing tag works`); - } - } - - // Delete a previous release - try { - core.info(`fetching release`); - let release = await octokit.rest.repos.getReleaseByTag({ owner, repo, tag: name }); - console.log("found release: ", JSON.stringify(release.data, null, 2)); - await octokit.rest.repos.deleteRelease({ - owner, - repo, - release_id: release.data.id, - }); - console.log("deleted release"); - } catch (e) { - console.log("ERROR: ", JSON.stringify(e, null, 2)); - } - - console.log("creating a release"); - let release = await octokit.rest.repos.createRelease({ - owner, - repo, - tag_name: name, - prerelease: name === 'dev', - }); - - // Delete all assets from a previous run - for (const asset of release.data.assets) { - console.log(`deleting prior asset ${asset.id}`); - await octokit.rest.repos.deleteReleaseAsset({ - owner, - repo, - asset_id: asset.id, - }); - } - - // Upload all the relevant assets for this release as just general blobs. - for (const file of glob.sync(files)) { - const size = fs.statSync(file).size; - const name = path.basename(file); - core.info(`upload ${file}`); - await octokit.rest.repos.uploadReleaseAsset({ - data: fs.createReadStream(file), - headers: { 'content-length': size, 'content-type': 'application/octet-stream' }, - name, - url: release.data.upload_url, - }); - } -} - -async function run() { - const retries = 10; - for (let i = 0; i < retries; i++) { - try { - await runOnce(); - break; - } catch (e) { - if (i === retries - 1) - throw e; - logError(e); - console.log("RETRYING after 10s"); - await sleep(10000) - } - } -} - -function logError(e) { - console.log("ERROR: ", e.message); - try { - console.log(JSON.stringify(e, null, 2)); - } catch (e) { - // ignore json errors for now - } - console.log(e.stack); -} - -run().catch(err => { - logError(err); - core.setFailed(err.message); -}); diff --git a/compiler/rustc_codegen_cranelift/.github/actions/github-release/package-lock.json b/compiler/rustc_codegen_cranelift/.github/actions/github-release/package-lock.json deleted file mode 100644 index dd3b2a048f09..000000000000 --- a/compiler/rustc_codegen_cranelift/.github/actions/github-release/package-lock.json +++ /dev/null @@ -1,571 +0,0 @@ -{ - "name": "rustc_codegen_cranelift-github-release", - "version": "0.0.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "rustc_codegen_cranelift-github-release", - "version": "0.0.0", - "dependencies": { - "@actions/core": "^1.9.1", - "@actions/github": "^5.1.0", - "glob": "^7.1.5" - } - }, - "node_modules/@actions/core": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.9.1.tgz", - "integrity": "sha512-5ad+U2YGrmmiw6du20AQW5XuWo7UKN2052FjSV7MX+Wfjf8sCqcsZe62NfgHys4QI4/Y+vQvLKYL8jWtA1ZBTA==", - "dependencies": { - "@actions/http-client": "^2.0.1", - "uuid": "^8.3.2" - } - }, - "node_modules/@actions/github": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@actions/github/-/github-5.1.0.tgz", - "integrity": "sha512-tuI80F7JQIhg77ZTTgUAPpVD7ZnP9oHSPN8xw7LOwtA4vEMbAjWJNbmLBfV7xua7r016GyjzWLuec5cs8f/a8A==", - "dependencies": { - "@actions/http-client": "^2.0.1", - "@octokit/core": "^3.6.0", - "@octokit/plugin-paginate-rest": "^2.17.0", - "@octokit/plugin-rest-endpoint-methods": "^5.13.0" - } - }, - "node_modules/@actions/http-client": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz", - "integrity": "sha512-PIXiMVtz6VvyaRsGY268qvj57hXQEpsYogYOu2nrQhlf+XCGmZstmuZBbAybUl1nQGnvS1k1eEsQ69ZoD7xlSw==", - "dependencies": { - "tunnel": "^0.0.6" - } - }, - "node_modules/@octokit/auth-token": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz", - "integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==", - "dependencies": { - "@octokit/types": "^6.0.3" - } - }, - "node_modules/@octokit/core": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.6.0.tgz", - "integrity": "sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==", - "dependencies": { - "@octokit/auth-token": "^2.4.4", - "@octokit/graphql": "^4.5.8", - "@octokit/request": "^5.6.3", - "@octokit/request-error": "^2.0.5", - "@octokit/types": "^6.0.3", - "before-after-hook": "^2.2.0", - "universal-user-agent": "^6.0.0" - } - }, - "node_modules/@octokit/endpoint": { - "version": "6.0.12", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz", - "integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==", - "dependencies": { - "@octokit/types": "^6.0.3", - "is-plain-object": "^5.0.0", - "universal-user-agent": "^6.0.0" - } - }, - "node_modules/@octokit/graphql": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz", - "integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==", - "dependencies": { - "@octokit/request": "^5.6.0", - "@octokit/types": "^6.0.3", - "universal-user-agent": "^6.0.0" - } - }, - "node_modules/@octokit/openapi-types": { - "version": "12.11.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.11.0.tgz", - "integrity": "sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ==" - }, - "node_modules/@octokit/plugin-paginate-rest": { - "version": "2.21.3", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.21.3.tgz", - "integrity": "sha512-aCZTEf0y2h3OLbrgKkrfFdjRL6eSOo8komneVQJnYecAxIej7Bafor2xhuDJOIFau4pk0i/P28/XgtbyPF0ZHw==", - "dependencies": { - "@octokit/types": "^6.40.0" - }, - "peerDependencies": { - "@octokit/core": ">=2" - } - }, - "node_modules/@octokit/plugin-rest-endpoint-methods": { - "version": "5.16.2", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.16.2.tgz", - "integrity": "sha512-8QFz29Fg5jDuTPXVtey05BLm7OB+M8fnvE64RNegzX7U+5NUXcOcnpTIK0YfSHBg8gYd0oxIq3IZTe9SfPZiRw==", - "dependencies": { - "@octokit/types": "^6.39.0", - "deprecation": "^2.3.1" - }, - "peerDependencies": { - "@octokit/core": ">=3" - } - }, - "node_modules/@octokit/request": { - "version": "5.6.3", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz", - "integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==", - "dependencies": { - "@octokit/endpoint": "^6.0.1", - "@octokit/request-error": "^2.1.0", - "@octokit/types": "^6.16.1", - "is-plain-object": "^5.0.0", - "node-fetch": "^2.6.7", - "universal-user-agent": "^6.0.0" - } - }, - "node_modules/@octokit/request-error": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz", - "integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==", - "dependencies": { - "@octokit/types": "^6.0.3", - "deprecation": "^2.0.0", - "once": "^1.4.0" - } - }, - "node_modules/@octokit/types": { - "version": "6.41.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.41.0.tgz", - "integrity": "sha512-eJ2jbzjdijiL3B4PrSQaSjuF2sPEQPVCPzBvTHJD9Nz+9dw2SGH4K4xeQJ77YfTq5bRQ+bD8wT11JbeDPmxmGg==", - "dependencies": { - "@octokit/openapi-types": "^12.11.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "node_modules/before-after-hook": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", - "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==" - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" - }, - "node_modules/deprecation": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", - "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==" - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, - "node_modules/tunnel": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", - "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", - "engines": { - "node": ">=0.6.11 <=0.7.0 || >=0.7.3" - } - }, - "node_modules/universal-user-agent": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", - "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==" - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" - } - }, - "dependencies": { - "@actions/core": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.9.1.tgz", - "integrity": "sha512-5ad+U2YGrmmiw6du20AQW5XuWo7UKN2052FjSV7MX+Wfjf8sCqcsZe62NfgHys4QI4/Y+vQvLKYL8jWtA1ZBTA==", - "requires": { - "@actions/http-client": "^2.0.1", - "uuid": "^8.3.2" - } - }, - "@actions/github": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@actions/github/-/github-5.1.0.tgz", - "integrity": "sha512-tuI80F7JQIhg77ZTTgUAPpVD7ZnP9oHSPN8xw7LOwtA4vEMbAjWJNbmLBfV7xua7r016GyjzWLuec5cs8f/a8A==", - "requires": { - "@actions/http-client": "^2.0.1", - "@octokit/core": "^3.6.0", - "@octokit/plugin-paginate-rest": "^2.17.0", - "@octokit/plugin-rest-endpoint-methods": "^5.13.0" - } - }, - "@actions/http-client": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz", - "integrity": "sha512-PIXiMVtz6VvyaRsGY268qvj57hXQEpsYogYOu2nrQhlf+XCGmZstmuZBbAybUl1nQGnvS1k1eEsQ69ZoD7xlSw==", - "requires": { - "tunnel": "^0.0.6" - } - }, - "@octokit/auth-token": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz", - "integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==", - "requires": { - "@octokit/types": "^6.0.3" - } - }, - "@octokit/core": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.6.0.tgz", - "integrity": "sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==", - "requires": { - "@octokit/auth-token": "^2.4.4", - "@octokit/graphql": "^4.5.8", - "@octokit/request": "^5.6.3", - "@octokit/request-error": "^2.0.5", - "@octokit/types": "^6.0.3", - "before-after-hook": "^2.2.0", - "universal-user-agent": "^6.0.0" - } - }, - "@octokit/endpoint": { - "version": "6.0.12", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz", - "integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==", - "requires": { - "@octokit/types": "^6.0.3", - "is-plain-object": "^5.0.0", - "universal-user-agent": "^6.0.0" - } - }, - "@octokit/graphql": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz", - "integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==", - "requires": { - "@octokit/request": "^5.6.0", - "@octokit/types": "^6.0.3", - "universal-user-agent": "^6.0.0" - } - }, - "@octokit/openapi-types": { - "version": "12.11.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.11.0.tgz", - "integrity": "sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ==" - }, - "@octokit/plugin-paginate-rest": { - "version": "2.21.3", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.21.3.tgz", - "integrity": "sha512-aCZTEf0y2h3OLbrgKkrfFdjRL6eSOo8komneVQJnYecAxIej7Bafor2xhuDJOIFau4pk0i/P28/XgtbyPF0ZHw==", - "requires": { - "@octokit/types": "^6.40.0" - } - }, - "@octokit/plugin-rest-endpoint-methods": { - "version": "5.16.2", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.16.2.tgz", - "integrity": "sha512-8QFz29Fg5jDuTPXVtey05BLm7OB+M8fnvE64RNegzX7U+5NUXcOcnpTIK0YfSHBg8gYd0oxIq3IZTe9SfPZiRw==", - "requires": { - "@octokit/types": "^6.39.0", - "deprecation": "^2.3.1" - } - }, - "@octokit/request": { - "version": "5.6.3", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz", - "integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==", - "requires": { - "@octokit/endpoint": "^6.0.1", - "@octokit/request-error": "^2.1.0", - "@octokit/types": "^6.16.1", - "is-plain-object": "^5.0.0", - "node-fetch": "^2.6.7", - "universal-user-agent": "^6.0.0" - } - }, - "@octokit/request-error": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz", - "integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==", - "requires": { - "@octokit/types": "^6.0.3", - "deprecation": "^2.0.0", - "once": "^1.4.0" - } - }, - "@octokit/types": { - "version": "6.41.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.41.0.tgz", - "integrity": "sha512-eJ2jbzjdijiL3B4PrSQaSjuF2sPEQPVCPzBvTHJD9Nz+9dw2SGH4K4xeQJ77YfTq5bRQ+bD8wT11JbeDPmxmGg==", - "requires": { - "@octokit/openapi-types": "^12.11.0" - } - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "before-after-hook": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", - "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==" - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" - }, - "deprecation": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", - "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==" - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==" - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "requires": { - "whatwg-url": "^5.0.0" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "requires": { - "wrappy": "1" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" - }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, - "tunnel": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", - "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==" - }, - "universal-user-agent": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", - "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==" - }, - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" - }, - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" - } - } -} diff --git a/compiler/rustc_codegen_cranelift/.github/actions/github-release/package.json b/compiler/rustc_codegen_cranelift/.github/actions/github-release/package.json deleted file mode 100644 index d9c23f8873ec..000000000000 --- a/compiler/rustc_codegen_cranelift/.github/actions/github-release/package.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "rustc_codegen_cranelift-github-release", - "version": "0.0.0", - "license": "Apache-2.0 WITH LLVM-exception", - "main": "main.js", - "dependencies": { - "@actions/core": "^1.9.1", - "@actions/github": "^5.1.0", - "glob": "^7.1.5" - } -} diff --git a/compiler/rustc_codegen_cranelift/.github/workflows/abi-cafe.yml b/compiler/rustc_codegen_cranelift/.github/workflows/abi-cafe.yml deleted file mode 100644 index 12aa69d3c795..000000000000 --- a/compiler/rustc_codegen_cranelift/.github/workflows/abi-cafe.yml +++ /dev/null @@ -1,57 +0,0 @@ -name: Abi-cafe - -on: - - push - -jobs: - abi_cafe: - runs-on: ${{ matrix.os }} - timeout-minutes: 60 - concurrency: - group: ${{ github.workflow }}-${{ github.ref }}-${{ matrix.os }}-${{ matrix.env.TARGET_TRIPLE }} - cancel-in-progress: true - - defaults: - run: - shell: bash - - strategy: - fail-fast: true - matrix: - include: - - os: ubuntu-latest - env: - TARGET_TRIPLE: x86_64-unknown-linux-gnu - - os: macos-latest - env: - TARGET_TRIPLE: x86_64-apple-darwin - - os: windows-latest - env: - TARGET_TRIPLE: x86_64-pc-windows-msvc - - os: windows-latest - env: - TARGET_TRIPLE: x86_64-pc-windows-gnu - - steps: - - uses: actions/checkout@v3 - - - name: Cache cargo target dir - uses: actions/cache@v3 - with: - path: build/cg_clif - key: ${{ runner.os }}-${{ matrix.env.TARGET_TRIPLE }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }} - - - name: Set MinGW as the default toolchain - if: matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu' - run: rustup set default-host x86_64-pc-windows-gnu - - - name: Prepare dependencies - run: ./y.sh prepare - - - name: Build - run: ./y.sh build --sysroot none - - - name: Test abi-cafe - env: - TARGET_TRIPLE: ${{ matrix.env.TARGET_TRIPLE }} - run: ./y.sh abi-cafe diff --git a/compiler/rustc_codegen_cranelift/.github/workflows/audit.yml b/compiler/rustc_codegen_cranelift/.github/workflows/audit.yml deleted file mode 100644 index 3efdec415593..000000000000 --- a/compiler/rustc_codegen_cranelift/.github/workflows/audit.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: Security audit -on: - workflow_dispatch: - schedule: - - cron: '0 10 * * 1' # every monday at 10:00 UTC -permissions: - issues: write - checks: write -jobs: - audit: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - run: | - sed -i 's/components.*/components = []/' rust-toolchain - echo 'profile = "minimal"' >> rust-toolchain - - uses: rustsec/audit-check@v1.4.1 - with: - token: ${{ secrets.GITHUB_TOKEN }} diff --git a/compiler/rustc_codegen_cranelift/.github/workflows/main.yml b/compiler/rustc_codegen_cranelift/.github/workflows/main.yml deleted file mode 100644 index 652d6eca3f6e..000000000000 --- a/compiler/rustc_codegen_cranelift/.github/workflows/main.yml +++ /dev/null @@ -1,292 +0,0 @@ -name: CI - -on: - - push - - pull_request - -jobs: - rustfmt: - runs-on: ubuntu-latest - timeout-minutes: 10 - - steps: - - uses: actions/checkout@v3 - - - name: Avoid installing rustc-dev - run: | - sed -i 's/components.*/components = ["rustfmt"]/' rust-toolchain - echo 'profile = "minimal"' >> rust-toolchain - rustfmt -v - - - name: Rustfmt - run: | - cargo fmt --check - rustfmt --check build_system/main.rs - rustfmt --check example/* - - - test: - runs-on: ${{ matrix.os }} - timeout-minutes: 60 - - defaults: - run: - shell: bash - - strategy: - fail-fast: false - matrix: - include: - - os: ubuntu-latest - env: - TARGET_TRIPLE: x86_64-unknown-linux-gnu - - os: macos-latest - env: - TARGET_TRIPLE: x86_64-apple-darwin - # cross-compile from Linux to Windows using mingw - - os: ubuntu-latest - env: - TARGET_TRIPLE: x86_64-pc-windows-gnu - - os: ubuntu-latest - env: - TARGET_TRIPLE: aarch64-unknown-linux-gnu - # s390x requires QEMU 6.1 or greater, we could build it from source, but ubuntu 22.04 comes with 6.2 by default - - os: ubuntu-latest - env: - TARGET_TRIPLE: s390x-unknown-linux-gnu - - os: windows-latest - env: - TARGET_TRIPLE: x86_64-pc-windows-msvc - - os: windows-latest - env: - TARGET_TRIPLE: x86_64-pc-windows-gnu - - steps: - - uses: actions/checkout@v3 - - - name: Cache cargo target dir - uses: actions/cache@v3 - with: - path: build/cg_clif - key: ${{ runner.os }}-${{ matrix.env.TARGET_TRIPLE }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }} - - - name: Set MinGW as the default toolchain - if: matrix.os == 'windows-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu' - run: rustup set default-host x86_64-pc-windows-gnu - - - name: Install MinGW toolchain and wine - if: matrix.os == 'ubuntu-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu' - run: | - sudo apt-get update - sudo apt-get install -y gcc-mingw-w64-x86-64 wine-stable - - - name: Install AArch64 toolchain and qemu - if: matrix.os == 'ubuntu-latest' && matrix.env.TARGET_TRIPLE == 'aarch64-unknown-linux-gnu' - run: | - sudo apt-get update - sudo apt-get install -y gcc-aarch64-linux-gnu qemu-user - - - name: Install s390x toolchain and qemu - if: matrix.env.TARGET_TRIPLE == 's390x-unknown-linux-gnu' - run: | - sudo apt-get update - sudo apt-get install -y gcc-s390x-linux-gnu qemu-user - - - name: Prepare dependencies - run: ./y.sh prepare - - - name: Build - run: ./y.sh build --sysroot none - - - name: Test - env: - TARGET_TRIPLE: ${{ matrix.env.TARGET_TRIPLE }} - run: ./y.sh test - - - name: Install LLVM standard library - run: rustup target add ${{ matrix.env.TARGET_TRIPLE }} - - # This is roughly config rust-lang/rust uses for testing - - name: Test with LLVM sysroot - # Skip native x86_64-pc-windows-gnu. It is way too slow and cross-compiled - # x86_64-pc-windows-gnu covers at least part of the tests. - if: matrix.os != 'windows-latest' || matrix.env.TARGET_TRIPLE != 'x86_64-pc-windows-gnu' - env: - TARGET_TRIPLE: ${{ matrix.env.TARGET_TRIPLE }} - run: ./y.sh test --sysroot llvm --no-unstable-features - - - # This job doesn't use cg_clif in any way. It checks that all cg_clif tests work with cg_llvm too. - test_llvm: - runs-on: ubuntu-latest - timeout-minutes: 60 - - defaults: - run: - shell: bash - - steps: - - uses: actions/checkout@v3 - - - name: Prepare dependencies - run: ./y.sh prepare - - - name: Disable JIT tests - run: | - sed -i 's/jit./#jit./' config.txt - - - name: Test - env: - TARGET_TRIPLE: x86_64-unknown-linux-gnu - run: ./y.sh test --use-backend llvm - - bench: - runs-on: ubuntu-latest - timeout-minutes: 60 - - defaults: - run: - shell: bash - - steps: - - uses: actions/checkout@v3 - - - name: Cache cargo target dir - uses: actions/cache@v3 - with: - path: build/cg_clif - key: ${{ runner.os }}-x86_64-unknown-linux-gnu-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }} - - - name: Cache cargo bin dir - uses: actions/cache@v3 - with: - path: ~/.cargo/bin - key: ${{ runner.os }}-${{ matrix.env.TARGET_TRIPLE }}-cargo-bin-dir-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }} - - - name: Install hyperfine - run: cargo install hyperfine || true - - - name: Prepare dependencies - run: ./y.sh prepare - - - name: Build - run: CI_OPT=1 ./y.sh build --sysroot none - - - name: Benchmark - run: CI_OPT=1 ./y.sh bench - - - dist: - runs-on: ${{ matrix.os }} - timeout-minutes: 60 - - defaults: - run: - shell: bash - - strategy: - fail-fast: false - matrix: - include: - # FIXME update at some point in the future once most distros use a newer glibc - - os: ubuntu-20.04 - env: - TARGET_TRIPLE: x86_64-unknown-linux-gnu - - os: macos-latest - env: - TARGET_TRIPLE: x86_64-apple-darwin - # cross-compile from Linux to Windows using mingw - - os: ubuntu-latest - env: - TARGET_TRIPLE: x86_64-pc-windows-gnu - - os: windows-latest - env: - TARGET_TRIPLE: x86_64-pc-windows-msvc - - os: windows-latest - env: - TARGET_TRIPLE: x86_64-pc-windows-gnu - - steps: - - uses: actions/checkout@v3 - - - name: Cache cargo target dir - uses: actions/cache@v3 - with: - path: build/cg_clif - key: ${{ runner.os }}-${{ matrix.env.TARGET_TRIPLE }}-dist-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }} - - - name: Set MinGW as the default toolchain - if: matrix.os == 'windows-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu' - run: rustup set default-host x86_64-pc-windows-gnu - - - name: Install MinGW toolchain and wine - if: matrix.os == 'ubuntu-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu' - run: | - sudo apt-get update - sudo apt-get install -y gcc-mingw-w64-x86-64 wine-stable - - - name: Prepare dependencies - run: ./y.sh prepare - - - name: Build backend - run: CI_OPT=1 ./y.sh build --sysroot none - - - name: Build sysroot - run: CI_OPT=1 ./y.sh build - - - name: Package prebuilt cg_clif - run: tar cvfJ cg_clif.tar.xz dist - - - name: Upload prebuilt cg_clif - if: matrix.os == 'windows-latest' || matrix.env.TARGET_TRIPLE != 'x86_64-pc-windows-gnu' - uses: actions/upload-artifact@v3 - with: - name: cg_clif-${{ matrix.env.TARGET_TRIPLE }} - path: cg_clif.tar.xz - - - name: Upload prebuilt cg_clif (cross compile) - if: matrix.os != 'windows-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu' - uses: actions/upload-artifact@v3 - with: - name: cg_clif-${{ runner.os }}-cross-x86_64-mingw - path: cg_clif.tar.xz - - release: - runs-on: ubuntu-latest - timeout-minutes: 10 - if: ${{ github.ref == 'refs/heads/master' }} - needs: [rustfmt, test, bench, dist] - - concurrency: - group: release-dev - cancel-in-progress: true - - steps: - - uses: actions/checkout@v3 - - - name: Download all built artifacts - uses: actions/download-artifact@v3 - with: - path: artifacts/ - - - run: | - ls -R artifacts/ - mkdir release/ - pushd artifacts/ - for dir in *; do - mv $dir/cg_clif.tar.xz ../release/$dir.tar.xz - rmdir $dir/ # verify $dir is empty - done - popd - rmdir artifacts/ # verify all artifacts are represented in release/ - ls -R release/ - - - run: npm install --production - working-directory: .github/actions/github-release - - - name: Publish Release - uses: ./.github/actions/github-release - with: - files: "release/*" - token: ${{ github.token }} - continue-on-error: true diff --git a/compiler/rustc_codegen_cranelift/.github/workflows/rustc.yml b/compiler/rustc_codegen_cranelift/.github/workflows/rustc.yml deleted file mode 100644 index b49dc3aff7aa..000000000000 --- a/compiler/rustc_codegen_cranelift/.github/workflows/rustc.yml +++ /dev/null @@ -1,44 +0,0 @@ -name: Various rustc tests - -on: - - push - -jobs: - bootstrap_rustc: - runs-on: ubuntu-latest - timeout-minutes: 60 - - steps: - - uses: actions/checkout@v3 - - - name: Cache cargo target dir - uses: actions/cache@v3 - with: - path: build/cg_clif - key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }} - - - name: Prepare dependencies - run: ./y.sh prepare - - - name: Test - run: ./scripts/test_bootstrap.sh - - - rustc_test_suite: - runs-on: ubuntu-latest - timeout-minutes: 60 - - steps: - - uses: actions/checkout@v3 - - - name: Cache cargo target dir - uses: actions/cache@v3 - with: - path: build/cg_clif - key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }} - - - name: Prepare dependencies - run: ./y.sh prepare - - - name: Test - run: ./scripts/test_rustc_tests.sh diff --git a/compiler/rustc_codegen_gcc/.github/workflows/ci.yml b/compiler/rustc_codegen_gcc/.github/workflows/ci.yml deleted file mode 100644 index f075c744e457..000000000000 --- a/compiler/rustc_codegen_gcc/.github/workflows/ci.yml +++ /dev/null @@ -1,154 +0,0 @@ -name: CI - -on: - - push - - pull_request - -permissions: - contents: read - -env: - # Enable backtraces for easier debugging - RUST_BACKTRACE: 1 - -jobs: - build: - runs-on: ubuntu-22.04 - - strategy: - fail-fast: false - matrix: - libgccjit_version: - - { gcc: "libgccjit.so", extra: "", env_extra: "", artifacts_branch: "master" } - - { gcc: "libgccjit_without_int128.so", extra: "", env_extra: "", artifacts_branch: "master-without-128bit-integers" } - - { gcc: "libgccjit12.so", extra: "--no-default-features", env_extra: "TEST_FLAGS='-Cpanic=abort -Zpanic-abort-tests'", artifacts_branch: "gcc12" } - commands: [ - "--mini-tests", - "--std-tests", - # FIXME: re-enable asm tests when GCC can emit in the right syntax. - # "--asm-tests", - "--test-libcore", - "--extended-rand-tests", - "--extended-regex-example-tests", - "--extended-regex-tests", - "--test-successful-rustc --nb-parts 2 --current-part 0", - "--test-successful-rustc --nb-parts 2 --current-part 1", - "--test-failing-rustc", - ] - - steps: - - uses: actions/checkout@v3 - - - uses: actions/checkout@v3 - with: - repository: llvm/llvm-project - path: llvm - - - name: Install packages - # `llvm-14-tools` is needed to install the `FileCheck` binary which is used for asm tests. - run: sudo apt-get install ninja-build ripgrep llvm-14-tools - - - name: Install libgccjit12 - if: matrix.libgccjit_version.gcc == 'libgccjit12.so' - run: sudo apt-get install libgccjit-12-dev - - - name: Download artifact - if: matrix.libgccjit_version.gcc != 'libgccjit12.so' - uses: dawidd6/action-download-artifact@v2 - with: - workflow: main.yml - name: gcc-13 - path: gcc-13 - repo: antoyo/gcc - branch: ${{ matrix.libgccjit_version.artifacts_branch }} - event: push - search_artifacts: true # Because, instead, the action only check the last job ran and that won't work since we want multiple artifacts. - - - name: Setup path to libgccjit - if: matrix.libgccjit_version.gcc == 'libgccjit12.so' - run: echo /usr/lib/gcc/x86_64-linux-gnu/12 > gcc_path - - - name: Setup path to libgccjit - if: matrix.libgccjit_version.gcc != 'libgccjit12.so' - run: | - sudo dpkg --force-overwrite -i gcc-13/gcc-13.deb - echo /usr/lib/ > gcc_path - - - name: Set env - run: | - echo "LIBRARY_PATH=$(cat gcc_path)" >> $GITHUB_ENV - echo "LD_LIBRARY_PATH=$(cat gcc_path)" >> $GITHUB_ENV - echo "workspace="$GITHUB_WORKSPACE >> $GITHUB_ENV - - - name: Set RUST_COMPILER_RT_ROOT - run: echo "RUST_COMPILER_RT_ROOT="${{ env.workspace }}/llvm/compiler-rt >> $GITHUB_ENV - - - name: Cache cargo installed crates - uses: actions/cache@v3 - with: - path: ~/.cargo/bin - key: cargo-installed-crates2-ubuntu-latest - - - name: Cache cargo registry - uses: actions/cache@v3 - with: - path: ~/.cargo/registry - key: ${{ runner.os }}-cargo-registry2-${{ hashFiles('**/Cargo.lock') }} - - - name: Cache cargo index - uses: actions/cache@v3 - with: - path: ~/.cargo/git - key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }} - - - name: Cache cargo target dir - uses: actions/cache@v3 - with: - path: target - key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain') }} - - #- name: Cache rust repository - ## We only clone the rust repository for rustc tests - #if: ${{ contains(matrix.commands, 'rustc') }} - #uses: actions/cache@v3 - #id: cache-rust-repository - #with: - #path: rust - #key: ${{ runner.os }}-packages-${{ hashFiles('rust/.git/HEAD') }} - - - name: Build - run: | - ./y.sh prepare --only-libcore - ${{ matrix.libgccjit_version.env_extra }} ./y.sh build ${{ matrix.libgccjit_version.extra }} - ${{ matrix.libgccjit_version.env_extra }} cargo test ${{ matrix.libgccjit_version.extra }} - ./clean_all.sh - - - name: Prepare dependencies - run: | - git config --global user.email "user@example.com" - git config --global user.name "User" - ./y.sh prepare - - # Compile is a separate step, as the actions-rs/cargo action supports error annotations - - name: Compile - uses: actions-rs/cargo@v1.0.3 - with: - command: build - args: --release - - - name: Add more failing tests for GCC 12 - if: ${{ matrix.libgccjit_version.gcc == 'libgccjit12.so' }} - run: cat failing-ui-tests12.txt >> failing-ui-tests.txt - - - name: Add more failing tests because the sysroot is not compiled with LTO - run: cat failing-non-lto-tests.txt >> failing-ui-tests.txt - - - name: Run tests - run: | - ${{ matrix.libgccjit_version.env_extra }} ./test.sh --release --clean --build-sysroot ${{ matrix.commands }} ${{ matrix.libgccjit_version.extra }} - - duplicates: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - run: python tools/check_intrinsics_duplicates.py diff --git a/compiler/rustc_codegen_gcc/.github/workflows/release.yml b/compiler/rustc_codegen_gcc/.github/workflows/release.yml deleted file mode 100644 index bd0415040e7e..000000000000 --- a/compiler/rustc_codegen_gcc/.github/workflows/release.yml +++ /dev/null @@ -1,113 +0,0 @@ -name: CI with sysroot compiled in release mode - -on: - - push - - pull_request - -permissions: - contents: read - -env: - # Enable backtraces for easier debugging - RUST_BACKTRACE: 1 - -jobs: - build: - runs-on: ubuntu-latest - - strategy: - fail-fast: false - matrix: - commands: [ - "--test-successful-rustc --nb-parts 2 --current-part 0", - "--test-successful-rustc --nb-parts 2 --current-part 1", - ] - - steps: - - uses: actions/checkout@v3 - - - uses: actions/checkout@v3 - with: - repository: llvm/llvm-project - path: llvm - - - name: Install packages - run: sudo apt-get install ninja-build ripgrep - - - name: Download artifact - uses: dawidd6/action-download-artifact@v2 - with: - workflow: main.yml - name: gcc-13 - path: gcc-13 - repo: antoyo/gcc - branch: "master" - event: push - search_artifacts: true # Because, instead, the action only check the last job ran and that won't work since we want multiple artifacts. - - - name: Setup path to libgccjit - run: | - sudo dpkg --force-overwrite -i gcc-13/gcc-13.deb - echo /usr/lib/ > gcc_path - - - name: Set env - run: | - echo "LIBRARY_PATH=$(cat gcc_path)" >> $GITHUB_ENV - echo "LD_LIBRARY_PATH=$(cat gcc_path)" >> $GITHUB_ENV - echo "workspace="$GITHUB_WORKSPACE >> $GITHUB_ENV - - - name: Set RUST_COMPILER_RT_ROOT - run: echo "RUST_COMPILER_RT_ROOT="${{ env.workspace }}/llvm/compiler-rt >> $GITHUB_ENV - - - name: Cache cargo installed crates - uses: actions/cache@v3 - with: - path: ~/.cargo/bin - key: cargo-installed-crates2-ubuntu-latest - - - name: Cache cargo registry - uses: actions/cache@v3 - with: - path: ~/.cargo/registry - key: ${{ runner.os }}-cargo-registry2-${{ hashFiles('**/Cargo.lock') }} - - - name: Cache cargo index - uses: actions/cache@v3 - with: - path: ~/.cargo/git - key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }} - - - name: Cache cargo target dir - uses: actions/cache@v3 - with: - path: target - key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain') }} - - - name: Build - run: | - ./y.sh prepare --only-libcore - EMBED_LTO_BITCODE=1 ./y.sh build --release --release-sysroot - cargo test - ./clean_all.sh - - - name: Prepare dependencies - run: | - git config --global user.email "user@example.com" - git config --global user.name "User" - ./y.sh prepare - # FIXME(antoyo): we cannot enable LTO for stdarch tests currently because of some failing LTO tests using proc-macros. - echo -n 'lto = "fat"' >> build_sysroot/Cargo.toml - - # Compile is a separate step, as the actions-rs/cargo action supports error annotations - - name: Compile - uses: actions-rs/cargo@v1.0.3 - with: - command: build - args: --release - - - name: Add more failing tests because of undefined symbol errors (FIXME) - run: cat failing-lto-tests.txt >> failing-ui-tests.txt - - - name: Run tests - run: | - EMBED_LTO_BITCODE=1 ./test.sh --release --clean --release-sysroot --build-sysroot ${{ matrix.commands }} diff --git a/compiler/rustc_codegen_gcc/.github/workflows/stdarch.yml b/compiler/rustc_codegen_gcc/.github/workflows/stdarch.yml deleted file mode 100644 index 6c28326823cc..000000000000 --- a/compiler/rustc_codegen_gcc/.github/workflows/stdarch.yml +++ /dev/null @@ -1,140 +0,0 @@ -name: stdarch tests with sysroot compiled in release mode - -on: - - push - - pull_request - -permissions: - contents: read - -env: - # Enable backtraces for easier debugging - RUST_BACKTRACE: 1 - -jobs: - build: - runs-on: ubuntu-latest - - strategy: - fail-fast: false - matrix: - cargo_runner: [ - "sde -future -rtm_mode full --", - "", - ] - - steps: - - uses: actions/checkout@v3 - - - uses: actions/checkout@v3 - with: - repository: llvm/llvm-project - path: llvm - - - name: Install packages - run: sudo apt-get install ninja-build ripgrep - - - name: Install Intel Software Development Emulator - if: ${{ matrix.cargo_runner }} - run: | - mkdir intel-sde - cd intel-sde - dir=sde-external-9.14.0-2022-10-25-lin - file=$dir.tar.xz - wget https://downloadmirror.intel.com/751535/$file - tar xvf $file - sudo mkdir /usr/share/intel-sde - sudo cp -r $dir/* /usr/share/intel-sde - sudo ln -s /usr/share/intel-sde/sde /usr/bin/sde - sudo ln -s /usr/share/intel-sde/sde64 /usr/bin/sde64 - - - name: Download artifact - uses: dawidd6/action-download-artifact@v2 - with: - workflow: main.yml - name: gcc-13 - path: gcc-13 - repo: antoyo/gcc - branch: "master" - event: push - search_artifacts: true # Because, instead, the action only check the last job ran and that won't work since we want multiple artifacts. - - - name: Setup path to libgccjit - run: | - sudo dpkg --force-overwrite -i gcc-13/gcc-13.deb - echo /usr/lib/ > gcc_path - - - name: Set env - run: | - echo "LIBRARY_PATH=$(cat gcc_path)" >> $GITHUB_ENV - echo "LD_LIBRARY_PATH=$(cat gcc_path)" >> $GITHUB_ENV - echo "workspace="$GITHUB_WORKSPACE >> $GITHUB_ENV - - - name: Set RUST_COMPILER_RT_ROOT - run: echo "RUST_COMPILER_RT_ROOT="${{ env.workspace }}/llvm/compiler-rt >> $GITHUB_ENV - - - name: Cache cargo installed crates - uses: actions/cache@v3 - with: - path: ~/.cargo/bin - key: cargo-installed-crates2-ubuntu-latest - - - name: Cache cargo registry - uses: actions/cache@v3 - with: - path: ~/.cargo/registry - key: ${{ runner.os }}-cargo-registry2-${{ hashFiles('**/Cargo.lock') }} - - - name: Cache cargo index - uses: actions/cache@v3 - with: - path: ~/.cargo/git - key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }} - - - name: Cache cargo target dir - uses: actions/cache@v3 - with: - path: target - key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain') }} - - - name: Build - run: | - ./y.sh prepare --only-libcore - ./y.sh build --release --release-sysroot - cargo test - - - name: Clean - if: ${{ !matrix.cargo_runner }} - run: | - ./clean_all.sh - - - name: Prepare dependencies - run: | - git config --global user.email "user@example.com" - git config --global user.name "User" - ./y.sh prepare - - # Compile is a separate step, as the actions-rs/cargo action supports error annotations - - name: Compile - uses: actions-rs/cargo@v1.0.3 - with: - command: build - args: --release - - - name: Run tests - if: ${{ !matrix.cargo_runner }} - run: | - ./test.sh --release --clean --release-sysroot --build-sysroot --mini-tests --std-tests --test-libcore - - - name: Run stdarch tests - if: ${{ !matrix.cargo_runner }} - run: | - cd build_sysroot/sysroot_src/library/stdarch/ - CHANNEL=release TARGET=x86_64-unknown-linux-gnu CG_RUSTFLAGS="-Ainternal_features" ../../../../cargo.sh test - - - name: Run stdarch tests - if: ${{ matrix.cargo_runner }} - run: | - cd build_sysroot/sysroot_src/library/stdarch/ - # FIXME: these tests fail when the sysroot is compiled with LTO because of a missing symbol in proc-macro. - STDARCH_TEST_EVERYTHING=1 CHANNEL=release CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER="${{ matrix.cargo_runner }}" TARGET=x86_64-unknown-linux-gnu CG_RUSTFLAGS="-Ainternal_features" ../../../../cargo.sh test -- --skip rtm --skip tbm --skip sse4a diff --git a/library/portable-simd/.github/ISSUE_TEMPLATE/blank_issue.md b/library/portable-simd/.github/ISSUE_TEMPLATE/blank_issue.md deleted file mode 100644 index 9aef3ebe637a..000000000000 --- a/library/portable-simd/.github/ISSUE_TEMPLATE/blank_issue.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -name: Blank Issue -about: Create a blank issue. ---- diff --git a/library/portable-simd/.github/ISSUE_TEMPLATE/bug_report.md b/library/portable-simd/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 16a8251d52ba..000000000000 --- a/library/portable-simd/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -name: Bug Report -about: Create a bug report for Rust. -labels: C-bug ---- - - -I tried this code: - -```rust - -``` - -I expected to see this happen: *explanation* - -Instead, this happened: *explanation* - -### Meta - -`rustc --version --verbose`: -``` - -``` - - -`crate version in Cargo.toml`: -```toml -[dependencies] -stdsimd = -``` - - - - -
Backtrace -

- -``` - -``` - -

-
diff --git a/library/portable-simd/.github/ISSUE_TEMPLATE/config.yml b/library/portable-simd/.github/ISSUE_TEMPLATE/config.yml deleted file mode 100644 index 1567542c01a4..000000000000 --- a/library/portable-simd/.github/ISSUE_TEMPLATE/config.yml +++ /dev/null @@ -1,10 +0,0 @@ -# This only controls whether a tiny, hard-to-find "open a blank issue" link appears at the end of -# the template list. -blank_issues_enabled: true -contact_links: - - name: Intrinsic Support - url: https://github.com/rust-lang/stdarch/issues - about: Please direct issues about Rust's support for vendor intrinsics to core::arch - - name: Internal Compiler Error - url: https://github.com/rust-lang/rust/issues - about: Please report ICEs to the rustc repository diff --git a/library/portable-simd/.github/ISSUE_TEMPLATE/feature_request.md b/library/portable-simd/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index be6c9e3d17e2..000000000000 --- a/library/portable-simd/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -name: Feature Request -about: Request an addition to the core::simd API -labels: C-feature-request ---- - diff --git a/library/portable-simd/.github/PULL_REQUEST_TEMPLATE.md b/library/portable-simd/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index 31422b793450..000000000000 --- a/library/portable-simd/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,18 +0,0 @@ -Hello, welcome to `std::simd`! - -It seems this pull request template checklist was created while a lot of vector math ops were being implemented, and only really applies to ops. Feel free to delete everything here if it's not applicable, or ask for help if you're not sure what it means! - -For a given vector math operation on TxN, please add tests for interactions with: - - [ ] `T::MAX` - - [ ] `T::MIN` - - [ ] -1 - - [ ] 1 - - [ ] 0 - - -For a given vector math operation on TxN where T is a float, please add tests for test interactions with: - - [ ] a really large number, larger than the mantissa - - [ ] a really small "subnormal" number - - [ ] NaN - - [ ] Infinity - - [ ] Negative Infinity diff --git a/library/portable-simd/.github/workflows/ci.yml b/library/portable-simd/.github/workflows/ci.yml deleted file mode 100644 index 1ff377fce346..000000000000 --- a/library/portable-simd/.github/workflows/ci.yml +++ /dev/null @@ -1,265 +0,0 @@ -name: CI - -on: - pull_request: - push: - branches: - - master - -env: - CARGO_NET_RETRY: 10 - RUSTUP_MAX_RETRIES: 10 - -jobs: - rustfmt: - name: "rustfmt" - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - name: Setup Rust - run: | - rustup update nightly --no-self-update - rustup default nightly - rustup component add rustfmt - - name: Run rustfmt - run: cargo fmt --all -- --check - - clippy: - name: "clippy on ${{ matrix.target }}" - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - target: - # We shouldn't really have any OS-specific code, so think of this as a list of architectures - - x86_64-unknown-linux-gnu - - i686-unknown-linux-gnu - - i586-unknown-linux-gnu - - aarch64-unknown-linux-gnu - - armv7-unknown-linux-gnueabihf - # non-nightly since https://github.com/rust-lang/rust/pull/113274 - # - mips-unknown-linux-gnu - # - mips64-unknown-linux-gnuabi64 - - powerpc-unknown-linux-gnu - - powerpc64-unknown-linux-gnu - - riscv64gc-unknown-linux-gnu - - s390x-unknown-linux-gnu - - sparc64-unknown-linux-gnu - - wasm32-unknown-unknown - - steps: - - uses: actions/checkout@v2 - - name: Setup Rust - run: | - rustup update nightly --no-self-update - rustup default nightly - rustup target add ${{ matrix.target }} - rustup component add clippy - - name: Run Clippy - run: cargo clippy --all-targets --target ${{ matrix.target }} - - x86-tests: - name: "${{ matrix.target_feature }} on ${{ matrix.target }}" - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - target: [x86_64-pc-windows-msvc, i686-pc-windows-msvc, i586-pc-windows-msvc, x86_64-unknown-linux-gnu, x86_64-apple-darwin] - # `default` means we use the default target config for the target, - # `native` means we run with `-Ctarget-cpu=native`, and anything else is - # an arg to `-Ctarget-feature` - target_feature: [default, native, +sse3, +ssse3, +sse4.1, +sse4.2, +avx, +avx2] - - exclude: - # The macos runners seem to only reliably support up to `avx`. - - { target: x86_64-apple-darwin, target_feature: +avx2 } - # These features are statically known to be present for all 64 bit - # macs, and thus are covered by the `default` test - - { target: x86_64-apple-darwin, target_feature: +sse3 } - - { target: x86_64-apple-darwin, target_feature: +ssse3 } - # -Ctarget-cpu=native sounds like bad-news if target != host - - { target: i686-pc-windows-msvc, target_feature: native } - - { target: i586-pc-windows-msvc, target_feature: native } - - include: - # Populate the `matrix.os` field - - { target: x86_64-apple-darwin, os: macos-latest } - - { target: x86_64-unknown-linux-gnu, os: ubuntu-latest } - - { target: x86_64-pc-windows-msvc, os: windows-latest } - - { target: i686-pc-windows-msvc, os: windows-latest } - - { target: i586-pc-windows-msvc, os: windows-latest } - - # These are globally available on all the other targets. - - { target: i586-pc-windows-msvc, target_feature: +sse, os: windows-latest } - - { target: i586-pc-windows-msvc, target_feature: +sse2, os: windows-latest } - - # Annoyingly, the x86_64-unknown-linux-gnu runner *almost* always has - # avx512vl, but occasionally doesn't. Maybe one day we can enable it. - - steps: - - uses: actions/checkout@v2 - - name: Setup Rust - run: | - rustup update nightly --no-self-update - rustup default nightly - rustup target add ${{ matrix.target }} - - - name: Configure RUSTFLAGS - shell: bash - run: | - case "${{ matrix.target_feature }}" in - default) - echo "RUSTFLAGS=-Dwarnings" >> $GITHUB_ENV;; - native) - echo "RUSTFLAGS=-Dwarnings -Ctarget-cpu=native" >> $GITHUB_ENV - ;; - *) - echo "RUSTFLAGS=-Dwarnings -Ctarget-feature=${{ matrix.target_feature }}" >> $GITHUB_ENV - ;; - esac - - # Super useful for debugging why a SIGILL occurred. - - name: Dump target configuration and support - run: | - rustc -Vv - - echo "Caveat: not all target features are expected to be logged" - - echo "## Requested target configuration (RUSTFLAGS=$RUSTFLAGS)" - rustc --print=cfg --target=${{ matrix.target }} $RUSTFLAGS - - echo "## Supported target configuration for --target=${{ matrix.target }}" - rustc --print=cfg --target=${{ matrix.target }} -Ctarget-cpu=native - - echo "## Natively supported target configuration" - rustc --print=cfg -Ctarget-cpu=native - - - name: Test (debug) - run: cargo test --verbose --target=${{ matrix.target }} - - - name: Test (release) - run: cargo test --verbose --target=${{ matrix.target }} --release - - wasm-tests: - name: "wasm (firefox, ${{ matrix.name }})" - runs-on: ubuntu-latest - strategy: - matrix: - include: - - { name: default, RUSTFLAGS: "" } - - { name: simd128, RUSTFLAGS: "-C target-feature=+simd128" } - steps: - - uses: actions/checkout@v2 - - name: Setup Rust - run: | - rustup update nightly --no-self-update - rustup default nightly - - name: Install wasm-pack - run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh - - name: Test (debug) - run: wasm-pack test --firefox --headless crates/core_simd - env: - RUSTFLAGS: ${{ matrix.rustflags }} - - name: Test (release) - run: wasm-pack test --firefox --headless crates/core_simd --release - env: - RUSTFLAGS: ${{ matrix.rustflags }} - - cross-tests: - name: "${{ matrix.target }} (via cross)" - runs-on: ubuntu-latest - strategy: - fail-fast: false - # TODO: Sadly, we cant configure target-feature in a meaningful way - # because `cross` doesn't tell qemu to enable any non-default cpu - # features, nor does it give us a way to do so. - # - # Ultimately, we'd like to do something like [rust-lang/stdarch][stdarch]. - # This is a lot more complex... but in practice it's likely that we can just - # snarf the docker config from around [here][1000-dockerfiles]. - # - # [stdarch]: https://github.com/rust-lang/stdarch/blob/a5db4eaf/.github/workflows/main.yml#L67 - # [1000-dockerfiles]: https://github.com/rust-lang/stdarch/tree/a5db4eaf/ci/docker - - matrix: - target: - - i586-unknown-linux-gnu - # 32-bit arm has a few idiosyncracies like having subnormal flushing - # to zero on by default. Ideally we'd set - - armv7-unknown-linux-gnueabihf - - aarch64-unknown-linux-gnu - # Note: The issue above means neither of these mips targets will use - # MSA (mips simd) but MIPS uses a nonstandard binary representation - # for NaNs which makes it worth testing on despite that. - # - mips-unknown-linux-gnu - # - mips64-unknown-linux-gnuabi64 - - riscv64gc-unknown-linux-gnu - # TODO this test works, but it appears to time out - # - powerpc-unknown-linux-gnu - # TODO this test is broken, but it appears to be a problem with QEMU, not us. - # - powerpc64le-unknown-linux-gnu - # TODO enable this once a new version of cross is released - # - powerpc64-unknown-linux-gnu - - steps: - - uses: actions/checkout@v2 - - name: Setup Rust - run: | - rustup update nightly --no-self-update - rustup default nightly - rustup target add ${{ matrix.target }} - rustup component add rust-src - - - name: Install Cross - # Equivalent to `cargo install cross`, but downloading a prebuilt - # binary. Ideally we wouldn't hardcode a version, but the version number - # being part of the tarball means we can't just use the download/latest - # URL :( - run: | - CROSS_URL=https://github.com/rust-embedded/cross/releases/download/v0.2.1/cross-v0.2.1-x86_64-unknown-linux-gnu.tar.gz - mkdir -p "$HOME/.bin" - curl -sfSL --retry-delay 10 --retry 5 "${CROSS_URL}" | tar zxf - -C "$HOME/.bin" - echo "$HOME/.bin" >> $GITHUB_PATH - - - name: Test (debug) - run: cross test --verbose --target=${{ matrix.target }} - - - name: Test (release) - run: cross test --verbose --target=${{ matrix.target }} --release - - features: - name: "Check cargo features (${{ matrix.simd }} × ${{ matrix.features }})" - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - simd: - - "" - - "avx512" - features: - - "" - - "--features std" - - "--features generic_const_exprs" - - "--features std --features generic_const_exprs" - - "--features all_lane_counts" - - "--features all_lane_counts --features std" - - "--features all_lane_counts --features generic_const_exprs" - - "--features all_lane_counts --features std --features generic_const_exprs" - - steps: - - uses: actions/checkout@v2 - - name: Setup Rust - run: | - rustup update nightly --no-self-update - rustup default nightly - - name: Detect AVX512 - run: echo "CPU_FEATURE=$(lscpu | grep -o avx512[a-z]* | sed s/avx/+avx/ | tr '\n' ',' )" >> $GITHUB_ENV - - name: Check build - if: ${{ matrix.simd == '' }} - run: RUSTFLAGS="-Dwarnings" cargo check --all-targets --no-default-features ${{ matrix.features }} - - name: Check AVX - if: ${{ matrix.simd == 'avx512' && contains(env.CPU_FEATURE, 'avx512') }} - run: | - echo "Found AVX features: $CPU_FEATURE" - RUSTFLAGS="-Dwarnings -Ctarget-feature=$CPU_FEATURE" cargo check --all-targets --no-default-features ${{ matrix.features }} diff --git a/library/portable-simd/.github/workflows/doc.yml b/library/portable-simd/.github/workflows/doc.yml deleted file mode 100644 index 9d1fa66ccb59..000000000000 --- a/library/portable-simd/.github/workflows/doc.yml +++ /dev/null @@ -1,30 +0,0 @@ -name: Documentation - -on: - push: - branches: - - master - -jobs: - release: - name: Deploy Documentation - runs-on: ubuntu-latest - - steps: - - name: Checkout Repository - uses: actions/checkout@v1 - - - name: Setup Rust - run: | - rustup update nightly --no-self-update - rustup default nightly - - - name: Build Documentation - run: cargo doc --no-deps - - - name: Deploy Documentation - uses: peaceiris/actions-gh-pages@v3 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_branch: gh-pages - publish_dir: ./target/doc diff --git a/src/tools/clippy/.github/ISSUE_TEMPLATE/blank_issue.yml b/src/tools/clippy/.github/ISSUE_TEMPLATE/blank_issue.yml deleted file mode 100644 index 89884bfc8590..000000000000 --- a/src/tools/clippy/.github/ISSUE_TEMPLATE/blank_issue.yml +++ /dev/null @@ -1,44 +0,0 @@ -name: Blank Issue -description: Create a blank issue. -body: - - type: markdown - attributes: - value: Thank you for filing an issue! - - type: textarea - id: problem - attributes: - label: Description - description: > - Please provide a description of the issue, along with any information - you feel relevant to replicate it. - validations: - required: true - - type: textarea - id: version - attributes: - label: Version - description: "Rust version (`rustc -Vv`)" - placeholder: | - rustc 1.46.0-nightly (f455e46ea 2020-06-20) - binary: rustc - commit-hash: f455e46eae1a227d735091091144601b467e1565 - commit-date: 2020-06-20 - host: x86_64-unknown-linux-gnu - release: 1.46.0-nightly - LLVM version: 10.0 - render: text - - type: textarea - id: labels - attributes: - label: Additional Labels - description: > - Additional labels can be added to this issue by including the following - command - placeholder: | - @rustbot label +