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

View file

@ -7,6 +7,7 @@ default-run = "bootstrap"
[features]
build-metrics = ["sysinfo"]
bootstrap-self-test = [] # enabled in the bootstrap unit tests
[lib]
path = "src/lib.rs"

View file

@ -599,6 +599,12 @@ class RustBuild(object):
print('Choosing a pool size of', pool_size, 'for the unpacking of the tarballs')
p = Pool(pool_size)
try:
# FIXME: A cheap workaround for https://github.com/rust-lang/rust/issues/125578,
# remove this once the issue is closed.
bootstrap_out = self.bootstrap_out()
if os.path.exists(bootstrap_out):
shutil.rmtree(bootstrap_out)
p.map(unpack_component, tarballs_download_info)
finally:
p.close()
@ -864,6 +870,16 @@ class RustBuild(object):
return line[start + 1:end]
return None
def bootstrap_out(self):
"""Return the path of the bootstrap build artifacts
>>> rb = RustBuild()
>>> rb.build_dir = "build"
>>> rb.bootstrap_binary() == os.path.join("build", "bootstrap")
True
"""
return os.path.join(self.build_dir, "bootstrap")
def bootstrap_binary(self):
"""Return the path of the bootstrap binary
@ -873,7 +889,7 @@ class RustBuild(object):
... "debug", "bootstrap")
True
"""
return os.path.join(self.build_dir, "bootstrap", "debug", "bootstrap")
return os.path.join(self.bootstrap_out(), "debug", "bootstrap")
def build_bootstrap(self):
"""Build bootstrap"""

View file

@ -29,7 +29,7 @@ macro_rules! submodule_helper {
}
macro_rules! book {
($($name:ident, $path:expr, $book_name:expr $(, submodule $(= $submodule:literal)? )? ;)+) => {
($($name:ident, $path:expr, $book_name:expr, $lang:expr $(, submodule $(= $submodule:literal)? )? ;)+) => {
$(
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub struct $name {
@ -61,6 +61,7 @@ macro_rules! book {
name: $book_name.to_owned(),
src: builder.src.join($path),
parent: Some(self),
languages: $lang.into(),
})
}
}
@ -74,15 +75,15 @@ macro_rules! book {
// FIXME: Make checking for a submodule automatic somehow (maybe by having a list of all submodules
// and checking against it?).
book!(
CargoBook, "src/tools/cargo/src/doc", "cargo", submodule = "src/tools/cargo";
ClippyBook, "src/tools/clippy/book", "clippy";
EditionGuide, "src/doc/edition-guide", "edition-guide", submodule;
EmbeddedBook, "src/doc/embedded-book", "embedded-book", submodule;
Nomicon, "src/doc/nomicon", "nomicon", submodule;
Reference, "src/doc/reference", "reference", submodule;
RustByExample, "src/doc/rust-by-example", "rust-by-example", submodule;
RustdocBook, "src/doc/rustdoc", "rustdoc";
StyleGuide, "src/doc/style-guide", "style-guide";
CargoBook, "src/tools/cargo/src/doc", "cargo", &[], submodule = "src/tools/cargo";
ClippyBook, "src/tools/clippy/book", "clippy", &[];
EditionGuide, "src/doc/edition-guide", "edition-guide", &[], submodule;
EmbeddedBook, "src/doc/embedded-book", "embedded-book", &[], submodule;
Nomicon, "src/doc/nomicon", "nomicon", &[], submodule;
Reference, "src/doc/reference", "reference", &[], submodule;
RustByExample, "src/doc/rust-by-example", "rust-by-example", &["ja"], submodule;
RustdocBook, "src/doc/rustdoc", "rustdoc", &[];
StyleGuide, "src/doc/style-guide", "style-guide", &[];
);
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
@ -110,6 +111,7 @@ impl Step for UnstableBook {
name: "unstable-book".to_owned(),
src: builder.md_doc_out(self.target).join("unstable-book"),
parent: Some(self),
languages: vec![],
})
}
}
@ -120,6 +122,7 @@ struct RustbookSrc<P: Step> {
name: String,
src: PathBuf,
parent: Option<P>,
languages: Vec<&'static str>,
}
impl<P: Step> Step for RustbookSrc<P> {
@ -151,7 +154,19 @@ impl<P: Step> Step for RustbookSrc<P> {
builder.info(&format!("Rustbook ({target}) - {name}"));
let _ = fs::remove_dir_all(&out);
builder.run(rustbook_cmd.arg("build").arg(src).arg("-d").arg(out));
builder.run(rustbook_cmd.arg("build").arg(&src).arg("-d").arg(&out));
for lang in &self.languages {
let out = out.join(lang);
builder.info(&format!("Rustbook ({target}) - {name} - {lang}"));
let _ = fs::remove_dir_all(&out);
let mut rustbook_cmd = builder.tool_cmd(Tool::Rustbook);
builder.run(
rustbook_cmd.arg("build").arg(&src).arg("-d").arg(&out).arg("-l").arg(lang),
);
}
}
if self.parent.is_some() {
@ -214,6 +229,7 @@ impl Step for TheBook {
name: "book".to_owned(),
src: absolute_path.clone(),
parent: Some(self),
languages: vec![],
});
// building older edition redirects
@ -225,6 +241,7 @@ impl Step for TheBook {
// There should only be one book that is marked as the parent for each target, so
// treat the other editions as not having a parent.
parent: Option::<Self>::None,
languages: vec![],
});
}
@ -1208,6 +1225,7 @@ impl Step for RustcBook {
name: "rustc".to_owned(),
src: out_base,
parent: Some(self),
languages: vec![],
});
}
}

View file

@ -118,7 +118,9 @@ fn print_paths(verb: &str, adjective: Option<&str>, paths: &[String]) {
pub fn format(build: &Builder<'_>, check: bool, all: bool, paths: &[PathBuf]) {
if !paths.is_empty() {
eprintln!("fmt error: path arguments are not accepted");
eprintln!(
"fmt error: path arguments are no longer accepted; use `--all` to format everything"
);
crate::exit!(1);
};
if build.config.dry_run() {

View file

@ -3053,6 +3053,7 @@ impl Step for Bootstrap {
let mut cmd = Command::new(&builder.initial_cargo);
cmd.arg("test")
.args(["--features", "bootstrap-self-test"])
.current_dir(builder.src.join("src/bootstrap"))
.env("RUSTFLAGS", "-Cdebuginfo=2")
.env("CARGO_TARGET_DIR", builder.out.join("bootstrap"))

View file

@ -10,6 +10,7 @@ use crate::core::builder::{Builder, Cargo as CargoCommand, RunConfig, ShouldRun,
use crate::core::config::TargetSelection;
use crate::utils::channel::GitInfo;
use crate::utils::exec::BootstrapCommand;
use crate::utils::helpers::output;
use crate::utils::helpers::{add_dylib_path, exe, t};
use crate::Compiler;
use crate::Mode;
@ -804,6 +805,59 @@ impl Step for LlvmBitcodeLinker {
}
}
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub struct LibcxxVersionTool {
pub target: TargetSelection,
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub enum LibcxxVersion {
Gnu(usize),
Llvm(usize),
}
impl Step for LibcxxVersionTool {
type Output = LibcxxVersion;
const DEFAULT: bool = false;
const ONLY_HOSTS: bool = true;
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
run.never()
}
fn run(self, builder: &Builder<'_>) -> LibcxxVersion {
let out_dir = builder.out.join(self.target.to_string()).join("libcxx-version");
let _ = fs::remove_dir_all(&out_dir);
t!(fs::create_dir_all(&out_dir));
let compiler = builder.cxx(self.target).unwrap();
let mut cmd = Command::new(compiler);
let executable = out_dir.join(exe("libcxx-version", self.target));
cmd.arg("-o").arg(&executable).arg(builder.src.join("src/tools/libcxx-version/main.cpp"));
builder.run_cmd(&mut cmd);
if !executable.exists() {
panic!("Something went wrong. {} is not present", executable.display());
}
let version_output = output(&mut Command::new(executable));
let version_str = version_output.split_once("version:").unwrap().1;
let version = version_str.trim().parse::<usize>().unwrap();
if version_output.starts_with("libstdc++") {
LibcxxVersion::Gnu(version)
} else if version_output.starts_with("libc++") {
LibcxxVersion::Llvm(version)
} else {
panic!("Coudln't recognize the standard library version.");
}
}
}
macro_rules! tool_extended {
(($sel:ident, $builder:ident),
$($name:ident,

View file

@ -22,8 +22,6 @@ use crate::utils::cache::{Interned, INTERNER};
use crate::utils::channel::{self, GitInfo};
use crate::utils::helpers::{exe, output, t};
use build_helper::exit;
use build_helper::util::fail;
use semver::Version;
use serde::{Deserialize, Deserializer};
use serde_derive::Deserialize;
@ -2382,8 +2380,14 @@ impl Config {
}
}
// check rustc/cargo version is same or lower with 1 apart from the building one
#[cfg(feature = "bootstrap-self-test")]
pub fn check_stage0_version(&self, _program_path: &Path, _component_name: &'static str) {}
/// check rustc/cargo version is same or lower with 1 apart from the building one
#[cfg(not(feature = "bootstrap-self-test"))]
pub fn check_stage0_version(&self, program_path: &Path, component_name: &'static str) {
use build_helper::util::fail;
if self.dry_run() {
return;
}
@ -2400,11 +2404,12 @@ impl Config {
}
let stage0_version =
Version::parse(stage0_output.next().unwrap().split('-').next().unwrap().trim())
.unwrap();
let source_version =
Version::parse(fs::read_to_string(self.src.join("src/version")).unwrap().trim())
semver::Version::parse(stage0_output.next().unwrap().split('-').next().unwrap().trim())
.unwrap();
let source_version = semver::Version::parse(
fs::read_to_string(self.src.join("src/version")).unwrap().trim(),
)
.unwrap();
if !(source_version == stage0_version
|| (source_version.major == stage0_version.major
&& (source_version.minor == stage0_version.minor

View file

@ -14,16 +14,9 @@ use std::{
};
fn parse(config: &str) -> Config {
Config::parse_inner(
&[
"check".to_string(),
"--set=build.rustc=/does/not/exist".to_string(),
"--set=build.cargo=/does/not/exist".to_string(),
"--config=/does/not/exist".to_string(),
"--skip-stage0-validation".to_string(),
],
|&_| toml::from_str(&config).unwrap(),
)
Config::parse_inner(&["check".to_string(), "--config=/does/not/exist".to_string()], |&_| {
toml::from_str(&config).unwrap()
})
}
#[test]
@ -212,10 +205,7 @@ fn override_toml_duplicate() {
Config::parse_inner(
&[
"check".to_owned(),
"--set=build.rustc=/does/not/exist".to_string(),
"--set=build.cargo=/does/not/exist".to_string(),
"--config=/does/not/exist".to_owned(),
"--skip-stage0-validation".to_owned(),
"--config=/does/not/exist".to_string(),
"--set=change-id=1".to_owned(),
"--set=change-id=2".to_owned(),
],
@ -238,15 +228,7 @@ fn profile_user_dist() {
.and_then(|table: toml::Value| TomlConfig::deserialize(table))
.unwrap()
}
Config::parse_inner(
&[
"check".to_owned(),
"--set=build.rustc=/does/not/exist".to_string(),
"--set=build.cargo=/does/not/exist".to_string(),
"--skip-stage0-validation".to_string(),
],
get_toml,
);
Config::parse_inner(&["check".to_owned()], get_toml);
}
#[test]

View file

@ -9,11 +9,10 @@ use std::{
};
use build_helper::ci::CiEnv;
use build_helper::stage0_parser::VersionMetadata;
use xz2::bufread::XzDecoder;
use crate::utils::helpers::hex_encode;
use crate::utils::helpers::{check_run, exe, move_file, program_out_of_date};
use crate::{core::build_steps::llvm::detect_llvm_sha, utils::helpers::hex_encode};
use crate::{t, Config};
static SHOULD_FIX_BINS_AND_DYLIBS: OnceLock<bool> = OnceLock::new();
@ -405,9 +404,17 @@ impl Config {
cargo_clippy
}
#[cfg(feature = "bootstrap-self-test")]
pub(crate) fn maybe_download_rustfmt(&self) -> Option<PathBuf> {
None
}
/// NOTE: rustfmt is a completely different toolchain than the bootstrap compiler, so it can't
/// reuse target directories or artifacts
#[cfg(not(feature = "bootstrap-self-test"))]
pub(crate) fn maybe_download_rustfmt(&self) -> Option<PathBuf> {
use build_helper::stage0_parser::VersionMetadata;
let VersionMetadata { date, version } = self.stage0_metadata.rustfmt.as_ref()?;
let channel = format!("{version}-{date}");
@ -487,6 +494,10 @@ impl Config {
);
}
#[cfg(feature = "bootstrap-self-test")]
pub(crate) fn download_beta_toolchain(&self) {}
#[cfg(not(feature = "bootstrap-self-test"))]
pub(crate) fn download_beta_toolchain(&self) {
self.verbose(|| println!("downloading stage0 beta artifacts"));
@ -665,7 +676,13 @@ download-rustc = false
self.unpack(&tarball, &bin_root, prefix);
}
#[cfg(feature = "bootstrap-self-test")]
pub(crate) fn maybe_download_ci_llvm(&self) {}
#[cfg(not(feature = "bootstrap-self-test"))]
pub(crate) fn maybe_download_ci_llvm(&self) {
use crate::core::build_steps::llvm::detect_llvm_sha;
if !self.llvm_from_ci {
return;
}
@ -707,6 +724,7 @@ download-rustc = false
}
}
#[cfg(not(feature = "bootstrap-self-test"))]
fn download_ci_llvm(&self, llvm_sha: &str) {
let llvm_assertions = self.llvm_assertions;

View file

@ -8,13 +8,19 @@
//! In theory if we get past this phase it's a bug if a build fails, but in
//! practice that's likely not true!
use std::collections::{HashMap, HashSet};
use std::collections::HashMap;
use std::env;
use std::ffi::{OsStr, OsString};
use std::fs;
use std::path::PathBuf;
use std::process::Command;
use walkdir::WalkDir;
#[cfg(not(feature = "bootstrap-self-test"))]
use crate::builder::Builder;
#[cfg(not(feature = "bootstrap-self-test"))]
use crate::core::build_steps::tool;
#[cfg(not(feature = "bootstrap-self-test"))]
use std::collections::HashSet;
use crate::builder::Kind;
use crate::core::config::Target;
@ -31,10 +37,16 @@ pub struct Finder {
// it might not yet be included in stage0. In such cases, we handle the targets missing from stage0 in this list.
//
// Targets can be removed from this list once they are present in the stage0 compiler (usually by updating the beta compiler of the bootstrap).
#[cfg(not(feature = "bootstrap-self-test"))]
const STAGE0_MISSING_TARGETS: &[&str] = &[
// just a dummy comment so the list doesn't get onelined
];
/// Minimum version threshold for libstdc++ required when using prebuilt LLVM
/// from CI (with`llvm.download-ci-llvm` option).
#[cfg(not(feature = "bootstrap-self-test"))]
const LIBSTDCXX_MIN_VERSION_THRESHOLD: usize = 8;
impl Finder {
pub fn new() -> Self {
Self { cache: HashMap::new(), path: env::var_os("PATH").unwrap_or_default() }
@ -99,6 +111,32 @@ pub fn check(build: &mut Build) {
cmd_finder.must_have("git");
}
// Ensure that a compatible version of libstdc++ is available on the system when using `llvm.download-ci-llvm`.
#[cfg(not(feature = "bootstrap-self-test"))]
if !build.config.dry_run() && !build.build.is_msvc() && build.config.llvm_from_ci {
let builder = Builder::new(build);
let libcxx_version = builder.ensure(tool::LibcxxVersionTool { target: build.build });
match libcxx_version {
tool::LibcxxVersion::Gnu(version) => {
if LIBSTDCXX_MIN_VERSION_THRESHOLD > version {
eprintln!(
"\nYour system's libstdc++ version is too old for the `llvm.download-ci-llvm` option."
);
eprintln!("Current version detected: '{}'", version);
eprintln!("Minimum required version: '{}'", LIBSTDCXX_MIN_VERSION_THRESHOLD);
eprintln!(
"Consider upgrading libstdc++ or disabling the `llvm.download-ci-llvm` option."
);
crate::exit!(1);
}
}
tool::LibcxxVersion::Llvm(_) => {
// FIXME: Handle libc++ version check.
}
}
}
// We need cmake, but only if we're actually building LLVM or sanitizers.
let building_llvm = build
.hosts
@ -167,6 +205,7 @@ than building it.
.map(|p| cmd_finder.must_have(p))
.or_else(|| cmd_finder.maybe_have("reuse"));
#[cfg(not(feature = "bootstrap-self-test"))]
let stage0_supported_target_list: HashSet<String> =
output(Command::new(&build.config.initial_rustc).args(["--print", "target-list"]))
.lines()
@ -193,11 +232,11 @@ than building it.
continue;
}
let target_str = target.to_string();
// Ignore fake targets that are only used for unit tests in bootstrap.
if !["A-A", "B-B", "C-C"].contains(&target_str.as_str()) {
#[cfg(not(feature = "bootstrap-self-test"))]
{
let mut has_target = false;
let target_str = target.to_string();
let missing_targets_hashset: HashSet<_> =
STAGE0_MISSING_TARGETS.iter().map(|t| t.to_string()).collect();
@ -226,7 +265,7 @@ than building it.
target_filename.push(".json");
// Recursively traverse through nested directories.
let walker = WalkDir::new(custom_target_path).into_iter();
let walker = walkdir::WalkDir::new(custom_target_path).into_iter();
for entry in walker.filter_map(|e| e.ok()) {
has_target |= entry.file_name() == target_filename;
}

View file

@ -54,7 +54,7 @@ apt-get clean
# This makes all those symlinks.
for lib in $(find -name '*.so.*'); do
target=${lib%.so.*}.so
[ -e $target ] || ln -s ${lib##*/} $target
ln -s ${lib##*/} $target || echo "warning: silenced error symlinking $lib"
done
# Remove Solaris 11 functions that are optionally used by libbacktrace.

View file

@ -58,6 +58,7 @@ envs:
CACHES_AWS_ACCESS_KEY_ID: AKIA46X5W6CZI5DHEBFL
ARTIFACTS_AWS_ACCESS_KEY_ID: AKIA46X5W6CZN24CBO55
AWS_REGION: us-west-1
TOOLSTATE_PUBLISH: 1
try:
<<: *production

View file

@ -24,8 +24,8 @@ cd rust-toolstate
FAILURE=1
for RETRY_COUNT in 1 2 3 4 5; do
# The purpose of this is to publish the new "current" toolstate in the toolstate repo.
# This happens post-landing, on master.
# (Publishing the per-commit test results happens pre-landing in src/bootstrap/toolstate.rs).
# This happens at the end of auto builds.
# (Publishing the per-commit test results happens in src/bootstrap/toolstate.rs).
"$(ciCheckoutPath)/src/tools/publish_toolstate.py" "$GIT_COMMIT" \
"$GIT_COMMIT_MSG" \
"$MESSAGE_FILE" \

@ -1 +1 @@
Subproject commit 85442a608426d3667f1c9458ad457b241a36b569
Subproject commit 5228bfac8267ad24659a81b92ec5417976b5edbc

@ -1 +1 @@
Subproject commit 0c68e90acaae5a611f8f5098a3c2980de9845ab2
Subproject commit bbaabbe088e21a81a0d9ae6757705020d5d7b416

@ -1 +1 @@
Subproject commit dd962bb82865a5284f2404e5234f1e3222b9c022
Subproject commit b10c6acaf0f43481f6600e95d4b5013446e29f7a

@ -1 +1 @@
Subproject commit 0d5f88475fe285affa6dbbc806e9e44d730797c0
Subproject commit 0ebdacadbda8ce2cd8fbf93985e15af61a7ab895

@ -1 +1 @@
Subproject commit e356977fceaa8591c762312d8d446769166d4b3e
Subproject commit 6019b76f5b28938565b251bbba0bf5cc5c43d863

@ -1 +1 @@
Subproject commit 20482893d1a502df72f76762c97aed88854cdf81
Subproject commit 4840dca06cadf48b305d3ce0aeafde7f80933f80

@ -1 +1 @@
Subproject commit b6d4a4940bab85cc91eec70cc2e3096dd48da62d
Subproject commit 6a7374bd87cbac0f8be4fd4877d8186d9c313985

View file

@ -3,12 +3,12 @@
<!--
This page is currently (as of May 2024) the canonical place for describing the interaction
between Cargo and --check-cfg. It is placed in the rustc book rather than the Cargo book
since check-cfg is primarely a Rust/rustc feature and is therefor consider by T-cargo to
since check-cfg is primarily a Rust/rustc feature and is therefore considered by T-cargo to
be an implementation detail, at least --check-cfg and the unexpected_cfgs are owned by
rustc, not Cargo.
-->
This document is intented to summarize the principal ways Cargo interacts with
This document is intended to summarize the principal ways Cargo interacts with
the `unexpected_cfgs` lint and `--check-cfg` flag. It is not intended to provide
individual details, for that refer to the [`--check-cfg` documentation](../check-cfg.md) and
to the [Cargo book](../../cargo/index.html).
@ -17,7 +17,7 @@ to the [Cargo book](../../cargo/index.html).
*See the [`[features]` section in the Cargo book][cargo-features] for more details.*
With the `[features]` table Cargo provides a mechanism to express conditional compilation and
With the `[features]` table, Cargo provides a mechanism to express conditional compilation and
optional dependencies. Cargo *automatically* declares corresponding cfgs for every feature as
expected.
@ -32,16 +32,16 @@ my_feature = []
## `check-cfg` in `[lints.rust]` table
<!-- Note that T-Cargo considers `[lints.rust.unexpected_cfgs.check-cfg]` to be an
implementation detail and is therefor not documented in Cargo, we therefor do that ourself -->
<!-- Note that T-Cargo considers `lints.rust.unexpected_cfgs.check-cfg` to be an
implementation detail and is therefore documented here and not in Cargo. -->
*See the [`[lints]` section in the Cargo book][cargo-lints-table] for more details.*
When using a staticlly known custom config (ie. not dependant on a build-script), Cargo provides
When using a statically known custom config (i.e., not dependent on a build-script), Cargo provides
the custom lint config `check-cfg` under `[lints.rust.unexpected_cfgs]`.
It can be used to set custom static [`--check-cfg`](../check-cfg.md) args, it is mainly useful when
the list of expected cfgs is known is advance.
the list of expected cfgs is known in advance.
`Cargo.toml`:
```toml

View file

@ -33,12 +33,12 @@ All tier 1 targets with host tools support the full standard library.
target | notes
-------|-------
`aarch64-unknown-linux-gnu` | ARM64 Linux (kernel 4.1, glibc 2.17+)
`i686-pc-windows-gnu` | 32-bit MinGW (Windows 10+) [^x86_32-floats-return-ABI]
`i686-pc-windows-msvc` | 32-bit MSVC (Windows 10+) [^x86_32-floats-return-ABI]
`i686-pc-windows-gnu` | 32-bit MinGW (Windows 10+, Windows Server 2016+) [^x86_32-floats-return-ABI]
`i686-pc-windows-msvc` | 32-bit MSVC (Windows 10+, Windows Server 2016+) [^x86_32-floats-return-ABI]
`i686-unknown-linux-gnu` | 32-bit Linux (kernel 3.2+, glibc 2.17+) [^x86_32-floats-return-ABI]
[`x86_64-apple-darwin`](platform-support/apple-darwin.md) | 64-bit macOS (10.12+, Sierra+)
`x86_64-pc-windows-gnu` | 64-bit MinGW (Windows 10+)
`x86_64-pc-windows-msvc` | 64-bit MSVC (Windows 10+)
`x86_64-pc-windows-gnu` | 64-bit MinGW (Windows 10+, Windows Server 2016+)
`x86_64-pc-windows-msvc` | 64-bit MSVC (Windows 10+, Windows Server 2016+)
`x86_64-unknown-linux-gnu` | 64-bit Linux (kernel 3.2+, glibc 2.17+)
[^x86_32-floats-return-ABI]: Due to limitations of the C ABI, floating-point support on `i686` targets is non-compliant: floating-point return values are passed via an x87 register, so NaN payload bits can be lost. See [issue #114479][x86-32-float-issue].

View file

@ -12,6 +12,7 @@ overall performance.
## Target Maintainers
* [@Lokathor](https://github.com/lokathor)
* [@corwinkuiper](https://github.com/corwinkuiper)
## Testing

View file

@ -10,9 +10,9 @@ updatable, and performant.
The [Fuchsia team]:
- Tyler Mandry ([@tmandry](https://github.com/tmandry))
- Dan Johnson ([@computerdruid](https://github.com/computerdruid))
- David Koloski ([@djkoloski](https://github.com/djkoloski))
- Joseph Ryan ([@P1n3appl3](https://github.com/P1n3appl3))
- Julia Ryan ([@P1n3appl3](https://github.com/P1n3appl3))
- Erick Tryzelaar ([@erickt](https://github.com/erickt))
As the team evolves over time, the specific members listed here may differ from
the members reported by the API. The API should be considered to be

View file

@ -12,8 +12,9 @@ backend. The library must be of crate type `dylib` and must contain a function
named `__rustc_codegen_backend` with a signature of `fn() -> Box<dyn rustc_codegen_ssa::traits::CodegenBackend>`.
## Example
See also the [`hotplug_codegen_backend`](https://github.com/rust-lang/rust/tree/master/tests/run-make-fulldeps/hotplug_codegen_backend) test
for a full example.
See also the [`codegen-backend/hotplug`] test for a working example.
[`codegen-backend/hotplug`]: https://github.com/rust-lang/rust/tree/master/tests/ui-fulldeps/codegen-backend/hotplug.rs
```rust,ignore (partial-example)
use rustc_codegen_ssa::traits::CodegenBackend;

View file

@ -130,7 +130,10 @@ pub(crate) fn try_inline(
}
Res::Def(DefKind::Const, did) => {
record_extern_fqn(cx, did, ItemType::Constant);
cx.with_param_env(did, |cx| clean::ConstantItem(build_const(cx, did)))
cx.with_param_env(did, |cx| {
let (generics, ty, ct) = build_const_item(cx, did);
clean::ConstantItem(generics, Box::new(ty), ct)
})
}
Res::Def(DefKind::Macro(kind), did) => {
let is_doc_hidden = cx.tcx.is_doc_hidden(did)
@ -717,21 +720,20 @@ pub(crate) fn print_inlined_const(tcx: TyCtxt<'_>, did: DefId) -> String {
}
}
fn build_const(cx: &mut DocContext<'_>, def_id: DefId) -> clean::Constant {
fn build_const_item(
cx: &mut DocContext<'_>,
def_id: DefId,
) -> (clean::Generics, clean::Type, clean::Constant) {
let mut generics =
clean_ty_generics(cx, cx.tcx.generics_of(def_id), cx.tcx.explicit_predicates_of(def_id));
clean::simplify::move_bounds_to_generic_parameters(&mut generics);
clean::Constant {
type_: Box::new(clean_middle_ty(
ty::Binder::dummy(cx.tcx.type_of(def_id).instantiate_identity()),
cx,
Some(def_id),
None,
)),
generics,
kind: clean::ConstantKind::Extern { def_id },
}
let ty = clean_middle_ty(
ty::Binder::dummy(cx.tcx.type_of(def_id).instantiate_identity()),
cx,
None,
None,
);
(generics, ty, clean::Constant { kind: clean::ConstantKind::Extern { def_id } })
}
fn build_static(cx: &mut DocContext<'_>, did: DefId, mutable: bool) -> clean::Static {

View file

@ -283,31 +283,17 @@ fn clean_lifetime<'tcx>(lifetime: &hir::Lifetime, cx: &mut DocContext<'tcx>) ->
pub(crate) fn clean_const<'tcx>(
constant: &hir::ConstArg<'_>,
cx: &mut DocContext<'tcx>,
_cx: &mut DocContext<'tcx>,
) -> Constant {
let def_id = cx.tcx.hir().body_owner_def_id(constant.value.body).to_def_id();
Constant {
type_: Box::new(clean_middle_ty(
ty::Binder::dummy(cx.tcx.type_of(def_id).instantiate_identity()),
cx,
Some(def_id),
None,
)),
generics: Generics::default(),
kind: ConstantKind::Anonymous { body: constant.value.body },
}
Constant { kind: ConstantKind::Anonymous { body: constant.value.body } }
}
pub(crate) fn clean_middle_const<'tcx>(
constant: ty::Binder<'tcx, ty::Const<'tcx>>,
cx: &mut DocContext<'tcx>,
_cx: &mut DocContext<'tcx>,
) -> Constant {
// FIXME: instead of storing the stringified expression, store `self` directly instead.
Constant {
type_: Box::new(clean_middle_ty(constant.map_bound(|c| c.ty()), cx, None, None)),
generics: Generics::default(),
kind: ConstantKind::TyConst { expr: constant.skip_binder().to_string().into() },
}
Constant { kind: ConstantKind::TyConst { expr: constant.skip_binder().to_string().into() } }
}
pub(crate) fn clean_middle_region<'tcx>(region: ty::Region<'tcx>) -> Option<Lifetime> {
@ -2738,11 +2724,11 @@ fn clean_maybe_renamed_item<'tcx>(
ItemKind::Static(ty, mutability, body_id) => {
StaticItem(Static { type_: clean_ty(ty, cx), mutability, expr: Some(body_id) })
}
ItemKind::Const(ty, generics, body_id) => ConstantItem(Constant {
type_: Box::new(clean_ty(ty, cx)),
generics: clean_generics(generics, cx),
kind: ConstantKind::Local { body: body_id, def_id },
}),
ItemKind::Const(ty, generics, body_id) => ConstantItem(
clean_generics(generics, cx),
Box::new(clean_ty(ty, cx)),
Constant { kind: ConstantKind::Local { body: body_id, def_id } },
),
ItemKind::OpaqueTy(ref ty) => OpaqueTyItem(OpaqueTy {
bounds: ty.bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect(),
generics: clean_generics(ty.generics, cx),
@ -3089,7 +3075,9 @@ fn clean_maybe_renamed_foreign_item<'tcx>(
let def_id = item.owner_id.to_def_id();
cx.with_param_env(def_id, |cx| {
let kind = match item.kind {
hir::ForeignItemKind::Fn(decl, names, generics) => {
// FIXME(missing_unsafe_on_extern) handle safety of foreign fns.
// Safety was added as part of the implementation of unsafe extern blocks PR #124482
hir::ForeignItemKind::Fn(decl, names, generics, _) => {
let (generics, decl) = enter_impl_trait(cx, |cx| {
// NOTE: generics must be cleaned before args
let generics = clean_generics(generics, cx);
@ -3099,7 +3087,9 @@ fn clean_maybe_renamed_foreign_item<'tcx>(
});
ForeignFunctionItem(Box::new(Function { decl, generics }))
}
hir::ForeignItemKind::Static(ty, mutability) => {
// FIXME(missing_unsafe_on_extern) handle safety of foreign statics.
// Safety was added as part of the implementation of unsafe extern blocks PR #124482
hir::ForeignItemKind::Static(ty, mutability, _) => {
ForeignStaticItem(Static { type_: clean_ty(ty, cx), mutability, expr: None })
}
hir::ForeignItemKind::Type => ForeignTypeItem,

View file

@ -65,7 +65,7 @@ fn snippet_equal_to_token(tcx: TyCtxt<'_>, matcher: &TokenTree) -> Option<String
let psess = ParseSess::new(rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec());
let file_name = source_map.span_to_filename(span);
let mut parser =
match rustc_parse::maybe_new_parser_from_source_str(&psess, file_name, snippet.clone()) {
match rustc_parse::new_parser_from_source_str(&psess, file_name, snippet.clone()) {
Ok(parser) => parser,
Err(errs) => {
errs.into_iter().for_each(|err| err.cancel());

View file

@ -830,7 +830,6 @@ pub(crate) enum ItemKind {
TypeAliasItem(Box<TypeAlias>),
OpaqueTyItem(OpaqueTy),
StaticItem(Static),
ConstantItem(Constant),
TraitItem(Box<Trait>),
TraitAliasItem(TraitAlias),
ImplItem(Box<Impl>),
@ -853,6 +852,7 @@ pub(crate) enum ItemKind {
PrimitiveItem(PrimitiveType),
/// A required associated constant in a trait declaration.
TyAssocConstItem(Generics, Box<Type>),
ConstantItem(Generics, Box<Type>, Constant),
/// An associated constant in a trait impl or a provided one in a trait declaration.
AssocConstItem(Generics, Box<Type>, ConstantKind),
/// A required associated type in a trait declaration.
@ -888,7 +888,7 @@ impl ItemKind {
| TypeAliasItem(_)
| OpaqueTyItem(_)
| StaticItem(_)
| ConstantItem(_)
| ConstantItem(_, _, _)
| TraitAliasItem(_)
| TyMethodItem(_)
| MethodItem(_, _)
@ -922,7 +922,7 @@ impl ItemKind {
| TypeAliasItem(_)
| OpaqueTyItem(_)
| StaticItem(_)
| ConstantItem(_)
| ConstantItem(_, _, _)
| TraitAliasItem(_)
| ForeignFunctionItem(_)
| ForeignStaticItem(_)
@ -1936,7 +1936,7 @@ impl PrimitiveType {
let mut primitive_locations = FxHashMap::default();
// NOTE: technically this misses crates that are only passed with `--extern` and not loaded when checking the crate.
// This is a degenerate case that I don't plan to support.
for &crate_num in tcx.crates_including_speculative(()) {
for &crate_num in tcx.crates(()) {
let e = ExternalCrate { crate_num };
let crate_name = e.name(tcx);
debug!(?crate_num, ?crate_name);
@ -2364,8 +2364,6 @@ pub(crate) struct Static {
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub(crate) struct Constant {
pub(crate) type_: Box<Type>,
pub(crate) generics: Generics,
pub(crate) kind: ConstantKind,
}

View file

@ -353,8 +353,8 @@ pub(crate) fn print_const(cx: &DocContext<'_>, n: ty::Const<'_>) -> String {
s
}
// array lengths are obviously usize
ty::ConstKind::Value(ty::ValTree::Leaf(scalar))
if *n.ty().kind() == ty::Uint(ty::UintTy::Usize) =>
ty::ConstKind::Value(ty, ty::ValTree::Leaf(scalar))
if *ty.kind() == ty::Uint(ty::UintTy::Usize) =>
{
scalar.to_string()
}

View file

@ -347,7 +347,7 @@ pub(crate) fn run_global_ctxt(
show_coverage,
};
for cnum in tcx.crates_including_speculative(()) {
for cnum in tcx.crates(()) {
crate::visit_lib::lib_embargo_visit_item(&mut ctxt, cnum.as_def_id());
}

View file

@ -9,7 +9,7 @@ use rustc_interface::interface;
use rustc_middle::hir::map::Map;
use rustc_middle::hir::nested_filter;
use rustc_middle::ty::TyCtxt;
use rustc_parse::maybe_new_parser_from_source_str;
use rustc_parse::new_parser_from_source_str;
use rustc_parse::parser::attr::InnerAttrPolicy;
use rustc_resolve::rustdoc::span_of_fragments;
use rustc_session::config::{self, CrateType, ErrorOutputType};
@ -638,7 +638,7 @@ pub(crate) fn make_test(
let mut found_extern_crate = crate_name.is_none();
let mut found_macro = false;
let mut parser = match maybe_new_parser_from_source_str(&psess, filename, source) {
let mut parser = match new_parser_from_source_str(&psess, filename, source) {
Ok(p) => p,
Err(errs) => {
errs.into_iter().for_each(|err| err.cancel());
@ -818,16 +818,15 @@ fn check_if_attr_is_complete(source: &str, edition: Edition) -> bool {
let dcx = DiagCtxt::new(Box::new(emitter)).disable_warnings();
let psess = ParseSess::with_dcx(dcx, sm);
let mut parser =
match maybe_new_parser_from_source_str(&psess, filename, source.to_owned()) {
Ok(p) => p,
Err(errs) => {
errs.into_iter().for_each(|err| err.cancel());
// If there is an unclosed delimiter, an error will be returned by the
// tokentrees.
return false;
}
};
let mut parser = match new_parser_from_source_str(&psess, filename, source.to_owned()) {
Ok(p) => p,
Err(errs) => {
errs.into_iter().for_each(|err| err.cancel());
// If there is an unclosed delimiter, an error will be returned by the
// tokentrees.
return false;
}
};
// If a parsing error happened, it's very likely that the attribute is incomplete.
if let Err(e) = parser.parse_attribute(InnerAttrPolicy::Permitted) {
e.cancel();

View file

@ -79,7 +79,7 @@ pub(crate) trait DocFolder: Sized {
| FunctionItem(_)
| OpaqueTyItem(_)
| StaticItem(_)
| ConstantItem(_)
| ConstantItem(_, _, _)
| TraitAliasItem(_)
| TyMethodItem(_)
| MethodItem(_, _)

View file

@ -155,7 +155,7 @@ impl Cache {
// Cache where all our extern crates are located
// FIXME: this part is specific to HTML so it'd be nice to remove it from the common code
for &crate_num in tcx.crates_including_speculative(()) {
for &crate_num in tcx.crates(()) {
let e = ExternalCrate { crate_num };
let name = e.name(tcx);

View file

@ -1438,13 +1438,9 @@ impl clean::FnDecl {
{
write!(f, "\n{}", Indent(n + 4))?;
}
let last_input_index = self.inputs.values.len().checked_sub(1);
for (i, input) in self.inputs.values.iter().enumerate() {
if i > 0 {
match line_wrapping_indent {
None => write!(f, ", ")?,
Some(n) => write!(f, ",\n{}", Indent(n + 4))?,
};
}
if let Some(selfty) = input.to_self() {
match selfty {
clean::SelfValue => {
@ -1477,18 +1473,25 @@ impl clean::FnDecl {
write!(f, "{}: ", input.name)?;
input.type_.print(cx).fmt(f)?;
}
match (line_wrapping_indent, last_input_index) {
(_, None) => (),
(None, Some(last_i)) if i != last_i => write!(f, ", ")?,
(None, Some(_)) => (),
(Some(n), Some(last_i)) if i != last_i => write!(f, ",\n{}", Indent(n + 4))?,
(Some(_), Some(_)) => write!(f, ",\n")?,
}
}
if self.c_variadic {
match line_wrapping_indent {
None => write!(f, ", ...")?,
Some(n) => write!(f, "\n{}...", Indent(n + 4))?,
Some(n) => write!(f, "{}...\n", Indent(n + 4))?,
};
}
match line_wrapping_indent {
None => write!(f, ")")?,
Some(n) => write!(f, "\n{})", Indent(n))?,
Some(n) => write!(f, "{})", Indent(n))?,
};
self.print_output(cx).fmt(f)

View file

@ -266,7 +266,7 @@ pub(super) fn print_item(cx: &mut Context<'_>, item: &clean::Item, buf: &mut Buf
clean::ProcMacroItem(ref m) => item_proc_macro(buf, cx, item, m),
clean::PrimitiveItem(_) => item_primitive(buf, cx, item),
clean::StaticItem(ref i) | clean::ForeignStaticItem(ref i) => item_static(buf, cx, item, i),
clean::ConstantItem(ref c) => item_constant(buf, cx, item, c),
clean::ConstantItem(generics, ty, c) => item_constant(buf, cx, item, generics, ty, c),
clean::ForeignTypeItem => item_foreign_type(buf, cx, item),
clean::KeywordItem => item_keyword(buf, cx, item),
clean::OpaqueTyItem(ref e) => item_opaque_ty(buf, cx, item, e),
@ -1844,7 +1844,14 @@ fn item_primitive(w: &mut impl fmt::Write, cx: &mut Context<'_>, it: &clean::Ite
}
}
fn item_constant(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, c: &clean::Constant) {
fn item_constant(
w: &mut Buffer,
cx: &mut Context<'_>,
it: &clean::Item,
generics: &clean::Generics,
ty: &clean::Type,
c: &clean::Constant,
) {
wrap_item(w, |w| {
let tcx = cx.tcx();
render_attributes_in_code(w, it, cx);
@ -1854,9 +1861,9 @@ fn item_constant(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, c: &cle
"{vis}const {name}{generics}: {typ}{where_clause}",
vis = visibility_print_with_space(it, cx),
name = it.name.unwrap(),
generics = c.generics.print(cx),
typ = c.type_.print(cx),
where_clause = print_where_clause(&c.generics, cx, 0, Ending::NoNewline),
generics = generics.print(cx),
typ = ty.print(cx),
where_clause = print_where_clause(&generics, cx, 0, Ending::NoNewline),
);
// FIXME: The code below now prints

View file

@ -183,7 +183,7 @@ impl FromWithTcx<clean::Constant> for Constant {
let expr = constant.expr(tcx);
let value = constant.value(tcx);
let is_literal = constant.is_literal(tcx);
Constant { type_: (*constant.type_).into_tcx(tcx), expr, value, is_literal }
Constant { expr, value, is_literal }
}
}
@ -321,7 +321,10 @@ fn from_clean_item(item: clean::Item, tcx: TyCtxt<'_>) -> ItemEnum {
ForeignTypeItem => ItemEnum::ForeignType,
TypeAliasItem(t) => ItemEnum::TypeAlias(t.into_tcx(tcx)),
OpaqueTyItem(t) => ItemEnum::OpaqueTy(t.into_tcx(tcx)),
ConstantItem(c) => ItemEnum::Constant(c.into_tcx(tcx)),
// FIXME(generic_const_items): Add support for generic free consts
ConstantItem(_generics, t, c) => {
ItemEnum::Constant { type_: (*t).into_tcx(tcx), const_: c.into_tcx(tcx) }
}
MacroItem(m) => ItemEnum::Macro(m.source),
ProcMacroItem(m) => ItemEnum::ProcMacro(m.into_tcx(tcx)),
PrimitiveItem(p) => {

View file

@ -186,7 +186,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
| types::ItemEnum::Impl(_)
| types::ItemEnum::TypeAlias(_)
| types::ItemEnum::OpaqueTy(_)
| types::ItemEnum::Constant(_)
| types::ItemEnum::Constant { .. }
| types::ItemEnum::Static(_)
| types::ItemEnum::ForeignType
| types::ItemEnum::Macro(_)

View file

@ -62,7 +62,7 @@ pub(crate) fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -
| clean::AssocTypeItem(..)
| clean::TypeAliasItem(_)
| clean::StaticItem(_)
| clean::ConstantItem(_)
| clean::ConstantItem(_, _, _)
| clean::ExternCrateItem { .. }
| clean::ImportItem(_)
| clean::PrimitiveItem(_)

View file

@ -12,7 +12,7 @@ use rustc_errors::{Applicability, Diag, DiagMessage};
use rustc_hir::def::Namespace::*;
use rustc_hir::def::{DefKind, Namespace, PerNS};
use rustc_hir::def_id::{DefId, CRATE_DEF_ID};
use rustc_hir::Mutability;
use rustc_hir::{Mutability, Safety};
use rustc_middle::ty::{Ty, TyCtxt};
use rustc_middle::{bug, span_bug, ty};
use rustc_resolve::rustdoc::{has_primitive_or_keyword_docs, prepare_to_doc_link_resolution};
@ -1517,7 +1517,11 @@ impl Disambiguator {
"union" => Kind(DefKind::Union),
"module" | "mod" => Kind(DefKind::Mod),
"const" | "constant" => Kind(DefKind::Const),
"static" => Kind(DefKind::Static { mutability: Mutability::Not, nested: false }),
"static" => Kind(DefKind::Static {
mutability: Mutability::Not,
nested: false,
safety: Safety::Safe,
}),
"function" | "fn" | "method" => Kind(DefKind::Fn),
"derive" => Kind(DefKind::Macro(MacroKind::Derive)),
"type" => NS(Namespace::TypeNS),

View file

@ -47,7 +47,7 @@ pub(crate) fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) ->
// External trait impls.
{
let _prof_timer = tcx.sess.prof.generic_activity("build_extern_trait_impls");
for &cnum in tcx.crates_including_speculative(()) {
for &cnum in tcx.crates(()) {
for &impl_def_id in tcx.trait_impls_in_crate(cnum) {
cx.with_param_env(impl_def_id, |cx| {
inline::build_impl(cx, impl_def_id, None, &mut new_items_external);

View file

@ -5,7 +5,7 @@ use rustc_errors::{
translation::{to_fluent_args, Translate},
Applicability, DiagCtxt, DiagInner, LazyFallbackBundle,
};
use rustc_parse::parse_stream_from_source_str;
use rustc_parse::{source_str_to_stream, unwrap_or_emit_fatal};
use rustc_resolve::rustdoc::source_span_for_markdown_range;
use rustc_session::parse::ParseSess;
use rustc_span::hygiene::{AstPass, ExpnData, ExpnKind, LocalExpnId, Transparency};
@ -51,12 +51,12 @@ fn check_rust_syntax(
let span = DUMMY_SP.apply_mark(expn_id.to_expn_id(), Transparency::Transparent);
let is_empty = rustc_driver::catch_fatal_errors(|| {
parse_stream_from_source_str(
unwrap_or_emit_fatal(source_str_to_stream(
&psess,
FileName::Custom(String::from("doctest")),
source,
&psess,
Some(span),
)
))
.is_empty()
})
.unwrap_or(false);

View file

@ -283,7 +283,7 @@ pub(crate) fn run(
// Collect CrateIds corresponding to provided target crates
// If two different versions of the crate in the dependency tree, then examples will be collected from both.
let all_crates = tcx
.crates_including_speculative(())
.crates(())
.iter()
.chain([&LOCAL_CRATE])
.map(|crate_num| (crate_num, tcx.crate_name(*crate_num)))

View file

@ -28,7 +28,7 @@ pub(crate) trait DocVisitor: Sized {
| TypeAliasItem(_)
| OpaqueTyItem(_)
| StaticItem(_)
| ConstantItem(_)
| ConstantItem(_, _, _)
| TraitAliasItem(_)
| TyMethodItem(_)
| MethodItem(_, _)

@ -1 +1 @@
Subproject commit b31c30a9bb4dbbd13c359d0e2bea7f65d20adf3f
Subproject commit 5a5152f653959d14d68613a3a8a033fb65eec021

View file

@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize};
use std::path::PathBuf;
/// rustdoc format-version.
pub const FORMAT_VERSION: u32 = 29;
pub const FORMAT_VERSION: u32 = 30;
/// A `Crate` is the root of the emitted JSON blob. It contains all type/documentation information
/// about the language items in the local crate, as well as info about external items to allow
@ -167,8 +167,6 @@ pub enum GenericArg {
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Constant {
#[serde(rename = "type")]
pub type_: Type,
pub expr: String,
pub value: Option<String>,
pub is_literal: bool,
@ -256,7 +254,12 @@ pub enum ItemEnum {
TypeAlias(TypeAlias),
OpaqueTy(OpaqueTy),
Constant(Constant),
Constant {
#[serde(rename = "type")]
type_: Type,
#[serde(rename = "const")]
const_: Constant,
},
Static(Static),

@ -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",