Merge from rustc
This commit is contained in:
commit
f0ea91c60f
517 changed files with 5033 additions and 3792 deletions
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"""
|
||||
|
|
|
|||
|
|
@ -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![],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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"))
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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].
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ overall performance.
|
|||
## Target Maintainers
|
||||
|
||||
* [@Lokathor](https://github.com/lokathor)
|
||||
* [@corwinkuiper](https://github.com/corwinkuiper)
|
||||
|
||||
## Testing
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ pub(crate) trait DocFolder: Sized {
|
|||
| FunctionItem(_)
|
||||
| OpaqueTyItem(_)
|
||||
| StaticItem(_)
|
||||
| ConstantItem(_)
|
||||
| ConstantItem(_, _, _)
|
||||
| TraitAliasItem(_)
|
||||
| TyMethodItem(_)
|
||||
| MethodItem(_, _)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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) => {
|
||||
|
|
|
|||
|
|
@ -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(_)
|
||||
|
|
|
|||
|
|
@ -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(_)
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)))
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)| {
|
||||
|
|
|
|||
|
|
@ -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)?;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
26
src/tools/libcxx-version/main.cpp
Normal file
26
src/tools/libcxx-version/main.cpp
Normal 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;
|
||||
}
|
||||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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?
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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}"));
|
||||
|
|
|
|||
|
|
@ -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 }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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> {
|
||||
|
|
|
|||
|
|
@ -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) => {
|
||||
|
|
|
|||
|
|
@ -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 => "",
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue