Auto merge of #78810 - JohnTitor:rollup-8fhtvxu, r=JohnTitor
Rollup of 15 pull requests Successful merges: - #74979 (`#![deny(unsafe_op_in_unsafe_fn)]` in sys/hermit) - #78006 (Use Intra-doc links for std::io::buffered) - #78167 (Fix unreachable sub-branch detection in or-patterns) - #78514 (Allow using 1/2/3/4 for `x.py setup` options) - #78538 (BTreeMap: document a curious assumption in test cases) - #78559 (Add LLVM upgrades from 7 to 10 to RELEASES.md) - #78666 (Fix shellcheck error) - #78705 (Print a summary of which test suite failed) - #78726 (Add link to rust website) - #78730 (Expand explanation of reverse_bits) - #78760 (`deny(invalid_codeblock_attributes)` for rustc_error_codes) - #78771 (inliner: Copy unevaluated constants only after successful inlining) - #78794 (rustc_expand: use collect_bang helper instead of manual reimplementation) - #78795 (The renumber pass is long gone) - #78798 (Fixing Spelling Typos) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
7e9a36fa8a
@ -297,6 +297,7 @@ Compiler
|
||||
- [Added the `tiny` value to the `code-model` codegen flag.][72397]
|
||||
- [Added tier 3 support\* for the `mipsel-sony-psp` target.][72062]
|
||||
- [Added tier 3 support for the `thumbv7a-uwp-windows-msvc` target.][72133]
|
||||
- [Upgraded to LLVM 10.][67759]
|
||||
|
||||
\* Refer to Rust's [platform support page][forge-platform-support] for more
|
||||
information on Rust's tiered platform support.
|
||||
@ -396,6 +397,7 @@ Internals Only
|
||||
[72062]: https://github.com/rust-lang/rust/pull/72062/
|
||||
[72094]: https://github.com/rust-lang/rust/pull/72094/
|
||||
[72133]: https://github.com/rust-lang/rust/pull/72133/
|
||||
[67759]: https://github.com/rust-lang/rust/pull/67759/
|
||||
[71900]: https://github.com/rust-lang/rust/pull/71900/
|
||||
[71928]: https://github.com/rust-lang/rust/pull/71928/
|
||||
[71662]: https://github.com/rust-lang/rust/pull/71662/
|
||||
@ -1270,6 +1272,7 @@ Compiler
|
||||
`armv7-unknown-linux-musleabi` targets.][63107]
|
||||
- [Added tier 3 support for the `hexagon-unknown-linux-musl` target.][62814]
|
||||
- [Added tier 3 support for the `riscv32i-unknown-none-elf` target.][62784]
|
||||
- [Upgraded to LLVM 9.][62592]
|
||||
|
||||
\* Refer to Rust's [platform support page][forge-platform-support] for more
|
||||
information on Rust's tiered platform support.
|
||||
@ -1336,6 +1339,7 @@ Compatibility Notes
|
||||
[62735]: https://github.com/rust-lang/rust/pull/62735/
|
||||
[62766]: https://github.com/rust-lang/rust/pull/62766/
|
||||
[62784]: https://github.com/rust-lang/rust/pull/62784/
|
||||
[62592]: https://github.com/rust-lang/rust/pull/62592/
|
||||
[62785]: https://github.com/rust-lang/rust/issues/62785/
|
||||
[62814]: https://github.com/rust-lang/rust/pull/62814/
|
||||
[62896]: https://github.com/rust-lang/rust/issues/62896/
|
||||
@ -2431,6 +2435,7 @@ Compiler
|
||||
--------
|
||||
- [Added the `riscv32imc-unknown-none-elf` target.][53822]
|
||||
- [Added the `aarch64-unknown-netbsd` target][53165]
|
||||
- [Upgraded to LLVM 8.][53611]
|
||||
|
||||
Libraries
|
||||
---------
|
||||
@ -2479,6 +2484,7 @@ Misc
|
||||
[53033]: https://github.com/rust-lang/rust/pull/53033/
|
||||
[53044]: https://github.com/rust-lang/rust/pull/53044/
|
||||
[53165]: https://github.com/rust-lang/rust/pull/53165/
|
||||
[53611]: https://github.com/rust-lang/rust/pull/53611/
|
||||
[53213]: https://github.com/rust-lang/rust/pull/53213/
|
||||
[53236]: https://github.com/rust-lang/rust/pull/53236/
|
||||
[53272]: https://github.com/rust-lang/rust/pull/53272/
|
||||
@ -2537,6 +2543,7 @@ Compiler
|
||||
- [Bumped minimum LLVM version to 5.0.][51899]
|
||||
- [Added `powerpc64le-unknown-linux-musl` target.][51619]
|
||||
- [Added `aarch64-unknown-hermit` and `x86_64-unknown-hermit` targets.][52861]
|
||||
- [Upgraded to LLVM 7.][51966]
|
||||
|
||||
Libraries
|
||||
---------
|
||||
@ -2588,6 +2595,7 @@ Compatibility Notes
|
||||
|
||||
[53893]: https://github.com/rust-lang/rust/pull/53893/
|
||||
[52861]: https://github.com/rust-lang/rust/pull/52861/
|
||||
[51966]: https://github.com/rust-lang/rust/pull/51966/
|
||||
[52656]: https://github.com/rust-lang/rust/pull/52656/
|
||||
[52239]: https://github.com/rust-lang/rust/pull/52239/
|
||||
[52330]: https://github.com/rust-lang/rust/pull/52330/
|
||||
|
@ -13,8 +13,8 @@ rustc_data_structures::define_id_collections!(NodeMap, NodeSet, NodeId);
|
||||
pub const CRATE_NODE_ID: NodeId = NodeId::from_u32(0);
|
||||
|
||||
/// When parsing and doing expansions, we initially give all AST nodes this AST
|
||||
/// node value. Then later, in the renumber pass, we renumber them to have
|
||||
/// small, positive ids.
|
||||
/// node value. Then later, during expansion, we renumber them to have small,
|
||||
/// positive ids.
|
||||
pub const DUMMY_NODE_ID: NodeId = NodeId::MAX;
|
||||
|
||||
impl NodeId {
|
||||
|
@ -10,7 +10,7 @@ cmd=$1
|
||||
shift || true
|
||||
|
||||
if [[ "$cmd" = "jit" ]]; then
|
||||
cargo +${TOOLCHAIN} rustc $@ -- --jit
|
||||
cargo +${TOOLCHAIN} rustc "$@" -- --jit
|
||||
else
|
||||
cargo +${TOOLCHAIN} $cmd $@
|
||||
cargo +${TOOLCHAIN} $cmd "$@"
|
||||
fi
|
||||
|
@ -1,3 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
unamestr=`uname`
|
||||
|
@ -3,13 +3,13 @@ set -e
|
||||
|
||||
export RUSTFLAGS="-Zrun_dsymutil=no"
|
||||
|
||||
./build.sh --without-sysroot $@
|
||||
./build.sh --without-sysroot "$@"
|
||||
|
||||
rm -r target/out || true
|
||||
|
||||
scripts/tests.sh no_sysroot
|
||||
|
||||
./build.sh $@
|
||||
./build.sh "$@"
|
||||
|
||||
scripts/tests.sh base_sysroot
|
||||
scripts/tests.sh extended_sysroot
|
||||
|
@ -1,3 +1,4 @@
|
||||
#![deny(invalid_codeblock_attributes)]
|
||||
//! This library is used to gather all error codes into one place,
|
||||
//! the goal being to make their maintenance easier.
|
||||
|
||||
|
@ -1436,9 +1436,9 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
|
||||
item.attrs = attrs;
|
||||
self.check_attributes(&item.attrs);
|
||||
item.and_then(|item| match item.kind {
|
||||
ItemKind::MacCall(mac) => self
|
||||
.collect(AstFragmentKind::Items, InvocationKind::Bang { mac, span })
|
||||
.make_items(),
|
||||
ItemKind::MacCall(mac) => {
|
||||
self.collect_bang(mac, span, AstFragmentKind::Items).make_items()
|
||||
}
|
||||
_ => unreachable!(),
|
||||
})
|
||||
}
|
||||
|
@ -693,7 +693,7 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
||||
// should only issue a warning for the sake of backwards compatibility.
|
||||
//
|
||||
// The solution those 2 expectations is to always take the minimum of both lints.
|
||||
// This prevent any new errors (unless both lints are explicitely set to `deny`).
|
||||
// This prevent any new errors (unless both lints are explicitly set to `deny`).
|
||||
let lint = if tcx.lint_level_at_node(SAFE_PACKED_BORROWS, lint_root).0
|
||||
<= tcx.lint_level_at_node(UNSAFE_OP_IN_UNSAFE_FN, lint_root).0
|
||||
{
|
||||
|
@ -140,14 +140,6 @@ impl Inliner<'tcx> {
|
||||
continue;
|
||||
};
|
||||
|
||||
// Copy only unevaluated constants from the callee_body into the caller_body.
|
||||
// Although we are only pushing `ConstKind::Unevaluated` consts to
|
||||
// `required_consts`, here we may not only have `ConstKind::Unevaluated`
|
||||
// because we are calling `subst_and_normalize_erasing_regions`.
|
||||
caller_body.required_consts.extend(callee_body.required_consts.iter().copied().filter(
|
||||
|&constant| matches!(constant.literal.val, ConstKind::Unevaluated(_, _, _)),
|
||||
));
|
||||
|
||||
let start = caller_body.basic_blocks().len();
|
||||
debug!("attempting to inline callsite {:?} - body={:?}", callsite, callee_body);
|
||||
if !self.inline_call(callsite, caller_body, callee_body) {
|
||||
@ -522,6 +514,16 @@ impl Inliner<'tcx> {
|
||||
kind: TerminatorKind::Goto { target: integrator.map_block(START_BLOCK) },
|
||||
});
|
||||
|
||||
// Copy only unevaluated constants from the callee_body into the caller_body.
|
||||
// Although we are only pushing `ConstKind::Unevaluated` consts to
|
||||
// `required_consts`, here we may not only have `ConstKind::Unevaluated`
|
||||
// because we are calling `subst_and_normalize_erasing_regions`.
|
||||
caller_body.required_consts.extend(
|
||||
callee_body.required_consts.iter().copied().filter(|&constant| {
|
||||
matches!(constant.literal.val, ConstKind::Unevaluated(_, _, _))
|
||||
}),
|
||||
);
|
||||
|
||||
true
|
||||
}
|
||||
kind => {
|
||||
|
@ -1,5 +1,11 @@
|
||||
//! Note: most of the tests relevant to this file can be found (at the time of writing) in
|
||||
//! src/tests/ui/pattern/usefulness.
|
||||
//! Note: tests specific to this file can be found in:
|
||||
//! - ui/pattern/usefulness
|
||||
//! - ui/or-patterns
|
||||
//! - ui/consts/const_in_pattern
|
||||
//! - ui/rfc-2008-non-exhaustive
|
||||
//! - probably many others
|
||||
//! I (Nadrieril) prefer to put new tests in `ui/pattern/usefulness` unless there's a specific
|
||||
//! reason not to, for example if they depend on a particular feature like or_patterns.
|
||||
//!
|
||||
//! This file includes the logic for exhaustiveness and usefulness checking for
|
||||
//! pattern-matching. Specifically, given a list of patterns for a type, we can
|
||||
@ -1361,8 +1367,9 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
crate enum Usefulness<'tcx> {
|
||||
/// Carries a list of unreachable subpatterns. Used only in the presence of or-patterns.
|
||||
Useful(Vec<Span>),
|
||||
/// Carries, for each column in the matrix, a set of sub-branches that have been found to be
|
||||
/// unreachable. Used only in the presence of or-patterns, otherwise it stays empty.
|
||||
Useful(Vec<FxHashSet<Span>>),
|
||||
/// Carries a list of witnesses of non-exhaustiveness.
|
||||
UsefulWithWitness(Vec<Witness<'tcx>>),
|
||||
NotUseful,
|
||||
@ -1410,6 +1417,23 @@ impl<'tcx> Usefulness<'tcx> {
|
||||
};
|
||||
UsefulWithWitness(new_witnesses)
|
||||
}
|
||||
Useful(mut unreachables) => {
|
||||
if !unreachables.is_empty() {
|
||||
// When we apply a constructor, there are `arity` columns of the matrix that
|
||||
// corresponded to its arguments. All the unreachables found in these columns
|
||||
// will, after `apply`, come from the first column. So we take the union of all
|
||||
// the corresponding sets and put them in the first column.
|
||||
// Note that `arity` may be 0, in which case we just push a new empty set.
|
||||
let len = unreachables.len();
|
||||
let arity = ctor_wild_subpatterns.len();
|
||||
let mut unioned = FxHashSet::default();
|
||||
for set in unreachables.drain((len - arity)..) {
|
||||
unioned.extend(set)
|
||||
}
|
||||
unreachables.push(unioned);
|
||||
}
|
||||
Useful(unreachables)
|
||||
}
|
||||
x => x,
|
||||
}
|
||||
}
|
||||
@ -2091,13 +2115,14 @@ crate fn is_useful<'p, 'tcx>(
|
||||
|
||||
// If the first pattern is an or-pattern, expand it.
|
||||
if let Some(vs) = v.expand_or_pat() {
|
||||
// We need to push the already-seen patterns into the matrix in order to detect redundant
|
||||
// branches like `Some(_) | Some(0)`. We also keep track of the unreachable subpatterns.
|
||||
let mut matrix = matrix.clone();
|
||||
// `Vec` of all the unreachable branches of the current or-pattern.
|
||||
let mut unreachable_branches = Vec::new();
|
||||
// Subpatterns that are unreachable from all branches. E.g. in the following case, the last
|
||||
// `true` is unreachable only from one branch, so it is overall reachable.
|
||||
// We expand the or pattern, trying each of its branches in turn and keeping careful track
|
||||
// of possible unreachable sub-branches.
|
||||
//
|
||||
// If two branches have detected some unreachable sub-branches, we need to be careful. If
|
||||
// they were detected in columns that are not the current one, we want to keep only the
|
||||
// sub-branches that were unreachable in _all_ branches. Eg. in the following, the last
|
||||
// `true` is unreachable in the second branch of the first or-pattern, but not otherwise.
|
||||
// Therefore we don't want to lint that it is unreachable.
|
||||
//
|
||||
// ```
|
||||
// match (true, true) {
|
||||
@ -2105,41 +2130,72 @@ crate fn is_useful<'p, 'tcx>(
|
||||
// (false | true, false | true) => {}
|
||||
// }
|
||||
// ```
|
||||
let mut unreachable_subpats = FxHashSet::default();
|
||||
// Whether any branch at all is useful.
|
||||
// If however the sub-branches come from the current column, they come from the inside of
|
||||
// the current or-pattern, and we want to keep them all. Eg. in the following, we _do_ want
|
||||
// to lint that the last `false` is unreachable.
|
||||
// ```
|
||||
// match None {
|
||||
// Some(false) => {}
|
||||
// None | Some(true | false) => {}
|
||||
// }
|
||||
// ```
|
||||
|
||||
let mut matrix = matrix.clone();
|
||||
// We keep track of sub-branches separately depending on whether they come from this column
|
||||
// or from others.
|
||||
let mut unreachables_this_column: FxHashSet<Span> = FxHashSet::default();
|
||||
let mut unreachables_other_columns: Vec<FxHashSet<Span>> = Vec::default();
|
||||
// Whether at least one branch is reachable.
|
||||
let mut any_is_useful = false;
|
||||
|
||||
for v in vs {
|
||||
let res = is_useful(cx, &matrix, &v, witness_preference, hir_id, is_under_guard, false);
|
||||
match res {
|
||||
Useful(pats) => {
|
||||
if !any_is_useful {
|
||||
any_is_useful = true;
|
||||
// Initialize with the first set of unreachable subpatterns encountered.
|
||||
unreachable_subpats = pats.into_iter().collect();
|
||||
} else {
|
||||
// Keep the patterns unreachable from both this and previous branches.
|
||||
unreachable_subpats =
|
||||
pats.into_iter().filter(|p| unreachable_subpats.contains(p)).collect();
|
||||
Useful(unreachables) => {
|
||||
if let Some((this_column, other_columns)) = unreachables.split_last() {
|
||||
// We keep the union of unreachables found in the first column.
|
||||
unreachables_this_column.extend(this_column);
|
||||
// We keep the intersection of unreachables found in other columns.
|
||||
if unreachables_other_columns.is_empty() {
|
||||
unreachables_other_columns = other_columns.to_vec();
|
||||
} else {
|
||||
unreachables_other_columns = unreachables_other_columns
|
||||
.into_iter()
|
||||
.zip(other_columns)
|
||||
.map(|(x, y)| x.intersection(&y).copied().collect())
|
||||
.collect();
|
||||
}
|
||||
}
|
||||
any_is_useful = true;
|
||||
}
|
||||
NotUseful => unreachable_branches.push(v.head().span),
|
||||
UsefulWithWitness(_) => {
|
||||
bug!("Encountered or-pat in `v` during exhaustiveness checking")
|
||||
NotUseful => {
|
||||
unreachables_this_column.insert(v.head().span);
|
||||
}
|
||||
UsefulWithWitness(_) => bug!(
|
||||
"encountered or-pat in the expansion of `_` during exhaustiveness checking"
|
||||
),
|
||||
}
|
||||
// If pattern has a guard don't add it to the matrix
|
||||
|
||||
// If pattern has a guard don't add it to the matrix.
|
||||
if !is_under_guard {
|
||||
// We push the already-seen patterns into the matrix in order to detect redundant
|
||||
// branches like `Some(_) | Some(0)`.
|
||||
matrix.push(v);
|
||||
}
|
||||
}
|
||||
if any_is_useful {
|
||||
// Collect all the unreachable patterns.
|
||||
unreachable_branches.extend(unreachable_subpats);
|
||||
return Useful(unreachable_branches);
|
||||
|
||||
return if any_is_useful {
|
||||
let mut unreachables = if unreachables_other_columns.is_empty() {
|
||||
let n_columns = v.len();
|
||||
(0..n_columns - 1).map(|_| FxHashSet::default()).collect()
|
||||
} else {
|
||||
unreachables_other_columns
|
||||
};
|
||||
unreachables.push(unreachables_this_column);
|
||||
Useful(unreachables)
|
||||
} else {
|
||||
return NotUseful;
|
||||
}
|
||||
NotUseful
|
||||
};
|
||||
}
|
||||
|
||||
// FIXME(Nadrieril): Hack to work around type normalization issues (see #72476).
|
||||
|
@ -389,8 +389,11 @@ fn check_arms<'p, 'tcx>(
|
||||
hir::MatchSource::AwaitDesugar | hir::MatchSource::TryDesugar => {}
|
||||
}
|
||||
}
|
||||
Useful(unreachable_subpatterns) => {
|
||||
for span in unreachable_subpatterns {
|
||||
Useful(unreachables) => {
|
||||
let mut unreachables: Vec<_> = unreachables.into_iter().flatten().collect();
|
||||
// Emit lints in the order in which they occur in the file.
|
||||
unreachables.sort_unstable();
|
||||
for span in unreachables {
|
||||
unreachable_pattern(cx.tcx, span, id, None);
|
||||
}
|
||||
}
|
||||
|
@ -1500,7 +1500,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
err.span_suggestion(
|
||||
sp,
|
||||
&format!(
|
||||
"if you don't care about {} missing field{}, you can explicitely ignore {}",
|
||||
"if you don't care about {} missing field{}, you can explicitly ignore {}",
|
||||
if len == 1 { "this" } else { "these" },
|
||||
if len == 1 { "" } else { "s" },
|
||||
if len == 1 { "it" } else { "them" },
|
||||
|
@ -1668,6 +1668,7 @@ create_append_test!(test_append_239, 239);
|
||||
create_append_test!(test_append_1700, 1700);
|
||||
|
||||
fn rand_data(len: usize) -> Vec<(u32, u32)> {
|
||||
assert!(len * 2 <= 70029); // from that point on numbers repeat
|
||||
let mut rng = DeterministicRng::new();
|
||||
Vec::from_iter((0..len).map(|_| (rng.next(), rng.next())))
|
||||
}
|
||||
|
@ -49,6 +49,7 @@ impl DeterministicRng {
|
||||
DeterministicRng { x: 0x193a6754, y: 0xa8a7d469, z: 0x97830e05, w: 0x113ba7bb }
|
||||
}
|
||||
|
||||
/// Guarantees that the first 70029 results are unique.
|
||||
fn next(&mut self) -> u32 {
|
||||
let x = self.x;
|
||||
let t = x ^ (x << 11);
|
||||
|
@ -687,6 +687,7 @@ fn test_first_last() {
|
||||
}
|
||||
|
||||
fn rand_data(len: usize) -> Vec<u32> {
|
||||
assert!(len <= 70029); // from that point on numbers repeat
|
||||
let mut rng = DeterministicRng::new();
|
||||
Vec::from_iter((0..len).map(|_| rng.next()))
|
||||
}
|
||||
|
@ -274,7 +274,8 @@ assert_eq!(m, ", $swapped, ");
|
||||
}
|
||||
|
||||
doc_comment! {
|
||||
concat!("Reverses the bit pattern of the integer.
|
||||
concat!("Reverses the order of bits in the integer. The least significant bit becomes the most significant bit,
|
||||
second least-significant bit becomes second most-significant bit, etc.
|
||||
|
||||
# Examples
|
||||
|
||||
@ -285,6 +286,7 @@ let n = ", $swap_op, stringify!($SelfT), ";
|
||||
let m = n.reverse_bits();
|
||||
|
||||
assert_eq!(m, ", $reversed, ");
|
||||
assert_eq!(0, 0", stringify!($SelfT), ".reverse_bits());
|
||||
```"),
|
||||
#[stable(feature = "reverse_bits", since = "1.37.0")]
|
||||
#[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
|
||||
|
@ -272,7 +272,8 @@ assert_eq!(m, ", $swapped, ");
|
||||
}
|
||||
|
||||
doc_comment! {
|
||||
concat!("Reverses the bit pattern of the integer.
|
||||
concat!("Reverses the order of bits in the integer. The least significant bit becomes the most significant bit,
|
||||
second least-significant bit becomes second most-significant bit, etc.
|
||||
|
||||
# Examples
|
||||
|
||||
@ -283,6 +284,7 @@ let n = ", $swap_op, stringify!($SelfT), ";
|
||||
let m = n.reverse_bits();
|
||||
|
||||
assert_eq!(m, ", $reversed, ");
|
||||
assert_eq!(0, 0", stringify!($SelfT), ".reverse_bits());
|
||||
```"),
|
||||
#[stable(feature = "reverse_bits", since = "1.37.0")]
|
||||
#[rustc_const_stable(feature = "const_math", since = "1.32.0")]
|
||||
|
@ -21,7 +21,8 @@ use crate::io::{self, BufRead, Initializer, IoSliceMut, Read, Seek, SeekFrom, DE
|
||||
/// unwrapping the `BufReader<R>` with [`BufReader::into_inner`] can also cause
|
||||
/// data loss.
|
||||
///
|
||||
/// [`TcpStream::read`]: Read::read
|
||||
// HACK(#78696): can't use `crate` for associated items
|
||||
/// [`TcpStream::read`]: super::super::super::net::TcpStream::read
|
||||
/// [`TcpStream`]: crate::net::TcpStream
|
||||
///
|
||||
/// # Examples
|
||||
|
@ -59,9 +59,10 @@ use crate::io::{
|
||||
/// together by the buffer and will all be written out in one system call when
|
||||
/// the `stream` is flushed.
|
||||
///
|
||||
/// [`TcpStream::write`]: Write::write
|
||||
// HACK(#78696): can't use `crate` for associated items
|
||||
/// [`TcpStream::write`]: super::super::super::net::TcpStream::write
|
||||
/// [`TcpStream`]: crate::net::TcpStream
|
||||
/// [`flush`]: Write::flush
|
||||
/// [`flush`]: BufWriter::flush
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct BufWriter<W: Write> {
|
||||
inner: Option<W>,
|
||||
|
@ -13,6 +13,8 @@
|
||||
//! compiling for wasm. That way it's a compile time error for something that's
|
||||
//! guaranteed to be a runtime error!
|
||||
|
||||
#![allow(unsafe_op_in_unsafe_fn)]
|
||||
|
||||
use crate::intrinsics;
|
||||
use crate::os::raw::c_char;
|
||||
|
||||
|
@ -127,14 +127,17 @@ pub fn setup(src_path: &Path, profile: Profile) {
|
||||
|
||||
// Used to get the path for `Subcommand::Setup`
|
||||
pub fn interactive_path() -> io::Result<Profile> {
|
||||
fn abbrev_all() -> impl Iterator<Item = (String, Profile)> {
|
||||
('a'..).map(|c| c.to_string()).zip(Profile::all())
|
||||
fn abbrev_all() -> impl Iterator<Item = ((String, String), Profile)> {
|
||||
('a'..)
|
||||
.zip(1..)
|
||||
.map(|(letter, number)| (letter.to_string(), number.to_string()))
|
||||
.zip(Profile::all())
|
||||
}
|
||||
|
||||
fn parse_with_abbrev(input: &str) -> Result<Profile, String> {
|
||||
let input = input.trim().to_lowercase();
|
||||
for (letter, profile) in abbrev_all() {
|
||||
if input == letter {
|
||||
for ((letter, number), profile) in abbrev_all() {
|
||||
if input == letter || input == number {
|
||||
return Ok(profile);
|
||||
}
|
||||
}
|
||||
@ -142,13 +145,13 @@ pub fn interactive_path() -> io::Result<Profile> {
|
||||
}
|
||||
|
||||
println!("Welcome to the Rust project! What do you want to do with x.py?");
|
||||
for (letter, profile) in abbrev_all() {
|
||||
for ((letter, _), profile) in abbrev_all() {
|
||||
println!("{}) {}: {}", letter, profile, profile.purpose());
|
||||
}
|
||||
let template = loop {
|
||||
print!(
|
||||
"Please choose one ({}): ",
|
||||
abbrev_all().map(|(l, _)| l).collect::<Vec<_>>().join("/")
|
||||
abbrev_all().map(|((l, _), _)| l).collect::<Vec<_>>().join("/")
|
||||
);
|
||||
io::stdout().flush()?;
|
||||
let mut input = String::new();
|
||||
|
@ -1040,6 +1040,7 @@ note: if you're sure you want to do this, please open an issue as to why. In the
|
||||
cmd.arg("--src-base").arg(builder.src.join("src/test").join(suite));
|
||||
cmd.arg("--build-base").arg(testdir(builder, compiler.host).join(suite));
|
||||
cmd.arg("--stage-id").arg(format!("stage{}-{}", compiler.stage, target));
|
||||
cmd.arg("--suite").arg(suite);
|
||||
cmd.arg("--mode").arg(mode);
|
||||
cmd.arg("--target").arg(target.rustc_target_arg());
|
||||
cmd.arg("--host").arg(&*compiler.host.triple);
|
||||
|
@ -17,7 +17,7 @@ exit 1
|
||||
trap "$on_err" ERR
|
||||
bash -c "while true; do sleep 30; echo \$(date) - building ...; done" &
|
||||
PING_LOOP_PID=$!
|
||||
$@ &> /tmp/build.log
|
||||
"$@" &> /tmp/build.log
|
||||
trap - ERR
|
||||
kill $PING_LOOP_PID
|
||||
set -x
|
||||
|
@ -22,7 +22,7 @@ exit 1
|
||||
trap "$on_err" ERR
|
||||
bash -c "while true; do sleep 30; echo \$(date) - building ...; done" &
|
||||
PING_LOOP_PID=$!
|
||||
$@ &> /tmp/build.log
|
||||
"$@" &> /tmp/build.log
|
||||
trap - ERR
|
||||
kill $PING_LOOP_PID
|
||||
set -x
|
||||
|
@ -11,7 +11,7 @@ exit 1
|
||||
trap "$on_err" ERR
|
||||
bash -c "while true; do sleep 30; echo \$(date) - building ...; done" &
|
||||
PING_LOOP_PID=$!
|
||||
$@ &> /tmp/build.log
|
||||
"$@" &> /tmp/build.log
|
||||
rm /tmp/build.log
|
||||
trap - ERR
|
||||
kill $PING_LOOP_PID
|
||||
|
@ -12,7 +12,7 @@ exit 1
|
||||
trap "$on_err" ERR
|
||||
bash -c "while true; do sleep 30; echo \$(date) - building ...; done" &
|
||||
PING_LOOP_PID=$!
|
||||
$@ &> /tmp/build.log
|
||||
"$@" &> /tmp/build.log
|
||||
rm /tmp/build.log
|
||||
trap - ERR
|
||||
kill $PING_LOOP_PID
|
||||
|
@ -12,7 +12,7 @@ exit 1
|
||||
trap "$on_err" ERR
|
||||
bash -c "while true; do sleep 30; echo \$(date) - building ...; done" &
|
||||
PING_LOOP_PID=$!
|
||||
$@ &> /tmp/build.log
|
||||
"$@" &> /tmp/build.log
|
||||
rm /tmp/build.log
|
||||
trap - ERR
|
||||
kill $PING_LOOP_PID
|
||||
|
@ -12,7 +12,7 @@ exit 1
|
||||
trap "$on_err" ERR
|
||||
bash -c "while true; do sleep 30; echo \$(date) - building ...; done" &
|
||||
PING_LOOP_PID=$!
|
||||
$@ &> /tmp/build.log
|
||||
"$@" &> /tmp/build.log
|
||||
rm /tmp/build.log
|
||||
trap - ERR
|
||||
kill $PING_LOOP_PID
|
||||
|
@ -11,7 +11,7 @@ exit 1
|
||||
trap "$on_err" ERR
|
||||
bash -c "while true; do sleep 30; echo \$(date) - building ...; done" &
|
||||
PING_LOOP_PID=$!
|
||||
$@ &> /tmp/build.log
|
||||
"$@" &> /tmp/build.log
|
||||
rm /tmp/build.log
|
||||
trap - ERR
|
||||
kill $PING_LOOP_PID
|
||||
|
@ -1,3 +1,4 @@
|
||||
#!/bin/sh
|
||||
hide_output() {
|
||||
set +x
|
||||
on_err="
|
||||
@ -8,7 +9,7 @@ exit 1
|
||||
trap "$on_err" ERR
|
||||
bash -c "while true; do sleep 30; echo \$(date) - building ...; done" &
|
||||
PING_LOOP_PID=$!
|
||||
$@ &> /tmp/build.log
|
||||
"$@" &> /tmp/build.log
|
||||
trap - ERR
|
||||
kill $PING_LOOP_PID
|
||||
set -x
|
||||
|
@ -1,3 +1,4 @@
|
||||
#!/bin/sh
|
||||
hide_output() {
|
||||
set +x
|
||||
on_err="
|
||||
@ -8,7 +9,7 @@ exit 1
|
||||
trap "$on_err" ERR
|
||||
bash -c "while true; do sleep 30; echo \$(date) - building ...; done" &
|
||||
PING_LOOP_PID=$!
|
||||
$@ &> /tmp/build.log
|
||||
"$@" &> /tmp/build.log
|
||||
trap - ERR
|
||||
kill $PING_LOOP_PID
|
||||
set -x
|
||||
|
@ -12,7 +12,7 @@ exit 1
|
||||
trap "$on_err" ERR
|
||||
bash -c "while true; do sleep 30; echo \$(date) - building ...; done" &
|
||||
PING_LOOP_PID=$!
|
||||
$@ &> /tmp/build.log
|
||||
"$@" &> /tmp/build.log
|
||||
rm /tmp/build.log
|
||||
trap - ERR
|
||||
kill $PING_LOOP_PID
|
||||
|
@ -1,3 +1,4 @@
|
||||
#!/bin/sh
|
||||
set -ex
|
||||
|
||||
# Mirrored from https://github.com/crosstool-ng/crosstool-ng/archive/crosstool-ng-1.24.0.tar.gz
|
||||
|
@ -11,7 +11,7 @@ exit 1
|
||||
trap "$on_err" ERR
|
||||
bash -c "while true; do sleep 30; echo \$(date) - building ...; done" &
|
||||
PING_LOOP_PID=$!
|
||||
$@ &> /tmp/build.log
|
||||
"$@" &> /tmp/build.log
|
||||
rm /tmp/build.log
|
||||
trap - ERR
|
||||
kill $PING_LOOP_PID
|
||||
|
@ -11,7 +11,7 @@ exit 1
|
||||
trap "$on_err" ERR
|
||||
bash -c "while true; do sleep 30; echo \$(date) - building ...; done" &
|
||||
PING_LOOP_PID=$!
|
||||
$@ &> /tmp/build.log
|
||||
"$@" &> /tmp/build.log
|
||||
trap - ERR
|
||||
kill $PING_LOOP_PID
|
||||
rm /tmp/build.log
|
||||
|
@ -1,3 +1,4 @@
|
||||
#!/bin/sh
|
||||
set -ex
|
||||
|
||||
mkdir /usr/local/mips-linux-musl
|
||||
|
@ -1,3 +1,4 @@
|
||||
#!/bin/sh
|
||||
set -ex
|
||||
|
||||
mkdir /usr/local/mipsel-linux-musl
|
||||
|
@ -1,3 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
hide_output() {
|
||||
{ set +x; } 2>/dev/null
|
||||
on_err="
|
||||
|
@ -1,3 +1,4 @@
|
||||
#!/bin/sh
|
||||
hide_output() {
|
||||
set +x
|
||||
on_err="
|
||||
@ -8,7 +9,7 @@ exit 1
|
||||
trap "$on_err" ERR
|
||||
bash -c "while true; do sleep 30; echo \$(date) - building ...; done" &
|
||||
PING_LOOP_PID=$!
|
||||
$@ &> /tmp/build.log
|
||||
"$@" &> /tmp/build.log
|
||||
trap - ERR
|
||||
kill $PING_LOOP_PID
|
||||
set -x
|
||||
|
@ -13,7 +13,7 @@ exit 1
|
||||
trap "$on_err" ERR
|
||||
bash -c "while true; do sleep 30; echo \$(date) - building ...; done" &
|
||||
PING_LOOP_PID=$!
|
||||
$@ &> /tmp/build.log
|
||||
"$@" &> /tmp/build.log
|
||||
rm /tmp/build.log
|
||||
trap - ERR
|
||||
kill $PING_LOOP_PID
|
||||
|
@ -1,3 +1,4 @@
|
||||
#!/bin/sh
|
||||
set -ex
|
||||
|
||||
apt-get update
|
||||
|
@ -1,3 +1,4 @@
|
||||
#!/bin/sh
|
||||
set -ex
|
||||
|
||||
URL=https://dl.google.com/android/repository
|
||||
|
@ -1,3 +1,4 @@
|
||||
#!/bin/sh
|
||||
set -ex
|
||||
|
||||
export ANDROID_HOME=/android/sdk
|
||||
|
@ -1,3 +1,4 @@
|
||||
#!/bin/sh
|
||||
apt-get update && apt-get install -y --no-install-recommends \
|
||||
automake \
|
||||
bison \
|
||||
|
@ -1,3 +1,4 @@
|
||||
#!/bin/sh
|
||||
set -ex
|
||||
|
||||
# Mirrored from https://github.com/crosstool-ng/crosstool-ng/archive/crosstool-ng-1.24.0.tar.gz
|
||||
|
@ -1,3 +1,4 @@
|
||||
#!/bin/sh
|
||||
set -ex
|
||||
|
||||
url="https://github.com/crosstool-ng/crosstool-ng/archive/crosstool-ng-1.22.0.tar.gz"
|
||||
|
@ -1,3 +1,4 @@
|
||||
#!/bin/sh
|
||||
set -ex
|
||||
|
||||
hide_output() {
|
||||
@ -10,7 +11,7 @@ exit 1
|
||||
trap "$on_err" ERR
|
||||
bash -c "while true; do sleep 30; echo \$(date) - building ...; done" &
|
||||
PING_LOOP_PID=$!
|
||||
$@ &> /tmp/build.log
|
||||
"$@" &> /tmp/build.log
|
||||
trap - ERR
|
||||
kill $PING_LOOP_PID
|
||||
rm -f /tmp/build.log
|
||||
|
@ -19,7 +19,7 @@ exit 1
|
||||
trap "$on_err" ERR
|
||||
bash -c "while true; do sleep 30; echo \$(date) - building ...; done" &
|
||||
local ping_loop_pid=$!
|
||||
$@ &> /tmp/build.log
|
||||
"$@" &> /tmp/build.log
|
||||
trap - ERR
|
||||
kill $ping_loop_pid
|
||||
set -x
|
||||
|
@ -1,3 +1,4 @@
|
||||
#!/bin/sh
|
||||
set -ex
|
||||
|
||||
curl -f https://ftp.gnu.org/gnu/make/make-3.81.tar.gz | tar xzf -
|
||||
|
@ -1,3 +1,4 @@
|
||||
#!/bin/sh
|
||||
# This script runs `musl-cross-make` to prepare C toolchain (Binutils, GCC, musl itself)
|
||||
# and builds static libunwind that we distribute for static target.
|
||||
#
|
||||
@ -19,7 +20,7 @@ exit 1
|
||||
trap "$on_err" ERR
|
||||
bash -c "while true; do sleep 30; echo \$(date) - building ...; done" &
|
||||
PING_LOOP_PID=$!
|
||||
$@ &> /tmp/build.log
|
||||
"$@" &> /tmp/build.log
|
||||
trap - ERR
|
||||
kill $PING_LOOP_PID
|
||||
rm /tmp/build.log
|
||||
|
@ -1,3 +1,4 @@
|
||||
#!/bin/sh
|
||||
set -ex
|
||||
|
||||
hide_output() {
|
||||
@ -10,7 +11,7 @@ exit 1
|
||||
trap "$on_err" ERR
|
||||
bash -c "while true; do sleep 30; echo \$(date) - building ...; done" &
|
||||
PING_LOOP_PID=$!
|
||||
$@ &> /tmp/build.log
|
||||
"$@" &> /tmp/build.log
|
||||
trap - ERR
|
||||
kill $PING_LOOP_PID
|
||||
rm /tmp/build.log
|
||||
@ -32,7 +33,7 @@ if [ ! -d $MUSL ]; then
|
||||
fi
|
||||
|
||||
cd $MUSL
|
||||
./configure --enable-optimize --enable-debug --disable-shared --prefix=/musl-$TAG $@
|
||||
./configure --enable-optimize --enable-debug --disable-shared --prefix=/musl-$TAG "$@"
|
||||
if [ "$TAG" = "i586" -o "$TAG" = "i686" ]; then
|
||||
hide_output make -j$(nproc) AR=ar RANLIB=ranlib
|
||||
else
|
||||
|
@ -1,3 +1,4 @@
|
||||
#!/bin/sh
|
||||
set -ex
|
||||
|
||||
groupadd -r rustbuild && useradd -m -r -g rustbuild rustbuild
|
||||
|
@ -1,3 +1,4 @@
|
||||
#!/bin/sh
|
||||
set -ex
|
||||
|
||||
case "$(uname -m)" in
|
||||
|
@ -53,6 +53,7 @@ modules=($modules)
|
||||
use_git=""
|
||||
urls="$(git config --file .gitmodules --get-regexp '\.url$' | cut -d' ' -f2)"
|
||||
urls=($urls)
|
||||
# shellcheck disable=SC2068
|
||||
for i in ${!modules[@]}; do
|
||||
module=${modules[$i]}
|
||||
if [[ " $included " = *" $module "* ]]; then
|
||||
|
@ -1,4 +1,5 @@
|
||||
#!/bin/false
|
||||
# shellcheck shell=bash
|
||||
|
||||
# This file is intended to be sourced with `. shared.sh` or
|
||||
# `source shared.sh`, hence the invalid shebang and not being
|
||||
|
@ -26,7 +26,7 @@ h2 {
|
||||
}
|
||||
</style>
|
||||
|
||||
Welcome to an overview of the documentation provided by the Rust project.
|
||||
Welcome to an overview of the documentation provided by the [Rust project].
|
||||
All of these projects are managed by the Docs Team; there are other
|
||||
unofficial documentation resources as well!
|
||||
|
||||
@ -139,3 +139,4 @@ When developing for Bare Metal or Embedded Linux systems, you may find these res
|
||||
[The Embedded Rust Book] is targeted at developers familiar with embedded development and familiar with Rust, but have not used Rust for embedded development.
|
||||
|
||||
[The Embedded Rust Book]: embedded-book/index.html
|
||||
[Rust project]: https://www.rust-lang.org
|
||||
|
@ -1,3 +1,4 @@
|
||||
#!/bin/sh
|
||||
set -exuo pipefail
|
||||
|
||||
CRATE=example
|
||||
|
@ -1,3 +1,4 @@
|
||||
#!/bin/sh
|
||||
set -exuo pipefail
|
||||
|
||||
function build {
|
||||
|
@ -8,7 +8,7 @@ help: include the missing field in the pattern
|
||||
|
|
||||
LL | Dog { age: x, name } => {}
|
||||
| ^^^^^^
|
||||
help: if you don't care about this missing field, you can explicitely ignore it
|
||||
help: if you don't care about this missing field, you can explicitly ignore it
|
||||
|
|
||||
LL | Dog { age: x, .. } => {}
|
||||
| ^^^^
|
||||
@ -23,7 +23,7 @@ help: include the missing fields in the pattern
|
||||
|
|
||||
LL | Dog { name, age } => {}
|
||||
| ^^^^^^^^^^^^^
|
||||
help: if you don't care about these missing fields, you can explicitely ignore them
|
||||
help: if you don't care about these missing fields, you can explicitly ignore them
|
||||
|
|
||||
LL | Dog { .. } => {}
|
||||
| ^^^^^^
|
||||
|
@ -77,10 +77,17 @@ fn main() {
|
||||
(false | true, false | true) => {}
|
||||
}
|
||||
match (true, true) {
|
||||
(true, false) => {}
|
||||
(false, true) => {}
|
||||
(true, true) => {}
|
||||
(false, false) => {}
|
||||
(false | true, false | true) => {}
|
||||
}
|
||||
// https://github.com/rust-lang/rust/issues/76836
|
||||
match None {
|
||||
Some(false) => {}
|
||||
None | Some(true
|
||||
| false) => {} //~ ERROR unreachable
|
||||
}
|
||||
|
||||
// A subpattern that is unreachable in all branches is overall unreachable.
|
||||
match (true, true) {
|
||||
(false, true) => {}
|
||||
|
@ -101,16 +101,22 @@ LL | Some(0
|
||||
| ^
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/exhaustiveness-unreachable-pattern.rs:89:15
|
||||
--> $DIR/exhaustiveness-unreachable-pattern.rs:88:19
|
||||
|
|
||||
LL | | false) => {}
|
||||
| ^^^^^
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/exhaustiveness-unreachable-pattern.rs:96:15
|
||||
|
|
||||
LL | | true) => {}
|
||||
| ^^^^
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/exhaustiveness-unreachable-pattern.rs:95:15
|
||||
--> $DIR/exhaustiveness-unreachable-pattern.rs:102:15
|
||||
|
|
||||
LL | | true,
|
||||
| ^^^^
|
||||
|
||||
error: aborting due to 18 previous errors
|
||||
error: aborting due to 19 previous errors
|
||||
|
||||
|
@ -22,7 +22,7 @@ help: include the missing field in the pattern
|
||||
|
|
||||
LL | let Foo { present } = foo;
|
||||
| ^^^^^^^^^^^
|
||||
help: if you don't care about this missing field, you can explicitely ignore it
|
||||
help: if you don't care about this missing field, you can explicitly ignore it
|
||||
|
|
||||
LL | let Foo { .. } = foo;
|
||||
| ^^^^^^
|
||||
|
@ -20,7 +20,7 @@ help: include the missing fields in the pattern
|
||||
|
|
||||
LL | let A { x, y, b, c } = self.d;
|
||||
| ^^^^^^
|
||||
help: if you don't care about these missing fields, you can explicitely ignore them
|
||||
help: if you don't care about these missing fields, you can explicitly ignore them
|
||||
|
|
||||
LL | let A { x, y, .. } = self.d;
|
||||
| ^^^^
|
||||
|
@ -224,6 +224,10 @@ pub struct Config {
|
||||
/// The test mode, compile-fail, run-fail, ui
|
||||
pub mode: Mode,
|
||||
|
||||
/// The test suite (essentially which directory is running, but without the
|
||||
/// directory prefix such as src/test)
|
||||
pub suite: String,
|
||||
|
||||
/// The debugger to use in debuginfo mode. Unset otherwise.
|
||||
pub debugger: Option<Debugger>,
|
||||
|
||||
|
@ -39,6 +39,7 @@ fn config() -> Config {
|
||||
let args = &[
|
||||
"compiletest",
|
||||
"--mode=ui",
|
||||
"--suite=ui",
|
||||
"--compile-lib-path=",
|
||||
"--run-lib-path=",
|
||||
"--rustc-path=",
|
||||
|
@ -70,6 +70,12 @@ pub fn parse_config(args: Vec<String>) -> Config {
|
||||
"compile-fail | run-fail | run-pass-valgrind | pretty | debug-info | codegen | rustdoc \
|
||||
codegen-units | incremental | run-make | ui | js-doc-test | mir-opt | assembly",
|
||||
)
|
||||
.reqopt(
|
||||
"",
|
||||
"suite",
|
||||
"which suite of compile tests to run. used for nicer error reporting.",
|
||||
"SUITE",
|
||||
)
|
||||
.optopt(
|
||||
"",
|
||||
"pass",
|
||||
@ -201,6 +207,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
|
||||
build_base: opt_path(matches, "build-base"),
|
||||
stage_id: matches.opt_str("stage-id").unwrap(),
|
||||
mode: matches.opt_str("mode").unwrap().parse().expect("invalid mode"),
|
||||
suite: matches.opt_str("suite").unwrap(),
|
||||
debugger: None,
|
||||
run_ignored,
|
||||
filter: matches.free.first().cloned(),
|
||||
@ -340,7 +347,7 @@ pub fn run_tests(config: Config) {
|
||||
configs.extend(configure_lldb(&config));
|
||||
}
|
||||
} else {
|
||||
configs.push(config);
|
||||
configs.push(config.clone());
|
||||
};
|
||||
|
||||
let mut tests = Vec::new();
|
||||
@ -351,11 +358,32 @@ pub fn run_tests(config: Config) {
|
||||
let res = test::run_tests_console(&opts, tests);
|
||||
match res {
|
||||
Ok(true) => {}
|
||||
Ok(false) => panic!("Some tests failed"),
|
||||
Ok(false) => {
|
||||
// We want to report that the tests failed, but we also want to give
|
||||
// some indication of just what tests we were running. Especially on
|
||||
// CI, where there can be cross-compiled tests for a lot of
|
||||
// architectures, without this critical information it can be quite
|
||||
// easy to miss which tests failed, and as such fail to reproduce
|
||||
// the failure locally.
|
||||
|
||||
eprintln!(
|
||||
"Some tests failed in compiletest suite={}{} mode={} host={} target={}",
|
||||
config.suite,
|
||||
config.compare_mode.map(|c| format!(" compare_mode={:?}", c)).unwrap_or_default(),
|
||||
config.mode,
|
||||
config.host,
|
||||
config.target
|
||||
);
|
||||
|
||||
std::process::exit(1);
|
||||
}
|
||||
Err(e) => {
|
||||
// We don't know if tests passed or not, but if there was an error
|
||||
// during testing we don't want to just suceeed (we may not have
|
||||
// tested something), so fail.
|
||||
//
|
||||
// This should realistically "never" happen, so don't try to make
|
||||
// this a pretty error message.
|
||||
panic!("I/O failure during tests: {:?}", e);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user