Merge from rustc
This commit is contained in:
commit
4835a9da54
212 changed files with 2091 additions and 2941 deletions
|
|
@ -50,26 +50,39 @@ use crate::utils::channel;
|
|||
use crate::utils::helpers::exe;
|
||||
use crate::{Command, GitInfo, OnceLock, TargetSelection, check_ci_llvm, helpers, output, t};
|
||||
|
||||
/// Each path in this list is considered "allowed" in the `download-rustc="if-unchanged"` logic.
|
||||
/// Each path from this function is considered "allowed" in the `download-rustc="if-unchanged"` logic.
|
||||
/// This means they can be modified and changes to these paths should never trigger a compiler build
|
||||
/// when "if-unchanged" is set.
|
||||
///
|
||||
/// NOTE: Paths must have the ":!" prefix to tell git to ignore changes in those paths during
|
||||
/// the diff check.
|
||||
///
|
||||
/// WARNING: Be cautious when adding paths to this list. If a path that influences the compiler build
|
||||
/// is added here, it will cause bootstrap to skip necessary rebuilds, which may lead to risky results.
|
||||
/// For example, "src/bootstrap" should never be included in this list as it plays a crucial role in the
|
||||
/// final output/compiler, which can be significantly affected by changes made to the bootstrap sources.
|
||||
#[rustfmt::skip] // We don't want rustfmt to oneline this list
|
||||
pub const RUSTC_IF_UNCHANGED_ALLOWED_PATHS: &[&str] = &[
|
||||
":!library",
|
||||
":!src/tools",
|
||||
":!src/librustdoc",
|
||||
":!src/rustdoc-json-types",
|
||||
":!tests",
|
||||
":!triagebot.toml",
|
||||
];
|
||||
pub fn rustc_if_unchanged_allowed_paths() -> Vec<&'static str> {
|
||||
// NOTE: Paths must have the ":!" prefix to tell git to ignore changes in those paths during
|
||||
// the diff check.
|
||||
//
|
||||
// WARNING: Be cautious when adding paths to this list. If a path that influences the compiler build
|
||||
// is added here, it will cause bootstrap to skip necessary rebuilds, which may lead to risky results.
|
||||
// For example, "src/bootstrap" should never be included in this list as it plays a crucial role in the
|
||||
// final output/compiler, which can be significantly affected by changes made to the bootstrap sources.
|
||||
let mut paths = vec![
|
||||
":!library",
|
||||
":!src/tools",
|
||||
":!src/librustdoc",
|
||||
":!src/rustdoc-json-types",
|
||||
":!tests",
|
||||
":!triagebot.toml",
|
||||
];
|
||||
|
||||
if !CiEnv::is_ci() {
|
||||
// When a dependency is added/updated/removed in the library tree (or in some tools),
|
||||
// `Cargo.lock` will be updated by `cargo`. This update will incorrectly invalidate the
|
||||
// `download-rustc=if-unchanged` cache.
|
||||
//
|
||||
// To prevent this, add `Cargo.lock` to the list of allowed paths when not running on CI.
|
||||
// This is generally safe because changes to dependencies typically involve modifying
|
||||
// `Cargo.toml`, which would already invalidate the CI-rustc cache on non-allowed paths.
|
||||
paths.push(":!Cargo.lock");
|
||||
}
|
||||
|
||||
paths
|
||||
}
|
||||
|
||||
/// Global configuration for the entire build and/or bootstrap.
|
||||
///
|
||||
|
|
@ -1503,7 +1516,7 @@ impl Config {
|
|||
let commit = if self.rust_info.is_managed_git_subrepository() {
|
||||
// Look for a version to compare to based on the current commit.
|
||||
// Only commits merged by bors will have CI artifacts.
|
||||
let freshness = self.check_path_modifications(RUSTC_IF_UNCHANGED_ALLOWED_PATHS);
|
||||
let freshness = self.check_path_modifications(&rustc_if_unchanged_allowed_paths());
|
||||
self.verbose(|| {
|
||||
eprintln!("rustc freshness: {freshness:?}");
|
||||
});
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ use serde::Deserialize;
|
|||
|
||||
use super::flags::Flags;
|
||||
use super::toml::change_id::ChangeIdWrapper;
|
||||
use super::{Config, RUSTC_IF_UNCHANGED_ALLOWED_PATHS};
|
||||
use super::{Config, rustc_if_unchanged_allowed_paths};
|
||||
use crate::ChangeId;
|
||||
use crate::core::build_steps::clippy::{LintConfig, get_clippy_rules_in_order};
|
||||
use crate::core::build_steps::llvm;
|
||||
|
|
@ -459,7 +459,7 @@ fn jobs_precedence() {
|
|||
#[test]
|
||||
fn check_rustc_if_unchanged_paths() {
|
||||
let config = parse("");
|
||||
let normalised_allowed_paths: Vec<_> = RUSTC_IF_UNCHANGED_ALLOWED_PATHS
|
||||
let normalised_allowed_paths: Vec<_> = rustc_if_unchanged_allowed_paths()
|
||||
.iter()
|
||||
.map(|t| {
|
||||
t.strip_prefix(":!").expect(&format!("{t} doesn't have ':!' prefix, but it should."))
|
||||
|
|
|
|||
|
|
@ -26,108 +26,131 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
) -> InterpResult<'tcx, EmulateItemResult> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let intrinsic_structure: Vec<_> = intrinsic_name.split('_').collect();
|
||||
let get_ord_at = |i: usize| {
|
||||
let ordering = generic_args.const_at(i).to_value();
|
||||
ordering.valtree.unwrap_branch()[0].unwrap_leaf().to_atomic_ordering()
|
||||
};
|
||||
|
||||
fn read_ord(ord: &str) -> AtomicReadOrd {
|
||||
fn read_ord(ord: AtomicOrdering) -> AtomicReadOrd {
|
||||
match ord {
|
||||
"seqcst" => AtomicReadOrd::SeqCst,
|
||||
"acquire" => AtomicReadOrd::Acquire,
|
||||
"relaxed" => AtomicReadOrd::Relaxed,
|
||||
_ => panic!("invalid read ordering `{ord}`"),
|
||||
}
|
||||
}
|
||||
|
||||
fn read_ord_const_generic(o: AtomicOrdering) -> AtomicReadOrd {
|
||||
match o {
|
||||
AtomicOrdering::SeqCst => AtomicReadOrd::SeqCst,
|
||||
AtomicOrdering::Acquire => AtomicReadOrd::Acquire,
|
||||
AtomicOrdering::Relaxed => AtomicReadOrd::Relaxed,
|
||||
_ => panic!("invalid read ordering `{o:?}`"),
|
||||
_ => panic!("invalid read ordering `{ord:?}`"),
|
||||
}
|
||||
}
|
||||
|
||||
fn write_ord(ord: &str) -> AtomicWriteOrd {
|
||||
fn write_ord(ord: AtomicOrdering) -> AtomicWriteOrd {
|
||||
match ord {
|
||||
"seqcst" => AtomicWriteOrd::SeqCst,
|
||||
"release" => AtomicWriteOrd::Release,
|
||||
"relaxed" => AtomicWriteOrd::Relaxed,
|
||||
_ => panic!("invalid write ordering `{ord}`"),
|
||||
AtomicOrdering::SeqCst => AtomicWriteOrd::SeqCst,
|
||||
AtomicOrdering::Release => AtomicWriteOrd::Release,
|
||||
AtomicOrdering::Relaxed => AtomicWriteOrd::Relaxed,
|
||||
_ => panic!("invalid write ordering `{ord:?}`"),
|
||||
}
|
||||
}
|
||||
|
||||
fn rw_ord(ord: &str) -> AtomicRwOrd {
|
||||
fn rw_ord(ord: AtomicOrdering) -> AtomicRwOrd {
|
||||
match ord {
|
||||
"seqcst" => AtomicRwOrd::SeqCst,
|
||||
"acqrel" => AtomicRwOrd::AcqRel,
|
||||
"acquire" => AtomicRwOrd::Acquire,
|
||||
"release" => AtomicRwOrd::Release,
|
||||
"relaxed" => AtomicRwOrd::Relaxed,
|
||||
_ => panic!("invalid read-write ordering `{ord}`"),
|
||||
AtomicOrdering::SeqCst => AtomicRwOrd::SeqCst,
|
||||
AtomicOrdering::AcqRel => AtomicRwOrd::AcqRel,
|
||||
AtomicOrdering::Acquire => AtomicRwOrd::Acquire,
|
||||
AtomicOrdering::Release => AtomicRwOrd::Release,
|
||||
AtomicOrdering::Relaxed => AtomicRwOrd::Relaxed,
|
||||
}
|
||||
}
|
||||
|
||||
fn fence_ord(ord: &str) -> AtomicFenceOrd {
|
||||
fn fence_ord(ord: AtomicOrdering) -> AtomicFenceOrd {
|
||||
match ord {
|
||||
"seqcst" => AtomicFenceOrd::SeqCst,
|
||||
"acqrel" => AtomicFenceOrd::AcqRel,
|
||||
"acquire" => AtomicFenceOrd::Acquire,
|
||||
"release" => AtomicFenceOrd::Release,
|
||||
_ => panic!("invalid fence ordering `{ord}`"),
|
||||
AtomicOrdering::SeqCst => AtomicFenceOrd::SeqCst,
|
||||
AtomicOrdering::AcqRel => AtomicFenceOrd::AcqRel,
|
||||
AtomicOrdering::Acquire => AtomicFenceOrd::Acquire,
|
||||
AtomicOrdering::Release => AtomicFenceOrd::Release,
|
||||
_ => panic!("invalid fence ordering `{ord:?}`"),
|
||||
}
|
||||
}
|
||||
|
||||
match &*intrinsic_structure {
|
||||
// New-style intrinsics that use const generics
|
||||
["load"] => {
|
||||
let ordering = generic_args.const_at(1).to_value();
|
||||
let ordering =
|
||||
ordering.valtree.unwrap_branch()[0].unwrap_leaf().to_atomic_ordering();
|
||||
this.atomic_load(args, dest, read_ord_const_generic(ordering))?;
|
||||
match intrinsic_name {
|
||||
"load" => {
|
||||
let ord = get_ord_at(1);
|
||||
this.atomic_load(args, dest, read_ord(ord))?;
|
||||
}
|
||||
|
||||
// Old-style intrinsics that have the ordering in the intrinsic name
|
||||
["store", ord] => this.atomic_store(args, write_ord(ord))?,
|
||||
"store" => {
|
||||
let ord = get_ord_at(1);
|
||||
this.atomic_store(args, write_ord(ord))?
|
||||
}
|
||||
|
||||
["fence", ord] => this.atomic_fence_intrinsic(args, fence_ord(ord))?,
|
||||
["singlethreadfence", ord] => this.compiler_fence_intrinsic(args, fence_ord(ord))?,
|
||||
"fence" => {
|
||||
let ord = get_ord_at(0);
|
||||
this.atomic_fence_intrinsic(args, fence_ord(ord))?
|
||||
}
|
||||
"singlethreadfence" => {
|
||||
let ord = get_ord_at(0);
|
||||
this.compiler_fence_intrinsic(args, fence_ord(ord))?;
|
||||
}
|
||||
|
||||
["xchg", ord] => this.atomic_exchange(args, dest, rw_ord(ord))?,
|
||||
["cxchg", ord1, ord2] =>
|
||||
this.atomic_compare_exchange(args, dest, rw_ord(ord1), read_ord(ord2))?,
|
||||
["cxchgweak", ord1, ord2] =>
|
||||
this.atomic_compare_exchange_weak(args, dest, rw_ord(ord1), read_ord(ord2))?,
|
||||
"xchg" => {
|
||||
let ord = get_ord_at(1);
|
||||
this.atomic_exchange(args, dest, rw_ord(ord))?;
|
||||
}
|
||||
"cxchg" => {
|
||||
let ord1 = get_ord_at(1);
|
||||
let ord2 = get_ord_at(2);
|
||||
this.atomic_compare_exchange(args, dest, rw_ord(ord1), read_ord(ord2))?;
|
||||
}
|
||||
"cxchgweak" => {
|
||||
let ord1 = get_ord_at(1);
|
||||
let ord2 = get_ord_at(2);
|
||||
this.atomic_compare_exchange_weak(args, dest, rw_ord(ord1), read_ord(ord2))?;
|
||||
}
|
||||
|
||||
["or", ord] =>
|
||||
this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::BitOr, false), rw_ord(ord))?,
|
||||
["xor", ord] =>
|
||||
this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::BitXor, false), rw_ord(ord))?,
|
||||
["and", ord] =>
|
||||
this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::BitAnd, false), rw_ord(ord))?,
|
||||
["nand", ord] =>
|
||||
this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::BitAnd, true), rw_ord(ord))?,
|
||||
["xadd", ord] =>
|
||||
this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::Add, false), rw_ord(ord))?,
|
||||
["xsub", ord] =>
|
||||
this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::Sub, false), rw_ord(ord))?,
|
||||
["min", ord] => {
|
||||
"or" => {
|
||||
let ord = get_ord_at(1);
|
||||
this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::BitOr, false), rw_ord(ord))?;
|
||||
}
|
||||
"xor" => {
|
||||
let ord = get_ord_at(1);
|
||||
this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::BitXor, false), rw_ord(ord))?;
|
||||
}
|
||||
"and" => {
|
||||
let ord = get_ord_at(1);
|
||||
this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::BitAnd, false), rw_ord(ord))?;
|
||||
}
|
||||
"nand" => {
|
||||
let ord = get_ord_at(1);
|
||||
this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::BitAnd, true), rw_ord(ord))?;
|
||||
}
|
||||
"xadd" => {
|
||||
let ord = get_ord_at(1);
|
||||
this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::Add, false), rw_ord(ord))?;
|
||||
}
|
||||
"xsub" => {
|
||||
let ord = get_ord_at(1);
|
||||
this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::Sub, false), rw_ord(ord))?;
|
||||
}
|
||||
"min" => {
|
||||
let ord = get_ord_at(1);
|
||||
// Later we will use the type to indicate signed vs unsigned,
|
||||
// so make sure it matches the intrinsic name.
|
||||
assert!(matches!(args[1].layout.ty.kind(), ty::Int(_)));
|
||||
this.atomic_rmw_op(args, dest, AtomicOp::Min, rw_ord(ord))?;
|
||||
}
|
||||
["umin", ord] => {
|
||||
"umin" => {
|
||||
let ord = get_ord_at(1);
|
||||
// Later we will use the type to indicate signed vs unsigned,
|
||||
// so make sure it matches the intrinsic name.
|
||||
assert!(matches!(args[1].layout.ty.kind(), ty::Uint(_)));
|
||||
this.atomic_rmw_op(args, dest, AtomicOp::Min, rw_ord(ord))?;
|
||||
}
|
||||
["max", ord] => {
|
||||
"max" => {
|
||||
let ord = get_ord_at(1);
|
||||
// Later we will use the type to indicate signed vs unsigned,
|
||||
// so make sure it matches the intrinsic name.
|
||||
assert!(matches!(args[1].layout.ty.kind(), ty::Int(_)));
|
||||
this.atomic_rmw_op(args, dest, AtomicOp::Max, rw_ord(ord))?;
|
||||
}
|
||||
["umax", ord] => {
|
||||
"umax" => {
|
||||
let ord = get_ord_at(1);
|
||||
// Later we will use the type to indicate signed vs unsigned,
|
||||
// so make sure it matches the intrinsic name.
|
||||
assert!(matches!(args[1].layout.ty.kind(), ty::Uint(_)));
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ error[E0080]: accessing memory based on pointer with alignment ALIGN, but alignm
|
|||
--> tests/fail/const-ub-checks.rs:LL:CC
|
||||
|
|
||||
LL | ptr.read();
|
||||
| ^^^^^^^^^^ evaluation of constant value failed here
|
||||
| ^^^^^^^^^^ evaluation of `UNALIGNED_READ` failed here
|
||||
|
||||
note: erroneous constant encountered
|
||||
--> tests/fail/const-ub-checks.rs:LL:CC
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ error[E0080]: attempt to compute `5_u32 - 6_u32`, which would overflow
|
|||
--> tests/fail/erroneous_const2.rs:LL:CC
|
||||
|
|
||||
LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
|
||||
| ^^^^^ evaluation of constant value failed here
|
||||
| ^^^^^ evaluation of `FOO` failed here
|
||||
|
||||
note: erroneous constant encountered
|
||||
--> tests/fail/erroneous_const2.rs:LL:CC
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue