Merge from rustc

This commit is contained in:
The Miri Cronjob Bot 2024-06-07 05:03:53 +00:00
commit f0ea91c60f
517 changed files with 5033 additions and 3792 deletions

@ -1 +1 @@
Subproject commit 7a6fad0984d28c8330974636972aa296b67c4513
Subproject commit 34a6a87d8a2330d8c9d578f927489689328a652d

View file

@ -8,7 +8,7 @@ use rustc_data_structures::sync::Lrc;
use rustc_errors::emitter::HumanEmitter;
use rustc_errors::{Diag, DiagCtxt};
use rustc_lint::LateContext;
use rustc_parse::maybe_new_parser_from_source_str;
use rustc_parse::new_parser_from_source_str;
use rustc_parse::parser::ForceCollect;
use rustc_session::parse::ParseSess;
use rustc_span::edition::Edition;
@ -50,7 +50,7 @@ pub fn check(
let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
let psess = ParseSess::with_dcx(dcx, sm);
let mut parser = match maybe_new_parser_from_source_str(&psess, filename, code) {
let mut parser = match new_parser_from_source_str(&psess, filename, code) {
Ok(p) => p,
Err(errs) => {
errs.into_iter().for_each(Diag::cancel);

View file

@ -54,7 +54,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeConstArrays {
&& generics.params.is_empty() && !generics.has_where_clause_predicates
&& let ty = cx.tcx.type_of(item.owner_id).instantiate_identity()
&& let ty::Array(element_type, cst) = ty.kind()
&& let ConstKind::Value(ty::ValTree::Leaf(element_count)) = cst.kind()
&& let ConstKind::Value(_, ty::ValTree::Leaf(element_count)) = cst.kind()
&& let Ok(element_count) = element_count.try_to_target_usize(cx.tcx)
&& let Ok(element_size) = cx.layout_of(*element_type).map(|l| l.size.bytes())
&& self.maximum_allowed_size < u128::from(element_count) * u128::from(element_size)

View file

@ -64,7 +64,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeStackArrays {
if let ExprKind::Repeat(_, _) | ExprKind::Array(_) = expr.kind
&& !self.is_from_vec_macro(cx, expr.span)
&& let ty::Array(element_type, cst) = cx.typeck_results().expr_ty(expr).kind()
&& let ConstKind::Value(ty::ValTree::Leaf(element_count)) = cst.kind()
&& let ConstKind::Value(_, ty::ValTree::Leaf(element_count)) = cst.kind()
&& let Ok(element_count) = element_count.try_to_target_usize(cx.tcx)
&& let Ok(element_size) = cx.layout_of(*element_type).map(|l| l.size.bytes())
&& !cx.tcx.hir().parent_iter(expr.hir_id).any(|(_, node)| {

View file

@ -37,14 +37,14 @@ fn all_ranges<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>], ty: Ty<'tcx>)
Some(lhs) => constant(cx, cx.typeck_results(), lhs)?,
None => {
let min_val_const = ty.numeric_min_val(cx.tcx)?;
mir_to_const(cx, mir::Const::from_ty_const(min_val_const, cx.tcx))?
mir_to_const(cx, mir::Const::from_ty_const(min_val_const, ty, cx.tcx))?
},
};
let rhs_const = match rhs {
Some(rhs) => constant(cx, cx.typeck_results(), rhs)?,
None => {
let max_val_const = ty.numeric_max_val(cx.tcx)?;
mir_to_const(cx, mir::Const::from_ty_const(max_val_const, cx.tcx))?
mir_to_const(cx, mir::Const::from_ty_const(max_val_const, ty, cx.tcx))?
},
};
let lhs_val = lhs_const.int_value(cx, ty)?;

View file

@ -55,7 +55,7 @@ impl LateLintPass<'_> for ZeroRepeatSideEffects {
inner_check(cx, expr, inner_expr, true);
} else if let ExprKind::Repeat(inner_expr, _) = expr.kind
&& let ty::Array(_, cst) = cx.typeck_results().expr_ty(expr).kind()
&& let ConstKind::Value(ty::ValTree::Leaf(element_count)) = cst.kind()
&& let ConstKind::Value(_, ty::ValTree::Leaf(element_count)) = cst.kind()
&& let Ok(element_count) = element_count.try_to_target_usize(cx.tcx)
&& element_count == 0
{

View file

@ -308,13 +308,15 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
ty: lt,
mutability: lm,
expr: le,
safety: ls,
}),
Static(box StaticItem {
ty: rt,
mutability: rm,
expr: re,
safety: rs,
}),
) => lm == rm && eq_ty(lt, rt) && eq_expr_opt(le, re),
) => lm == rm && ls == rs && eq_ty(lt, rt) && eq_expr_opt(le, re),
(
Const(box ConstItem {
defaultness: ld,
@ -451,13 +453,15 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool {
ty: lt,
mutability: lm,
expr: le,
safety: ls,
}),
Static(box StaticForeignItem {
ty: rt,
mutability: rm,
expr: re,
safety: rs,
}),
) => lm == rm && eq_ty(lt, rt) && eq_expr_opt(le, re),
) => lm == rm && eq_ty(lt, rt) && eq_expr_opt(le, re) && ls == rs,
(
Fn(box ast::Fn {
defaultness: ld,

View file

@ -647,7 +647,7 @@ fn item_children_by_name(tcx: TyCtxt<'_>, def_id: DefId, name: Symbol) -> Vec<Re
/// This function is expensive and should be used sparingly.
pub fn def_path_res(cx: &LateContext<'_>, path: &[&str]) -> Vec<Res> {
fn find_crates(tcx: TyCtxt<'_>, name: Symbol) -> impl Iterator<Item = DefId> + '_ {
tcx.crates_including_speculative(())
tcx.crates(())
.iter()
.copied()
.filter(move |&num| tcx.crate_name(num) == name)
@ -1534,7 +1534,7 @@ pub fn is_range_full(cx: &LateContext<'_>, expr: &Expr<'_>, container_path: Opti
if let rustc_ty::Adt(_, subst) = ty.kind()
&& let bnd_ty = subst.type_at(0)
&& let Some(min_val) = bnd_ty.numeric_min_val(cx.tcx)
&& let Some(min_const) = mir_to_const(cx, Const::from_ty_const(min_val, cx.tcx))
&& let Some(min_const) = mir_to_const(cx, Const::from_ty_const(min_val, bnd_ty, cx.tcx))
&& let Some(start_const) = constant(cx, cx.typeck_results(), start)
{
start_const == min_const
@ -1547,7 +1547,7 @@ pub fn is_range_full(cx: &LateContext<'_>, expr: &Expr<'_>, container_path: Opti
if let rustc_ty::Adt(_, subst) = ty.kind()
&& let bnd_ty = subst.type_at(0)
&& let Some(max_val) = bnd_ty.numeric_max_val(cx.tcx)
&& let Some(max_const) = mir_to_const(cx, Const::from_ty_const(max_val, cx.tcx))
&& let Some(max_const) = mir_to_const(cx, Const::from_ty_const(max_val, bnd_ty, cx.tcx))
&& let Some(end_const) = constant(cx, cx.typeck_results(), end)
{
end_const == max_const

View file

@ -94,7 +94,7 @@ pub struct TestProps {
// Extra flags to pass to the compiler
pub compile_flags: Vec<String>,
// Extra flags to pass when the compiled code is run (such as --bench)
pub run_flags: Option<String>,
pub run_flags: Vec<String>,
// If present, the name of a file that this test should match when
// pretty-printed
pub pp_exact: Option<PathBuf>,
@ -107,6 +107,9 @@ pub struct TestProps {
// Similar to `aux_builds`, but a list of NAME=somelib.rs of dependencies
// to build and pass with the `--extern` flag.
pub aux_crates: Vec<(String, String)>,
/// Similar to `aux_builds`, but also passes the resulting dylib path to
/// `-Zcodegen-backend`.
pub aux_codegen_backend: Option<String>,
// Environment settings to use for compiling
pub rustc_env: Vec<(String, String)>,
// Environment variables to unset prior to compiling.
@ -231,6 +234,7 @@ mod directives {
pub const AUX_BIN: &'static str = "aux-bin";
pub const AUX_BUILD: &'static str = "aux-build";
pub const AUX_CRATE: &'static str = "aux-crate";
pub const AUX_CODEGEN_BACKEND: &'static str = "aux-codegen-backend";
pub const EXEC_ENV: &'static str = "exec-env";
pub const RUSTC_ENV: &'static str = "rustc-env";
pub const UNSET_EXEC_ENV: &'static str = "unset-exec-env";
@ -262,11 +266,12 @@ impl TestProps {
error_patterns: vec![],
regex_error_patterns: vec![],
compile_flags: vec![],
run_flags: None,
run_flags: vec![],
pp_exact: None,
aux_builds: vec![],
aux_bins: vec![],
aux_crates: vec![],
aux_codegen_backend: None,
revisions: vec![],
rustc_env: vec![
("RUSTC_ICE".to_string(), "0".to_string()),
@ -399,7 +404,9 @@ impl TestProps {
config.parse_and_update_revisions(ln, &mut self.revisions);
config.set_name_value_directive(ln, RUN_FLAGS, &mut self.run_flags, |r| r);
if let Some(flags) = config.parse_name_value_directive(ln, RUN_FLAGS) {
self.run_flags.extend(split_flags(&flags));
}
if self.pp_exact.is_none() {
self.pp_exact = config.parse_pp_exact(ln, testfile);
@ -444,6 +451,9 @@ impl TestProps {
&mut self.aux_crates,
Config::parse_aux_crate,
);
if let Some(r) = config.parse_name_value_directive(ln, AUX_CODEGEN_BACKEND) {
self.aux_codegen_backend = Some(r.trim().to_owned());
}
config.push_name_value_directive(
ln,
EXEC_ENV,
@ -720,6 +730,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
"assembly-output",
"aux-bin",
"aux-build",
"aux-codegen-backend",
"aux-crate",
"build-aux-docs",
"build-fail",
@ -799,6 +810,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
"ignore-none",
"ignore-nto",
"ignore-nvptx64",
"ignore-nvptx64-nvidia-cuda",
"ignore-openbsd",
"ignore-pass",
"ignore-remote",
@ -1267,6 +1279,8 @@ fn expand_variables(mut value: String, config: &Config) -> String {
const CWD: &str = "{{cwd}}";
const SRC_BASE: &str = "{{src-base}}";
const BUILD_BASE: &str = "{{build-base}}";
const SYSROOT_BASE: &str = "{{sysroot-base}}";
const TARGET_LINKER: &str = "{{target-linker}}";
if value.contains(CWD) {
let cwd = env::current_dir().unwrap();
@ -1281,6 +1295,14 @@ fn expand_variables(mut value: String, config: &Config) -> String {
value = value.replace(BUILD_BASE, &config.build_base.to_string_lossy());
}
if value.contains(SYSROOT_BASE) {
value = value.replace(SYSROOT_BASE, &config.sysroot_base.to_string_lossy());
}
if value.contains(TARGET_LINKER) {
value = value.replace(TARGET_LINKER, config.target_linker.as_deref().unwrap_or(""));
}
value
}

View file

@ -1833,6 +1833,16 @@ impl<'test> TestCx<'test> {
));
}
}
// Build any `//@ aux-codegen-backend`, and pass the resulting library
// to `-Zcodegen-backend` when compiling the test file.
if let Some(aux_file) = &self.props.aux_codegen_backend {
let aux_type = self.build_auxiliary(of, aux_file, aux_dir, false);
if let Some(lib_name) = get_lib_name(aux_file.trim_end_matches(".rs"), aux_type) {
let lib_path = aux_dir.join(&lib_name);
rustc.arg(format!("-Zcodegen-backend={}", lib_path.display()));
}
}
}
fn compose_and_run_compiler(&self, mut rustc: Command, input: Option<String>) -> ProcRes {
@ -2254,6 +2264,9 @@ impl<'test> TestCx<'test> {
}
match output_file {
// If the test's compile flags specify an output path with `-o`,
// avoid a compiler warning about `--out-dir` being ignored.
_ if self.props.compile_flags.iter().any(|flag| flag == "-o") => {}
TargetLocation::ThisFile(path) => {
rustc.arg("-o").arg(path);
}
@ -2355,7 +2368,7 @@ impl<'test> TestCx<'test> {
args.push(exe_file.into_os_string());
// Add the arguments in the run_flags directive
args.extend(self.split_maybe_args(&self.props.run_flags));
args.extend(self.props.run_flags.iter().map(OsString::from));
let prog = args.remove(0);
ProcArgs { prog, args }
@ -2469,6 +2482,7 @@ impl<'test> TestCx<'test> {
}
}
#[track_caller]
fn fatal(&self, err: &str) -> ! {
self.error(err);
error!("fatal error, panic: {:?}", err);
@ -4173,10 +4187,12 @@ impl<'test> TestCx<'test> {
}
fn normalize_output(&self, output: &str, custom_rules: &[(String, String)]) -> String {
let rflags = self.props.run_flags.as_ref();
// Crude heuristic to detect when the output should have JSON-specific
// normalization steps applied.
let rflags = self.props.run_flags.join(" ");
let cflags = self.props.compile_flags.join(" ");
let json = rflags
.map_or(false, |s| s.contains("--format json") || s.contains("--format=json"))
let json = rflags.contains("--format json")
|| rflags.contains("--format=json")
|| cflags.contains("--error-format json")
|| cflags.contains("--error-format pretty-json")
|| cflags.contains("--error-format=json")

View file

@ -150,7 +150,7 @@ impl Kind {
ItemEnum::Impl(_) => Impl,
ItemEnum::TypeAlias(_) => TypeAlias,
ItemEnum::OpaqueTy(_) => OpaqueTy,
ItemEnum::Constant(_) => Constant,
ItemEnum::Constant { .. } => Constant,
ItemEnum::Static(_) => Static,
ItemEnum::Macro(_) => Macro,
ItemEnum::ProcMacro(_) => ProcMacro,

View file

@ -101,7 +101,10 @@ impl<'a> Validator<'a> {
ItemEnum::Impl(x) => self.check_impl(x, id),
ItemEnum::TypeAlias(x) => self.check_type_alias(x),
ItemEnum::OpaqueTy(x) => self.check_opaque_ty(x),
ItemEnum::Constant(x) => self.check_constant(x),
ItemEnum::Constant { type_, const_ } => {
self.check_type(type_);
self.check_constant(const_);
}
ItemEnum::Static(x) => self.check_static(x),
ItemEnum::ForeignType => {} // nop
ItemEnum::Macro(x) => self.check_macro(x),
@ -231,8 +234,8 @@ impl<'a> Validator<'a> {
self.check_generics(&x.generics);
}
fn check_constant(&mut self, x: &'a Constant) {
self.check_type(&x.type_);
fn check_constant(&mut self, _x: &'a Constant) {
// nop
}
fn check_static(&mut self, x: &'a Static) {

View file

@ -0,0 +1,26 @@
// Detecting the standard library version manually using a bunch of shell commands is very
// complicated and fragile across different platforms. This program provides the major version
// of the standard library on any target platform without requiring any messy work.
//
// It's nothing more than specifying the name of the standard library implementation (either libstdc++ or libc++)
// and its major version.
#include <iostream>
int main() {
#ifdef _GLIBCXX_RELEASE
std::cout << "libstdc++ version: " << _GLIBCXX_RELEASE << std::endl;
#elif defined(_LIBCPP_VERSION)
// _LIBCPP_VERSION follows "XXYYZZ" format (e.g., 170001 for 17.0.1).
// ref: https://github.com/llvm/llvm-project/blob/f64732195c1030ee2627ff4e4142038e01df1d26/libcxx/include/__config#L51-L54
//
// Since we use the major version from _GLIBCXX_RELEASE, we need to extract only the first 2 characters of _LIBCPP_VERSION
// to provide the major version for consistency.
std::cout << "libc++ version: " << std::to_string(_LIBCPP_VERSION).substr(0, 2) << std::endl;
#else
std::cerr << "Coudln't recognize the standard library version." << std::endl;
return 1;
#endif
return 0;
}

View file

@ -126,7 +126,7 @@ fn try_resolve_did(tcx: TyCtxt<'_>, path: &[&str], namespace: Option<Namespace>)
// the one in the sysroot and the one locally built by `cargo test`.)
// FIXME: can we prefer the one from the sysroot?
'crates: for krate in
tcx.used_crates(()).iter().filter(|&&krate| tcx.crate_name(krate).as_str() == crate_name)
tcx.crates(()).iter().filter(|&&krate| tcx.crate_name(krate).as_str() == crate_name)
{
let mut cur_item = DefId { krate: *krate, index: CRATE_DEF_INDEX };
// Go over the modules.
@ -1354,7 +1354,7 @@ pub fn get_local_crates(tcx: TyCtxt<'_>) -> Vec<CrateNum> {
.map(|crates| crates.split(',').map(|krate| krate.to_string()).collect::<Vec<_>>())
.unwrap_or_default();
let mut local_crates = Vec::new();
for &crate_num in tcx.crates_including_speculative(()) {
for &crate_num in tcx.crates(()) {
let name = tcx.crate_name(crate_num);
let name = name.as_str();
if local_crate_names.iter().any(|local_name| local_name == name) {

View file

@ -590,6 +590,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
.expect_const()
.eval(*this.tcx, this.param_env(), this.tcx.span)
.unwrap()
.1
.unwrap_branch();
let index_len = index.len();

View file

@ -83,12 +83,24 @@ fn main() {
test_abi_compat(main as fn(), id::<i32> as fn(i32) -> i32);
// - 1-ZST
test_abi_compat((), [0u8; 0]);
// - Guaranteed null-pointer-optimizations (RFC 3391).
// - Guaranteed Option<X> null-pointer-optimizations (RFC 3391).
test_abi_compat(&0u32 as *const u32, Some(&0u32));
test_abi_compat(main as fn(), Some(main as fn()));
test_abi_compat(0u32, Some(num::NonZero::new(1u32).unwrap()));
test_abi_compat(&0u32 as *const u32, Some(Wrapper(&0u32)));
test_abi_compat(0u32, Some(Wrapper(num::NonZero::new(1u32).unwrap())));
test_abi_compat(0u32, Some(Wrapper(num::NonZeroU32::new(1u32).unwrap())));
// - Guaranteed Result<X, ZST1> does the same as Option<X> (RFC 3391)
test_abi_compat(&0u32 as *const u32, Result::<_, ()>::Ok(&0u32));
test_abi_compat(main as fn(), Result::<_, ()>::Ok(main as fn()));
test_abi_compat(0u32, Result::<_, ()>::Ok(num::NonZeroU32::new(1).unwrap()));
test_abi_compat(&0u32 as *const u32, Result::<_, ()>::Ok(Wrapper(&0u32)));
test_abi_compat(0u32, Result::<_, ()>::Ok(Wrapper(num::NonZeroU32::new(1).unwrap())));
// - Guaranteed Result<ZST1, X> also does the same as Option<X> (RFC 3391)
test_abi_compat(&0u32 as *const u32, Result::<(), _>::Err(&0u32));
test_abi_compat(main as fn(), Result::<(), _>::Err(main as fn()));
test_abi_compat(0u32, Result::<(), _>::Err(num::NonZeroU32::new(1).unwrap()));
test_abi_compat(&0u32 as *const u32, Result::<(), _>::Err(Wrapper(&0u32)));
test_abi_compat(0u32, Result::<(), _>::Err(Wrapper(num::NonZeroU32::new(1).unwrap())));
// These must work for *any* type, since we guarantee that `repr(transparent)` is ABI-compatible
// with the wrapped field.

View file

@ -17,6 +17,9 @@ pub struct Environment {
host_llvm_dir: Utf8PathBuf,
/// List of test paths that should be skipped when testing the optimized artifacts.
skipped_tests: Vec<String>,
/// Arguments passed to `rustc-perf --cargo-config <value>` when running benchmarks.
#[builder(default)]
benchmark_cargo_config: Vec<String>,
/// Directory containing a pre-built rustc-perf checkout.
#[builder(default)]
prebuilt_rustc_perf: Option<Utf8PathBuf>,
@ -94,6 +97,10 @@ impl Environment {
pub fn skipped_tests(&self) -> &[String] {
&self.skipped_tests
}
pub fn benchmark_cargo_config(&self) -> &[String] {
&self.benchmark_cargo_config
}
}
/// What is the extension of binary executables on this platform?

View file

@ -90,6 +90,10 @@ enum EnvironmentCmd {
#[clap(flatten)]
shared: SharedArgs,
/// Arguments passed to `rustc-perf --cargo-config <value>` when running benchmarks.
#[arg(long)]
benchmark_cargo_config: Vec<String>,
},
/// Perform an optimized build on Linux CI, from inside Docker.
LinuxCi {
@ -119,6 +123,7 @@ fn create_environment(args: Args) -> anyhow::Result<(Environment, Vec<String>)>
llvm_shared,
use_bolt,
skipped_tests,
benchmark_cargo_config,
shared,
} => {
let env = EnvironmentBuilder::default()
@ -132,6 +137,7 @@ fn create_environment(args: Args) -> anyhow::Result<(Environment, Vec<String>)>
.shared_llvm(llvm_shared)
.use_bolt(use_bolt)
.skipped_tests(skipped_tests)
.benchmark_cargo_config(benchmark_cargo_config)
.build()?;
(env, shared.build_args)

View file

@ -36,7 +36,7 @@ fn init_compiler_benchmarks(
// Run rustc-perf benchmarks
// Benchmark using profile_local with eprintln, which essentially just means
// don't actually benchmark -- just make sure we run rustc a bunch of times.
cmd(&[
let mut cmd = cmd(&[
env.cargo_stage_0().as_str(),
"run",
"-p",
@ -61,7 +61,17 @@ fn init_compiler_benchmarks(
.env("RUST_LOG", "collector=debug")
.env("RUSTC", env.rustc_stage_0().as_str())
.env("RUSTC_BOOTSTRAP", "1")
.workdir(&env.rustc_perf_dir())
.workdir(&env.rustc_perf_dir());
// This propagates cargo configs to `rustc-perf --cargo-config`,
// which is particularly useful when the environment is air-gapped,
// and you want to use the default set of training crates vendored
// in the rustc-src tarball.
for config in env.benchmark_cargo_config() {
cmd = cmd.arg("--cargo-config").arg(config);
}
cmd
}
/// Describes which `llvm-profdata` binary should be used for merging PGO profiles.

View file

@ -1,8 +1,9 @@
use std::env;
use std::path::Path;
use std::process::Command;
use crate::{bin_name, cygpath_windows, handle_failed_output, is_msvc, is_windows, tmp_dir, uname};
use crate::{
bin_name, cygpath_windows, env_var, handle_failed_output, is_msvc, is_windows, tmp_dir, uname,
};
/// Construct a new platform-specific C compiler invocation.
///
@ -27,11 +28,11 @@ impl Cc {
/// WARNING: This means that what flags are accepted by the underlying C compile is
/// platform- AND compiler-specific. Consult the relevant docs for `gcc`, `clang` and `mvsc`.
pub fn new() -> Self {
let compiler = env::var("CC").unwrap();
let compiler = env_var("CC");
let mut cmd = Command::new(compiler);
let default_cflags = env::var("CC_DEFAULT_FLAGS").unwrap();
let default_cflags = env_var("CC_DEFAULT_FLAGS");
for flag in default_cflags.split(char::is_whitespace) {
cmd.arg(flag);
}

View file

@ -1,8 +1,7 @@
use std::env;
use std::path::Path;
use std::process::Command;
use crate::{bin_name, handle_failed_output, tmp_dir};
use crate::{bin_name, env_var, handle_failed_output, tmp_dir};
/// Construct a new `clang` invocation. `clang` is not always available for all targets.
pub fn clang() -> Clang {
@ -20,8 +19,7 @@ crate::impl_common_helpers!(Clang);
impl Clang {
/// Construct a new `clang` invocation. `clang` is not always available for all targets.
pub fn new() -> Self {
let clang =
env::var("CLANG").expect("`CLANG` not specified, but this is required to find `clang`");
let clang = env_var("CLANG");
let cmd = Command::new(clang);
Self { cmd }
}

View file

@ -12,6 +12,7 @@ pub mod rustc;
pub mod rustdoc;
use std::env;
use std::ffi::OsString;
use std::fs;
use std::io;
use std::path::{Path, PathBuf};
@ -30,14 +31,28 @@ pub use run::{run, run_fail};
pub use rustc::{aux_build, rustc, Rustc};
pub use rustdoc::{bare_rustdoc, rustdoc, Rustdoc};
pub fn env_var(name: &str) -> String {
match env::var(name) {
Ok(v) => v,
Err(err) => panic!("failed to retrieve environment variable {name:?}: {err:?}"),
}
}
pub fn env_var_os(name: &str) -> OsString {
match env::var_os(name) {
Some(v) => v,
None => panic!("failed to retrieve environment variable {name:?}"),
}
}
/// Path of `TMPDIR` (a temporary build directory, not under `/tmp`).
pub fn tmp_dir() -> PathBuf {
env::var_os("TMPDIR").unwrap().into()
env_var_os("TMPDIR").into()
}
/// `TARGET`
pub fn target() -> String {
env::var("TARGET").unwrap()
env_var("TARGET")
}
/// Check if target is windows-like.
@ -62,18 +77,19 @@ pub fn static_lib(name: &str) -> PathBuf {
}
pub fn python_command() -> Command {
let python_path = std::env::var("PYTHON").expect("PYTHON environment variable does not exist");
let python_path = env_var("PYTHON");
Command::new(python_path)
}
pub fn htmldocck() -> Command {
let mut python = python_command();
python.arg(source_path().join("src/etc/htmldocck.py"));
python.arg(source_root().join("src/etc/htmldocck.py"));
python
}
pub fn source_path() -> PathBuf {
std::env::var("S").expect("S variable does not exist").into()
/// Path to the root rust-lang/rust source checkout.
pub fn source_root() -> PathBuf {
env_var("S").into()
}
/// Construct the static library name based on the platform.
@ -208,12 +224,12 @@ fn handle_failed_output(cmd: &Command, output: Output, caller_line_number: u32)
/// Set the runtime library path as needed for running the host rustc/rustdoc/etc.
pub fn set_host_rpath(cmd: &mut Command) {
let ld_lib_path_envvar = env::var("LD_LIB_PATH_ENVVAR").unwrap();
let ld_lib_path_envvar = env_var("LD_LIB_PATH_ENVVAR");
cmd.env(&ld_lib_path_envvar, {
let mut paths = vec![];
paths.push(PathBuf::from(env::var("TMPDIR").unwrap()));
paths.push(PathBuf::from(env::var("HOST_RPATH_DIR").unwrap()));
for p in env::split_paths(&env::var(&ld_lib_path_envvar).unwrap()) {
paths.push(PathBuf::from(env_var("TMPDIR")));
paths.push(PathBuf::from(env_var("HOST_RPATH_DIR")));
for p in env::split_paths(&env_var(&ld_lib_path_envvar)) {
paths.push(p.to_path_buf());
}
env::join_paths(paths.iter()).unwrap()

View file

@ -1,8 +1,7 @@
use std::env;
use std::path::{Path, PathBuf};
use std::process::Command;
use crate::handle_failed_output;
use crate::{env_var, handle_failed_output};
/// Construct a new `llvm-readobj` invocation. This assumes that `llvm-readobj` is available
/// at `$LLVM_BIN_DIR/llvm-readobj`.
@ -22,8 +21,7 @@ impl LlvmReadobj {
/// Construct a new `llvm-readobj` invocation. This assumes that `llvm-readobj` is available
/// at `$LLVM_BIN_DIR/llvm-readobj`.
pub fn new() -> Self {
let llvm_bin_dir = env::var("LLVM_BIN_DIR")
.expect("`LLVM_BIN_DIR` not specified, but this is required to find `llvm-readobj`");
let llvm_bin_dir = env_var("LLVM_BIN_DIR");
let llvm_bin_dir = PathBuf::from(llvm_bin_dir);
let llvm_readobj = llvm_bin_dir.join("llvm-readobj");
let cmd = Command::new(llvm_readobj);

View file

@ -2,23 +2,23 @@ use std::env;
use std::path::{Path, PathBuf};
use std::process::{Command, Output};
use crate::is_windows;
use crate::{env_var, is_windows};
use super::handle_failed_output;
fn run_common(name: &str) -> (Command, Output) {
let mut bin_path = PathBuf::new();
bin_path.push(env::var("TMPDIR").unwrap());
bin_path.push(env_var("TMPDIR"));
bin_path.push(name);
let ld_lib_path_envvar = env::var("LD_LIB_PATH_ENVVAR").unwrap();
let ld_lib_path_envvar = env_var("LD_LIB_PATH_ENVVAR");
let mut cmd = Command::new(bin_path);
cmd.env(&ld_lib_path_envvar, {
let mut paths = vec![];
paths.push(PathBuf::from(env::var("TMPDIR").unwrap()));
for p in env::split_paths(&env::var("TARGET_RPATH_ENV").unwrap()) {
paths.push(PathBuf::from(env_var("TMPDIR")));
for p in env::split_paths(&env_var("TARGET_RPATH_ENV")) {
paths.push(p.to_path_buf());
}
for p in env::split_paths(&env::var(&ld_lib_path_envvar).unwrap()) {
for p in env::split_paths(&env_var(&ld_lib_path_envvar)) {
paths.push(p.to_path_buf());
}
env::join_paths(paths.iter()).unwrap()
@ -29,7 +29,7 @@ fn run_common(name: &str) -> (Command, Output) {
for p in env::split_paths(&std::env::var("PATH").unwrap_or(String::new())) {
paths.push(p.to_path_buf());
}
paths.push(Path::new(&std::env::var("TARGET_RPATH_DIR").unwrap()).to_path_buf());
paths.push(Path::new(&env_var("TARGET_RPATH_DIR")).to_path_buf());
cmd.env("PATH", env::join_paths(paths.iter()).unwrap());
}

View file

@ -1,10 +1,9 @@
use std::env;
use std::ffi::{OsStr, OsString};
use std::io::Write;
use std::path::Path;
use std::process::{Command, Output, Stdio};
use crate::{handle_failed_output, set_host_rpath, tmp_dir};
use crate::{env_var, handle_failed_output, set_host_rpath, tmp_dir};
/// Construct a new `rustc` invocation.
pub fn rustc() -> Rustc {
@ -26,7 +25,7 @@ pub struct Rustc {
crate::impl_common_helpers!(Rustc);
fn setup_common() -> Command {
let rustc = env::var("RUSTC").unwrap();
let rustc = env_var("RUSTC");
let mut cmd = Command::new(rustc);
set_host_rpath(&mut cmd);
cmd.arg("--out-dir").arg(tmp_dir()).arg("-L").arg(tmp_dir());
@ -70,6 +69,12 @@ impl Rustc {
self
}
/// Add a suffix in each output filename.
pub fn extra_filename(&mut self, suffix: &str) -> &mut Self {
self.cmd.arg(format!("-Cextra-filename={suffix}"));
self
}
/// Specify type(s) of output files to generate.
pub fn emit(&mut self, kinds: &str) -> &mut Self {
self.cmd.arg(format!("--emit={kinds}"));

View file

@ -1,10 +1,9 @@
use std::env;
use std::ffi::OsStr;
use std::io::Write;
use std::path::Path;
use std::process::{Command, Output, Stdio};
use crate::{handle_failed_output, set_host_rpath};
use crate::{env_var, env_var_os, handle_failed_output, set_host_rpath};
/// Construct a plain `rustdoc` invocation with no flags set.
pub fn bare_rustdoc() -> Rustdoc {
@ -25,7 +24,7 @@ pub struct Rustdoc {
crate::impl_common_helpers!(Rustdoc);
fn setup_common() -> Command {
let rustdoc = env::var("RUSTDOC").unwrap();
let rustdoc = env_var("RUSTDOC");
let mut cmd = Command::new(rustdoc);
set_host_rpath(&mut cmd);
cmd
@ -41,7 +40,7 @@ impl Rustdoc {
/// Construct a `rustdoc` invocation with `-L $(TARGET_RPATH_DIR)` set.
pub fn new() -> Self {
let mut cmd = setup_common();
let target_rpath_dir = env::var_os("TARGET_RPATH_DIR").unwrap();
let target_rpath_dir = env_var_os("TARGET_RPATH_DIR");
cmd.arg(format!("-L{}", target_rpath_dir.to_string_lossy()));
Self { cmd, stdin: None }
}

View file

@ -9,6 +9,7 @@ clap = "4.0.32"
env_logger = "0.11"
mdbook-trpl-listing = { path = "../../doc/book/packages/mdbook-trpl-listing" }
mdbook-trpl-note = { path = "../../doc/book/packages/mdbook-trpl-note" }
mdbook-i18n-helpers = "0.3.3"
[dependencies.mdbook]
version = "0.4.37"

View file

@ -7,6 +7,7 @@ use clap::{arg, ArgMatches, Command};
use mdbook::errors::Result as Result3;
use mdbook::MDBook;
use mdbook_i18n_helpers::preprocessors::Gettext;
use mdbook_trpl_listing::TrplListing;
use mdbook_trpl_note::TrplNote;
@ -19,6 +20,11 @@ fn main() {
.required(false)
.value_parser(clap::value_parser!(PathBuf));
let l_arg = arg!(-l --"lang" <LANGUAGE>
"The output language")
.required(false)
.value_parser(clap::value_parser!(String));
let dir_arg = arg!([dir] "Root directory for the book\n\
(Defaults to the current directory when omitted)")
.value_parser(clap::value_parser!(PathBuf));
@ -33,6 +39,7 @@ fn main() {
Command::new("build")
.about("Build the book from the markdown files")
.arg(d_arg)
.arg(l_arg)
.arg(&dir_arg),
)
.subcommand(
@ -63,6 +70,12 @@ pub fn build(args: &ArgMatches) -> Result3<()> {
let book_dir = get_book_dir(args);
let mut book = load_book(&book_dir)?;
if let Some(lang) = args.get_one::<String>("lang") {
let gettext = Gettext;
book.with_preprocessor(gettext);
book.config.set("book.language", lang).unwrap();
}
// Set this to allow us to catch bugs in advance.
book.config.build.create_missing = false;

@ -1 +1 @@
Subproject commit cc81f9654dac3fe08de286907dba747538417afd
Subproject commit 72daa50ce2350f5a9b5ae6dc3ad6babccd14ec0a

View file

@ -123,9 +123,7 @@ If you want to install the `browser-ui-test` dependency, run `npm install browse
cargo.env("RUSTDOCFLAGS", test_props.compile_flags.join(" "));
}
if let Some(flags) = &test_props.run_flags {
cargo.arg(flags);
}
cargo.args(&test_props.run_flags);
}
if try_run(&mut cargo, config.verbose).is_err() {

View file

@ -2,7 +2,7 @@ use rustc_ast::token::{Delimiter, NonterminalKind, TokenKind};
use rustc_ast::tokenstream::TokenStream;
use rustc_ast::{ast, ptr};
use rustc_parse::parser::{ForceCollect, Parser, Recovery};
use rustc_parse::{stream_to_parser, MACRO_ARGUMENTS};
use rustc_parse::MACRO_ARGUMENTS;
use rustc_session::parse::ParseSess;
use rustc_span::symbol::{self, kw};
use rustc_span::Symbol;
@ -15,7 +15,7 @@ pub(crate) mod cfg_if;
pub(crate) mod lazy_static;
fn build_stream_parser<'a>(psess: &'a ParseSess, tokens: TokenStream) -> Parser<'a> {
stream_to_parser(psess, tokens, MACRO_ARGUMENTS).recovery(Recovery::Forbidden)
Parser::new(psess, tokens, MACRO_ARGUMENTS).recovery(Recovery::Forbidden)
}
fn build_parser<'a>(context: &RewriteContext<'a>, tokens: TokenStream) -> Parser<'a> {

View file

@ -4,7 +4,8 @@ use std::path::{Path, PathBuf};
use rustc_ast::token::TokenKind;
use rustc_ast::{ast, attr, ptr};
use rustc_errors::Diag;
use rustc_parse::{new_parser_from_file, parser::Parser as RawParser};
use rustc_parse::parser::Parser as RawParser;
use rustc_parse::{new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal};
use rustc_span::{sym, Span};
use thin_vec::ThinVec;
@ -50,12 +51,9 @@ impl<'a> ParserBuilder<'a> {
let parser = match Self::parser(psess.inner(), input) {
Ok(p) => p,
Err(db) => {
if let Some(diagnostics) = db {
psess.emit_diagnostics(diagnostics);
return Err(ParserError::ParserCreationError);
}
return Err(ParserError::ParsePanicError);
Err(diagnostics) => {
psess.emit_diagnostics(diagnostics);
return Err(ParserError::ParserCreationError);
}
};
@ -65,18 +63,14 @@ impl<'a> ParserBuilder<'a> {
fn parser(
psess: &'a rustc_session::parse::ParseSess,
input: Input,
) -> Result<rustc_parse::parser::Parser<'a>, Option<Vec<Diag<'a>>>> {
) -> Result<RawParser<'a>, Vec<Diag<'a>>> {
match input {
Input::File(ref file) => catch_unwind(AssertUnwindSafe(move || {
new_parser_from_file(psess, file, None)
}))
.map_err(|_| None),
Input::Text(text) => rustc_parse::maybe_new_parser_from_source_str(
Input::File(ref file) => new_parser_from_file(psess, file, None),
Input::Text(text) => new_parser_from_source_str(
psess,
rustc_span::FileName::Custom("stdin".to_owned()),
text,
)
.map_err(Some),
),
}
}
}
@ -111,7 +105,8 @@ impl<'a> Parser<'a> {
span: Span,
) -> Result<(ast::AttrVec, ThinVec<ptr::P<ast::Item>>, Span), ParserError> {
let result = catch_unwind(AssertUnwindSafe(|| {
let mut parser = new_parser_from_file(psess.inner(), path, Some(span));
let mut parser =
unwrap_or_emit_fatal(new_parser_from_file(psess.inner(), path, Some(span)));
match parser.parse_mod(&TokenKind::Eof) {
Ok((a, i, spans)) => Some((a, i, spans.inner_span)),
Err(e) => {

View file

@ -111,6 +111,7 @@ pub(crate) fn format_defaultness(defaultness: ast::Defaultness) -> &'static str
pub(crate) fn format_safety(unsafety: ast::Safety) -> &'static str {
match unsafety {
ast::Safety::Unsafe(..) => "unsafe ",
ast::Safety::Safe(..) => "safe ",
ast::Safety::Default => "",
}
}

View file

@ -70,7 +70,6 @@ run-make/inaccessible-temp-dir/Makefile
run-make/include_bytes_deps/Makefile
run-make/incr-add-rust-src-component/Makefile
run-make/incr-foreign-head-span/Makefile
run-make/incr-prev-body-beyond-eof/Makefile
run-make/incremental-debugger-visualizer/Makefile
run-make/incremental-session-fail/Makefile
run-make/inline-always-many-cgu/Makefile
@ -136,7 +135,6 @@ run-make/lto-readonly-lib/Makefile
run-make/lto-smoke-c/Makefile
run-make/macos-deployment-target/Makefile
run-make/macos-fat-archive/Makefile
run-make/manual-crate-name/Makefile
run-make/manual-link/Makefile
run-make/many-crates-but-no-match/Makefile
run-make/metadata-dep-info/Makefile
@ -202,7 +200,6 @@ run-make/remap-path-prefix-dwarf/Makefile
run-make/remap-path-prefix/Makefile
run-make/reproducible-build-2/Makefile
run-make/reproducible-build/Makefile
run-make/resolve-rename/Makefile
run-make/return-non-c-like-enum-from-c/Makefile
run-make/return-non-c-like-enum/Makefile
run-make/rlib-chain/Makefile
@ -232,7 +229,6 @@ run-make/static-pie/Makefile
run-make/staticlib-blank-lib/Makefile
run-make/staticlib-dylib-linkage/Makefile
run-make/std-core-cycle/Makefile
run-make/suspicious-library/Makefile
run-make/symbol-mangling-hashed/Makefile
run-make/symbol-visibility/Makefile
run-make/symbols-include-type-name/Makefile

View file

@ -2445,7 +2445,6 @@ ui/issues/issue-53300.rs
ui/issues/issue-53333.rs
ui/issues/issue-53348.rs
ui/issues/issue-53419.rs
ui/issues/issue-53498.rs
ui/issues/issue-53568.rs
ui/issues/issue-5358-1.rs
ui/issues/issue-53728.rs

View file

@ -15,7 +15,7 @@ use std::path::{Path, PathBuf};
const ENTRY_LIMIT: u32 = 900;
// FIXME: The following limits should be reduced eventually.
const ISSUES_ENTRY_LIMIT: u32 = 1674;
const ISSUES_ENTRY_LIMIT: u32 = 1672;
const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
"rs", // test source files

View file

@ -16,6 +16,7 @@ pub fn filter_dirs(path: &Path) -> bool {
"library/stdarch",
"src/tools/cargo",
"src/tools/clippy",
"src/tools/libcxx-version",
"src/tools/miri",
"src/tools/rust-analyzer",
"src/tools/rustc-perf",