Merge from rustc

This commit is contained in:
The Miri Cronjob Bot 2025-04-12 05:07:15 +00:00
commit 352545f16f
357 changed files with 3354 additions and 1745 deletions

View file

@ -25,6 +25,7 @@ path = "src/driver.rs"
[dependencies]
clippy_config = { path = "clippy_config" }
clippy_lints = { path = "clippy_lints" }
clippy_utils = { path = "clippy_utils" }
rustc_tools_util = { path = "rustc_tools_util", version = "0.4.2" }
tempfile = { version = "3.3", optional = true }
termize = "0.1"

View file

@ -1,10 +1,10 @@
use super::{Attribute, DEPRECATED_CFG_ATTR, DEPRECATED_CLIPPY_CFG_ATTR, unnecessary_clippy_cfg};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::msrvs::{self, MsrvStack};
use clippy_utils::sym;
use rustc_ast::AttrStyle;
use rustc_errors::Applicability;
use rustc_lint::EarlyContext;
use rustc_span::sym;
pub(super) fn check(cx: &EarlyContext<'_>, attr: &Attribute, msrv: &MsrvStack) {
// check cfg_attr
@ -18,7 +18,7 @@ pub(super) fn check(cx: &EarlyContext<'_>, attr: &Attribute, msrv: &MsrvStack) {
&& msrv.meets(msrvs::TOOL_ATTRIBUTES)
// check for `rustfmt_skip` and `rustfmt::skip`
&& let Some(skip_item) = &items[1].meta_item()
&& (skip_item.has_name(sym!(rustfmt_skip))
&& (skip_item.has_name(sym::rustfmt_skip)
|| skip_item
.path
.segments

View file

@ -2,10 +2,10 @@ use super::USELESS_ATTRIBUTE;
use super::utils::{is_lint_level, is_word, namespace_and_lint};
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::source::{SpanRangeExt, first_line_of_span};
use clippy_utils::sym;
use rustc_ast::{Attribute, Item, ItemKind};
use rustc_errors::Applicability;
use rustc_lint::{EarlyContext, LintContext};
use rustc_span::sym;
pub(super) fn check(cx: &EarlyContext<'_>, item: &Item, attrs: &[Attribute]) {
let skip_unused_imports = attrs.iter().any(|attr| attr.has_name(sym::macro_use));
@ -61,7 +61,7 @@ pub(super) fn check(cx: &EarlyContext<'_>, item: &Item, attrs: &[Attribute]) {
if is_word(lint, sym::unused_imports) && skip_unused_imports {
return;
}
if is_word(lint, sym!(unused_extern_crates)) {
if is_word(lint, sym::unused_extern_crates) {
return;
}
},

View file

@ -53,7 +53,7 @@ fn is_impl_not_trait_with_bool_out<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -
.not_trait()
.filter(|trait_id| implements_trait(cx, ty, *trait_id, &[]))
.and_then(|trait_id| {
cx.tcx.associated_items(trait_id).find_by_name_and_kind(
cx.tcx.associated_items(trait_id).find_by_ident_and_kind(
cx.tcx,
Ident::from_str("Output"),
ty::AssocKind::Type,

View file

@ -38,7 +38,7 @@ pub fn check(
// of all `#[test]` attributes in not ignored code examples
fn check_code_sample(code: String, edition: Edition, ignore: bool) -> (bool, Vec<Range<usize>>) {
rustc_driver::catch_fatal_errors(|| {
rustc_span::create_session_globals_then(edition, None, || {
rustc_span::create_session_globals_then(edition, &[], None, || {
let mut test_attr_spans = vec![];
let filename = FileName::anon_source_code(&code);

View file

@ -22,8 +22,8 @@ pub(super) fn check_impl_item(cx: &LateContext<'_>, item: &ImplItem<'_>, ignored
&& let Some(did) = trait_item_def_id_of_impl(items, item.owner_id)
&& !is_from_ignored_trait(trait_ref, ignored_traits)
{
let mut param_idents_iter = cx.tcx.hir_body_param_names(body_id);
let mut default_param_idents_iter = cx.tcx.fn_arg_names(did).iter().copied();
let mut param_idents_iter = cx.tcx.hir_body_param_idents(body_id);
let mut default_param_idents_iter = cx.tcx.fn_arg_idents(did).iter().copied();
let renames = RenamedFnArgs::new(&mut default_param_idents_iter, &mut param_idents_iter);
if !renames.0.is_empty() {

View file

@ -238,7 +238,7 @@ fn is_contains_sig(cx: &LateContext<'_>, call_id: HirId, iter_expr: &Expr<'_>) -
.instantiate_bound_regions_with_erased(sig.rebind(search_ty))
.kind()
&& let Some(iter_trait) = cx.tcx.get_diagnostic_item(sym::Iterator)
&& let Some(iter_item) = cx.tcx.associated_items(iter_trait).find_by_name_and_kind(
&& let Some(iter_item) = cx.tcx.associated_items(iter_trait).find_by_ident_and_kind(
cx.tcx,
Ident::with_dummy_span(sym::Item),
AssocKind::Type,

View file

@ -3,6 +3,7 @@
#![feature(f128)]
#![feature(f16)]
#![feature(if_let_guard)]
#![feature(macro_metavar_expr)]
#![feature(macro_metavar_expr_concat)]
#![feature(let_chains)]
#![feature(never_type)]
@ -74,6 +75,7 @@ pub mod qualify_min_const_fn;
pub mod source;
pub mod str_utils;
pub mod sugg;
pub mod sym;
pub mod ty;
pub mod usage;
pub mod visitors;
@ -126,7 +128,7 @@ use rustc_middle::ty::{
use rustc_span::hygiene::{ExpnKind, MacroKind};
use rustc_span::source_map::SourceMap;
use rustc_span::symbol::{Ident, Symbol, kw};
use rustc_span::{InnerSpan, Span, sym};
use rustc_span::{InnerSpan, Span};
use visitors::{Visitable, for_each_unconsumed_temporary};
use crate::consts::{ConstEvalCtxt, Constant, mir_to_const};
@ -3502,7 +3504,7 @@ fn maybe_get_relative_path(from: &DefPath, to: &DefPath, max_super: usize) -> St
// a::b::c ::d::sym refers to
// e::f::sym:: ::
// result should be super::super::super::super::e::f
if let DefPathData::TypeNs(Some(s)) = l {
if let DefPathData::TypeNs(s) = l {
path.push(s.to_string());
}
if let DefPathData::TypeNs(_) = r {
@ -3513,7 +3515,7 @@ fn maybe_get_relative_path(from: &DefPath, to: &DefPath, max_super: usize) -> St
// a::b::sym:: :: refers to
// c::d::e ::f::sym
// when looking at `f`
Left(DefPathData::TypeNs(Some(sym))) => path.push(sym.to_string()),
Left(DefPathData::TypeNs(sym)) => path.push(sym.to_string()),
// consider:
// a::b::c ::d::sym refers to
// e::f::sym:: ::
@ -3527,7 +3529,7 @@ fn maybe_get_relative_path(from: &DefPath, to: &DefPath, max_super: usize) -> St
// `super` chain would be too long, just use the absolute path instead
once(String::from("crate"))
.chain(to.data.iter().filter_map(|el| {
if let DefPathData::TypeNs(Some(sym)) = el.data {
if let DefPathData::TypeNs(sym) = el.data {
Some(sym.to_string())
} else {
None

View file

@ -0,0 +1,23 @@
#![allow(non_upper_case_globals)]
use rustc_span::symbol::{Symbol, PREDEFINED_SYMBOLS_COUNT};
pub use rustc_span::sym::*;
macro_rules! generate {
($($sym:ident,)*) => {
/// To be supplied to `rustc_interface::Config`
pub const EXTRA_SYMBOLS: &[&str] = &[
$(stringify!($sym),)*
];
$(
pub const $sym: Symbol = Symbol::new(PREDEFINED_SYMBOLS_COUNT + ${index()});
)*
};
}
generate! {
rustfmt_skip,
unused_extern_crates,
}

View file

@ -1109,7 +1109,7 @@ pub fn make_projection<'tcx>(
assoc_ty: Symbol,
args: GenericArgsRef<'tcx>,
) -> Option<AliasTy<'tcx>> {
let Some(assoc_item) = tcx.associated_items(container_id).find_by_name_and_kind(
let Some(assoc_item) = tcx.associated_items(container_id).find_by_ident_and_kind(
tcx,
Ident::with_dummy_span(assoc_ty),
AssocKind::Type,

View file

@ -160,6 +160,7 @@ impl rustc_driver::Callbacks for ClippyCallbacks {
clippy_lints::register_lints(lint_store, conf);
clippy_lints::register_pre_expansion_lints(lint_store, conf);
}));
config.extra_symbols = clippy_utils::sym::EXTRA_SYMBOLS.into();
// FIXME: #4825; This is required, because Clippy lints that are based on MIR have to be
// run on the unoptimized MIR. On the other hand this results in some false negatives. If

View file

@ -1,7 +1,7 @@
[package]
name = "compiletest"
version = "0.0.0"
edition = "2021"
edition = "2024"
[lib]
doctest = false

View file

@ -395,6 +395,7 @@ pub struct Config {
pub target_cfgs: OnceLock<TargetCfgs>,
pub builtin_cfg_names: OnceLock<HashSet<String>>,
pub supported_crate_types: OnceLock<HashSet<String>>,
pub nocapture: bool,
@ -472,6 +473,11 @@ impl Config {
self.builtin_cfg_names.get_or_init(|| builtin_cfg_names(self))
}
/// Get the list of crate types that the target platform supports.
pub fn supported_crate_types(&self) -> &HashSet<String> {
self.supported_crate_types.get_or_init(|| supported_crate_types(self))
}
pub fn has_threads(&self) -> bool {
// Wasm targets don't have threads unless `-threads` is in the target
// name, such as `wasm32-wasip1-threads`.
@ -745,6 +751,31 @@ fn builtin_cfg_names(config: &Config) -> HashSet<String> {
.collect()
}
pub const KNOWN_CRATE_TYPES: &[&str] =
&["bin", "cdylib", "dylib", "lib", "proc-macro", "rlib", "staticlib"];
fn supported_crate_types(config: &Config) -> HashSet<String> {
let crate_types: HashSet<_> = rustc_output(
config,
&["--target", &config.target, "--print=supported-crate-types", "-Zunstable-options"],
Default::default(),
)
.lines()
.map(|l| l.to_string())
.collect();
for crate_type in crate_types.iter() {
assert!(
KNOWN_CRATE_TYPES.contains(&crate_type.as_str()),
"unexpected crate type `{}`: known crate types are {:?}",
crate_type,
KNOWN_CRATE_TYPES
);
}
crate_types
}
fn rustc_output(config: &Config, args: &[&str], envs: HashMap<String, String>) -> String {
let mut command = Command::new(&config.rustc_path);
add_dylib_path(&mut command, iter::once(&config.compile_lib_path));

View file

@ -40,7 +40,9 @@ pub(crate) fn configure_gdb(config: &Config) -> Option<Arc<Config>> {
//
// we should figure out how to lift this restriction! (run them all
// on different ports allocated dynamically).
env::set_var("RUST_TEST_THREADS", "1");
//
// SAFETY: at this point we are still single-threaded.
unsafe { env::set_var("RUST_TEST_THREADS", "1") };
}
Some(Arc::new(Config { debugger: Some(Debugger::Gdb), ..config.clone() }))

View file

@ -133,6 +133,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
"min-llvm-version",
"min-system-llvm-version",
"needs-asm-support",
"needs-crate-type",
"needs-deterministic-layouts",
"needs-dlltool",
"needs-dynamic-linking",

View file

@ -389,14 +389,22 @@ impl TestProps {
}
if let Some(flags) = config.parse_name_value_directive(ln, COMPILE_FLAGS) {
self.compile_flags.extend(split_flags(&flags));
let flags = split_flags(&flags);
for flag in &flags {
if flag == "--edition" || flag.starts_with("--edition=") {
panic!("you must use `//@ edition` to configure the edition");
}
}
self.compile_flags.extend(flags);
}
if config.parse_name_value_directive(ln, INCORRECT_COMPILER_FLAGS).is_some() {
panic!("`compiler-flags` directive should be spelled `compile-flags`");
}
if let Some(edition) = config.parse_edition(ln) {
self.compile_flags.push(format!("--edition={}", edition.trim()));
// The edition is added at the start, since flags from //@compile-flags must
// be passed to rustc last.
self.compile_flags.insert(0, format!("--edition={}", edition.trim()));
has_edition = true;
}
@ -452,7 +460,7 @@ impl TestProps {
ln,
UNSET_EXEC_ENV,
&mut self.unset_exec_env,
|r| r,
|r| r.trim().to_owned(),
);
config.push_name_value_directive(
ln,
@ -464,7 +472,7 @@ impl TestProps {
ln,
UNSET_RUSTC_ENV,
&mut self.unset_rustc_env,
|r| r,
|r| r.trim().to_owned(),
);
config.push_name_value_directive(
ln,
@ -624,7 +632,9 @@ impl TestProps {
}
if let (Some(edition), false) = (&config.edition, has_edition) {
self.compile_flags.push(format!("--edition={}", edition));
// The edition is added at the start, since flags from //@compile-flags must be passed
// to rustc last.
self.compile_flags.insert(0, format!("--edition={}", edition));
}
}
@ -997,16 +1007,13 @@ impl Config {
fn parse_env(nv: String) -> (String, String) {
// nv is either FOO or FOO=BAR
let mut strs: Vec<String> = nv.splitn(2, '=').map(str::to_owned).collect();
match strs.len() {
1 => (strs.pop().unwrap(), String::new()),
2 => {
let end = strs.pop().unwrap();
(strs.pop().unwrap(), end)
}
n => panic!("Expected 1 or 2 strings, not {}", n),
}
// FIXME(Zalathar): The form without `=` seems to be unused; should
// we drop support for it?
let (name, value) = nv.split_once('=').unwrap_or((&nv, ""));
// Trim whitespace from the name, so that `//@ exec-env: FOO=BAR`
// sees the name as `FOO` and not ` FOO`.
let name = name.trim();
(name.to_owned(), value.to_owned())
}
fn parse_pp_exact(&self, line: &str, testfile: &Path) -> Option<PathBuf> {

View file

@ -1,4 +1,4 @@
use crate::common::{Config, KNOWN_TARGET_HAS_ATOMIC_WIDTHS, Sanitizer};
use crate::common::{Config, KNOWN_CRATE_TYPES, KNOWN_TARGET_HAS_ATOMIC_WIDTHS, Sanitizer};
use crate::header::{IgnoreDecision, llvm_has_libzstd};
pub(super) fn handle_needs(
@ -6,7 +6,7 @@ pub(super) fn handle_needs(
config: &Config,
ln: &str,
) -> IgnoreDecision {
// Note thet we intentionally still put the needs- prefix here to make the file show up when
// Note that we intentionally still put the needs- prefix here to make the file show up when
// grepping for a directive name, even though we could technically strip that.
let needs = &[
Need {
@ -224,6 +224,50 @@ pub(super) fn handle_needs(
}
}
// FIXME(jieyouxu): share multi-value directive logic with `needs-target-has-atomic` above.
if name == "needs-crate-type" {
let Some(rest) = rest else {
return IgnoreDecision::Error {
message:
"expected `needs-crate-type` to have a comma-separated list of crate types"
.to_string(),
};
};
// Expect directive value to be a list of comma-separated crate-types.
let specified_crate_types = rest
.split(',')
.map(|crate_type| crate_type.trim())
.map(ToString::to_string)
.collect::<Vec<String>>();
for crate_type in &specified_crate_types {
if !KNOWN_CRATE_TYPES.contains(&crate_type.as_str()) {
return IgnoreDecision::Error {
message: format!(
"unknown crate type specified in `needs-crate-type`: `{crate_type}` is not \
a known crate type, known values are `{:?}`",
KNOWN_CRATE_TYPES
),
};
}
}
let satisfies_all_crate_types = specified_crate_types
.iter()
.all(|specified| config.supported_crate_types().contains(specified));
if satisfies_all_crate_types {
return IgnoreDecision::Continue;
} else {
return IgnoreDecision::Ignore {
reason: format!(
"skipping test as target does not support all of the crate types `{:?}`",
specified_crate_types
),
};
}
}
if !name.starts_with("needs-") {
return IgnoreDecision::Continue;
}

View file

@ -902,3 +902,41 @@ fn test_rustc_abi() {
assert!(!check_ignore(&config, "//@ ignore-rustc_abi-x86-sse2"));
assert!(check_ignore(&config, "//@ only-rustc_abi-x86-sse2"));
}
#[test]
fn test_supported_crate_types() {
// Basic assumptions check on under-test compiler's `--print=supported-crate-types` output based
// on knowledge about the cherry-picked `x86_64-unknown-linux-gnu` and `wasm32-unknown-unknown`
// targets. Also smoke tests the `needs-crate-type` directive itself.
use std::collections::HashSet;
let config = cfg().target("x86_64-unknown-linux-gnu").build();
assert_eq!(
config.supported_crate_types().iter().map(String::as_str).collect::<HashSet<_>>(),
HashSet::from(["bin", "cdylib", "dylib", "lib", "proc-macro", "rlib", "staticlib"]),
);
assert!(!check_ignore(&config, "//@ needs-crate-type: rlib"));
assert!(!check_ignore(&config, "//@ needs-crate-type: dylib"));
assert!(!check_ignore(
&config,
"//@ needs-crate-type: bin, cdylib, dylib, lib, proc-macro, rlib, staticlib"
));
let config = cfg().target("wasm32-unknown-unknown").build();
assert_eq!(
config.supported_crate_types().iter().map(String::as_str).collect::<HashSet<_>>(),
HashSet::from(["bin", "cdylib", "lib", "rlib", "staticlib"]),
);
// rlib is supported
assert!(!check_ignore(&config, "//@ needs-crate-type: rlib"));
// dylib is not
assert!(check_ignore(&config, "//@ needs-crate-type: dylib"));
// If multiple crate types are specified, then all specified crate types need to be supported.
assert!(check_ignore(&config, "//@ needs-crate-type: cdylib, dylib"));
assert!(check_ignore(
&config,
"//@ needs-crate-type: bin, cdylib, dylib, lib, proc-macro, rlib, staticlib"
));
}

View file

@ -431,6 +431,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
target_cfgs: OnceLock::new(),
builtin_cfg_names: OnceLock::new(),
supported_crate_types: OnceLock::new(),
nocapture: matches.opt_present("no-capture"),
@ -529,10 +530,14 @@ pub fn run_tests(config: Arc<Config>) {
}
// Prevent issue #21352 UAC blocking .exe containing 'patch' etc. on Windows
// If #11207 is resolved (adding manifest to .exe) this becomes unnecessary
env::set_var("__COMPAT_LAYER", "RunAsInvoker");
//
// SAFETY: at this point we're still single-threaded.
unsafe { env::set_var("__COMPAT_LAYER", "RunAsInvoker") };
// Let tests know which target they're running as
env::set_var("TARGET", &config.target);
// Let tests know which target they're running as.
//
// SAFETY: at this point we're still single-threaded.
unsafe { env::set_var("TARGET", &config.target) };
let mut configs = Vec::new();
if let Mode::DebugInfo = config.mode {

View file

@ -6,6 +6,7 @@
/// This fixes issue #7772.
#[cfg(target_vendor = "apple")]
#[allow(non_camel_case_types)]
// FIXME(#139616): document caller contract.
pub unsafe fn raise_fd_limit() {
use std::ptr::null_mut;
use std::{cmp, io};
@ -21,8 +22,10 @@ pub unsafe fn raise_fd_limit() {
let mut mib: [libc::c_int; 2] = [CTL_KERN, KERN_MAXFILESPERPROC];
let mut maxfiles: libc::c_int = 0;
let mut size: libc::size_t = size_of_val(&maxfiles) as libc::size_t;
if libc::sysctl(&mut mib[0], 2, &mut maxfiles as *mut _ as *mut _, &mut size, null_mut(), 0)
!= 0
// FIXME(#139616): justify why this is sound.
if unsafe {
libc::sysctl(&mut mib[0], 2, &mut maxfiles as *mut _ as *mut _, &mut size, null_mut(), 0)
} != 0
{
let err = io::Error::last_os_error();
panic!("raise_fd_limit: error calling sysctl: {}", err);
@ -30,7 +33,8 @@ pub unsafe fn raise_fd_limit() {
// Fetch the current resource limits
let mut rlim = libc::rlimit { rlim_cur: 0, rlim_max: 0 };
if libc::getrlimit(libc::RLIMIT_NOFILE, &mut rlim) != 0 {
// FIXME(#139616): justify why this is sound.
if unsafe { libc::getrlimit(libc::RLIMIT_NOFILE, &mut rlim) } != 0 {
let err = io::Error::last_os_error();
panic!("raise_fd_limit: error calling getrlimit: {}", err);
}
@ -41,7 +45,8 @@ pub unsafe fn raise_fd_limit() {
rlim.rlim_cur = cmp::min(maxfiles as libc::rlim_t, rlim.rlim_max);
// Set our newly-increased resource limit.
if libc::setrlimit(libc::RLIMIT_NOFILE, &rlim) != 0 {
// FIXME(#139616): justify why this is sound.
if unsafe { libc::setrlimit(libc::RLIMIT_NOFILE, &rlim) } != 0 {
let err = io::Error::last_os_error();
panic!("raise_fd_limit: error calling setrlimit: {}", err);
}

View file

@ -165,6 +165,7 @@ mod imp {
mut err_pipe: ChildStderr,
data: &mut dyn FnMut(bool, &mut Vec<u8>, bool),
) -> io::Result<()> {
// FIXME(#139616): justify why this is sound.
unsafe {
libc::fcntl(out_pipe.as_raw_fd(), libc::F_SETFL, libc::O_NONBLOCK);
libc::fcntl(err_pipe.as_raw_fd(), libc::F_SETFL, libc::O_NONBLOCK);
@ -175,6 +176,7 @@ mod imp {
let mut out = Vec::new();
let mut err = Vec::new();
// FIXME(#139616): justify why this is sound.
let mut fds: [libc::pollfd; 2] = unsafe { mem::zeroed() };
fds[0].fd = out_pipe.as_raw_fd();
fds[0].events = libc::POLLIN;
@ -185,6 +187,7 @@ mod imp {
while nfds > 0 {
// wait for either pipe to become readable using `select`
// FIXME(#139616): justify why this is sound.
let r = unsafe { libc::poll(fds.as_mut_ptr(), nfds, -1) };
if r == -1 {
let err = io::Error::last_os_error();
@ -256,6 +259,7 @@ mod imp {
port.add_handle(0, &out_pipe)?;
port.add_handle(1, &err_pipe)?;
// FIXME(#139616): justify why this is sound.
unsafe {
let mut out_pipe = Pipe::new(out_pipe, &mut out);
let mut err_pipe = Pipe::new(err_pipe, &mut err);
@ -284,18 +288,23 @@ mod imp {
}
impl<'a> Pipe<'a> {
// FIXME(#139616): document caller contract.
unsafe fn new<P: IntoRawHandle>(p: P, dst: &'a mut Vec<u8>) -> Pipe<'a> {
Pipe {
dst,
pipe: NamedPipe::from_raw_handle(p.into_raw_handle()),
// FIXME(#139616): justify why this is sound.
pipe: unsafe { NamedPipe::from_raw_handle(p.into_raw_handle()) },
overlapped: Overlapped::zero(),
done: false,
}
}
// FIXME(#139616): document caller contract.
unsafe fn read(&mut self) -> io::Result<()> {
let dst = slice_to_end(self.dst);
match self.pipe.read_overlapped(dst, self.overlapped.raw()) {
// FIXME(#139616): justify why this is sound.
let dst = unsafe { slice_to_end(self.dst) };
// FIXME(#139616): justify why this is sound.
match unsafe { self.pipe.read_overlapped(dst, self.overlapped.raw()) } {
Ok(_) => Ok(()),
Err(e) => {
if e.raw_os_error() == Some(ERROR_BROKEN_PIPE.0 as i32) {
@ -308,15 +317,18 @@ mod imp {
}
}
// FIXME(#139616): document caller contract.
unsafe fn complete(&mut self, status: &CompletionStatus) {
let prev = self.dst.len();
self.dst.set_len(prev + status.bytes_transferred() as usize);
// FIXME(#139616): justify why this is sound.
unsafe { self.dst.set_len(prev + status.bytes_transferred() as usize) };
if status.bytes_transferred() == 0 {
self.done = true;
}
}
}
// FIXME(#139616): document caller contract.
unsafe fn slice_to_end(v: &mut Vec<u8>) -> &mut [u8] {
if v.capacity() == 0 {
v.reserve(16);
@ -324,6 +336,12 @@ mod imp {
if v.capacity() == v.len() {
v.reserve(1);
}
slice::from_raw_parts_mut(v.as_mut_ptr().offset(v.len() as isize), v.capacity() - v.len())
// FIXME(#139616): justify why this is sound.
unsafe {
slice::from_raw_parts_mut(
v.as_mut_ptr().offset(v.len() as isize),
v.capacity() - v.len(),
)
}
}
}

View file

@ -177,6 +177,7 @@ pub fn compute_stamp_hash(config: &Config) -> String {
let mut hash = DefaultHasher::new();
config.stage_id.hash(&mut hash);
config.run.hash(&mut hash);
config.edition.hash(&mut hash);
match config.debugger {
Some(Debugger::Cdb) => {
@ -445,8 +446,8 @@ impl<'test> TestCx<'test> {
self.compose_and_run(
rustc,
self.config.compile_lib_path.to_str().unwrap(),
Some(aux_dir.to_str().unwrap()),
self.config.compile_lib_path.as_path(),
Some(aux_dir.as_path()),
src,
)
}
@ -968,16 +969,16 @@ impl<'test> TestCx<'test> {
delete_after_success: bool,
) -> ProcRes {
let prepare_env = |cmd: &mut Command| {
for key in &self.props.unset_exec_env {
cmd.env_remove(key);
}
for (key, val) in &self.props.exec_env {
cmd.env(key, val);
}
for (key, val) in env_extra {
cmd.env(key, val);
}
for key in &self.props.unset_exec_env {
cmd.env_remove(key);
}
};
let proc_res = match &*self.config.target {
@ -1020,8 +1021,8 @@ impl<'test> TestCx<'test> {
self.compose_and_run(
test_client,
self.config.run_lib_path.to_str().unwrap(),
Some(aux_dir.to_str().unwrap()),
self.config.run_lib_path.as_path(),
Some(aux_dir.as_path()),
None,
)
}
@ -1035,8 +1036,8 @@ impl<'test> TestCx<'test> {
self.compose_and_run(
wr_run,
self.config.run_lib_path.to_str().unwrap(),
Some(aux_dir.to_str().unwrap()),
self.config.run_lib_path.as_path(),
Some(aux_dir.as_path()),
None,
)
}
@ -1050,8 +1051,8 @@ impl<'test> TestCx<'test> {
self.compose_and_run(
program,
self.config.run_lib_path.to_str().unwrap(),
Some(aux_dir.to_str().unwrap()),
self.config.run_lib_path.as_path(),
Some(aux_dir.as_path()),
None,
)
}
@ -1197,8 +1198,8 @@ impl<'test> TestCx<'test> {
self.props.unset_rustc_env.iter().fold(&mut rustc, Command::env_remove);
self.compose_and_run(
rustc,
self.config.compile_lib_path.to_str().unwrap(),
Some(aux_dir.to_str().unwrap()),
self.config.compile_lib_path.as_path(),
Some(aux_dir.as_path()),
input,
)
}
@ -1219,8 +1220,7 @@ impl<'test> TestCx<'test> {
rustc.args(&["--crate-type", "rlib"]);
rustc.arg("-Cpanic=abort");
let res =
self.compose_and_run(rustc, self.config.compile_lib_path.to_str().unwrap(), None, None);
let res = self.compose_and_run(rustc, self.config.compile_lib_path.as_path(), None, None);
if !res.status.success() {
self.fatal_proc_rec(
&format!(
@ -1332,8 +1332,8 @@ impl<'test> TestCx<'test> {
let auxres = aux_cx.compose_and_run(
aux_rustc,
aux_cx.config.compile_lib_path.to_str().unwrap(),
Some(aux_dir.to_str().unwrap()),
aux_cx.config.compile_lib_path.as_path(),
Some(aux_dir.as_path()),
None,
);
if !auxres.status.success() {
@ -1373,8 +1373,8 @@ impl<'test> TestCx<'test> {
fn compose_and_run(
&self,
mut command: Command,
lib_path: &str,
aux_path: Option<&str>,
lib_path: &Path,
aux_path: Option<&Path>,
input: Option<String>,
) -> ProcRes {
let cmdline = {
@ -1806,7 +1806,7 @@ impl<'test> TestCx<'test> {
}
}
fn make_cmdline(&self, command: &Command, libpath: &str) -> String {
fn make_cmdline(&self, command: &Command, libpath: &Path) -> String {
use crate::util;
// Linux and mac don't require adjusting the library search path
@ -1819,7 +1819,7 @@ impl<'test> TestCx<'test> {
format!("{}=\"{}\"", util::lib_path_env_var(), util::make_new_path(path))
}
format!("{} {:?}", lib_path_cmd_prefix(libpath), command)
format!("{} {:?}", lib_path_cmd_prefix(libpath.to_str().unwrap()), command)
}
}
@ -1980,7 +1980,8 @@ impl<'test> TestCx<'test> {
// Add custom flags supplied by the `filecheck-flags:` test header.
filecheck.args(&self.props.filecheck_flags);
self.compose_and_run(filecheck, "", None, None)
// FIXME(jieyouxu): don't pass an empty Path
self.compose_and_run(filecheck, Path::new(""), None, None)
}
fn charset() -> &'static str {

View file

@ -104,7 +104,7 @@ impl TestCx<'_> {
let debugger_run_result = self.compose_and_run(
cdb,
self.config.run_lib_path.to_str().unwrap(),
self.config.run_lib_path.as_path(),
None, // aux_path
None, // input
);
@ -241,7 +241,8 @@ impl TestCx<'_> {
let cmdline = {
let mut gdb = Command::new(&format!("{}-gdb", self.config.target));
gdb.args(debugger_opts);
let cmdline = self.make_cmdline(&gdb, "");
// FIXME(jieyouxu): don't pass an empty Path
let cmdline = self.make_cmdline(&gdb, Path::new(""));
logv(self.config, format!("executing {}", cmdline));
cmdline
};
@ -340,7 +341,7 @@ impl TestCx<'_> {
gdb.args(debugger_opts).env("PYTHONPATH", pythonpath);
debugger_run_result =
self.compose_and_run(gdb, self.config.run_lib_path.to_str().unwrap(), None, None);
self.compose_and_run(gdb, self.config.run_lib_path.as_path(), None, None);
}
if !debugger_run_result.status.success() {

View file

@ -185,7 +185,7 @@ impl rustc_driver::Callbacks for MiriCompilerCalls {
let num_failed = sync::IntoDynSyncSend(AtomicU32::new(0));
sync::par_for_each_in(many_seeds.seeds.clone(), |seed| {
let mut config = config.clone();
config.seed = Some(seed.into());
config.seed = Some((*seed).into());
eprintln!("Trying seed: {seed}");
let return_code = miri::eval_entry(tcx, entry_def_id, entry_type, config)
.unwrap_or(rustc_driver::EXIT_FAILURE);

View file

@ -0,0 +1,30 @@
use std::mem::{size_of, align_of};
// See <https://github.com/rust-lang/rust/issues/134713>
#[repr(C)]
struct Foo(usize, u8);
fn main() {
let buf1: [usize; 2] = [1000, 2000];
let buf2: [usize; 2] = [3000, 4000];
// Foo and [usize; 2] have the same size and alignment,
// so swap_nonoverlapping should treat them the same
assert_eq!(size_of::<Foo>(), size_of::<[usize; 2]>());
assert_eq!(align_of::<Foo>(), align_of::<[usize; 2]>());
let mut b1 = buf1;
let mut b2 = buf2;
// Safety: b1 and b2 are distinct local variables,
// with the same size and alignment as Foo.
unsafe {
std::ptr::swap_nonoverlapping(
b1.as_mut_ptr().cast::<Foo>(),
b2.as_mut_ptr().cast::<Foo>(),
1,
);
}
assert_eq!(b1, buf2);
assert_eq!(b2, buf1);
}

View file

@ -361,7 +361,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
"rustc-demangle",
"rustc-hash",
"rustc-literal-escaper",
"rustc-rayon",
"rustc-rayon-core",
"rustc-stable-hash",
"rustc_apfloat",