Merge from rust-lang/rust
This commit is contained in:
commit
28af7e0958
3689 changed files with 50553 additions and 31998 deletions
|
|
@ -65,7 +65,7 @@ dependencies = [
|
|||
"termcolor",
|
||||
"toml",
|
||||
"walkdir",
|
||||
"windows",
|
||||
"windows 0.52.0",
|
||||
"xz2",
|
||||
]
|
||||
|
||||
|
|
@ -378,12 +378,6 @@ dependencies = [
|
|||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
|
||||
[[package]]
|
||||
name = "opener"
|
||||
version = "0.5.2"
|
||||
|
|
@ -549,16 +543,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "sysinfo"
|
||||
version = "0.30.5"
|
||||
version = "0.31.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fb4f3438c8f6389c864e61221cbc97e9bca98b4daf39a5beb7bea660f528bb2"
|
||||
checksum = "d4115055da5f572fff541dd0c4e61b0262977f453cc9fe04be83aba25a89bdab"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
"memchr",
|
||||
"ntapi",
|
||||
"once_cell",
|
||||
"windows",
|
||||
"windows 0.57.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -655,7 +648,17 @@ version = "0.52.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be"
|
||||
dependencies = [
|
||||
"windows-core",
|
||||
"windows-core 0.52.0",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143"
|
||||
dependencies = [
|
||||
"windows-core 0.57.0",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
|
|
@ -668,6 +671,49 @@ dependencies = [
|
|||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d"
|
||||
dependencies = [
|
||||
"windows-implement",
|
||||
"windows-interface",
|
||||
"windows-result",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-implement"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-interface"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-result"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.52.0"
|
||||
|
|
@ -679,13 +725,14 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.0"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd"
|
||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
|
|
@ -694,45 +741,51 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.0"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea"
|
||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.0"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef"
|
||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.0"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313"
|
||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.0"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a"
|
||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.0"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd"
|
||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.0"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e"
|
||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.0"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "xattr"
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ walkdir = "2.4"
|
|||
xz2 = "0.1"
|
||||
|
||||
# Dependencies needed by the build-metrics feature
|
||||
sysinfo = { version = "0.30", default-features = false, optional = true }
|
||||
sysinfo = { version = "0.31.2", default-features = false, optional = true, features = ["system"] }
|
||||
|
||||
[target.'cfg(windows)'.dependencies.junction]
|
||||
version = "1.0.0"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
Change this file to make users of the `download-ci-llvm` configuration download
|
||||
a new version of LLVM from CI, even if the LLVM submodule hasn’t changed.
|
||||
|
||||
Last change is for: https://github.com/rust-lang/rust/pull/126298
|
||||
Last change is for: https://github.com/rust-lang/rust/pull/125642
|
||||
|
|
|
|||
|
|
@ -5,23 +5,25 @@
|
|||
//! parent directory, and otherwise documentation can be found throughout the `build`
|
||||
//! directory in each respective module.
|
||||
|
||||
use std::io::Write;
|
||||
use std::process;
|
||||
use std::fs::{self, OpenOptions};
|
||||
use std::io::{self, BufRead, BufReader, IsTerminal, Write};
|
||||
use std::str::FromStr;
|
||||
use std::{
|
||||
env,
|
||||
fs::{self, OpenOptions},
|
||||
io::{self, BufRead, BufReader, IsTerminal},
|
||||
};
|
||||
use std::{env, process};
|
||||
|
||||
use bootstrap::{
|
||||
find_recent_config_change_ids, human_readable_changes, t, Build, Config, Subcommand,
|
||||
find_recent_config_change_ids, human_readable_changes, t, Build, Config, Flags, Subcommand,
|
||||
CONFIG_CHANGE_HISTORY,
|
||||
};
|
||||
|
||||
fn main() {
|
||||
let args = env::args().skip(1).collect::<Vec<_>>();
|
||||
let config = Config::parse(&args);
|
||||
|
||||
if Flags::try_parse_verbose_help(&args) {
|
||||
return;
|
||||
}
|
||||
|
||||
let flags = Flags::parse(&args);
|
||||
let config = Config::parse(flags);
|
||||
|
||||
let mut build_lock;
|
||||
let _build_lock_guard;
|
||||
|
|
@ -30,10 +32,7 @@ fn main() {
|
|||
// Display PID of process holding the lock
|
||||
// PID will be stored in a lock file
|
||||
let lock_path = config.out.join("lock");
|
||||
let pid = match fs::read_to_string(&lock_path) {
|
||||
Ok(contents) => contents,
|
||||
Err(_) => String::new(),
|
||||
};
|
||||
let pid = fs::read_to_string(&lock_path).unwrap_or_default();
|
||||
|
||||
build_lock = fd_lock::RwLock::new(t!(fs::OpenOptions::new()
|
||||
.write(true)
|
||||
|
|
|
|||
|
|
@ -89,6 +89,25 @@ fn main() {
|
|||
rustc_real
|
||||
};
|
||||
|
||||
// Get the name of the crate we're compiling, if any.
|
||||
let crate_name = parse_value_from_args(&orig_args, "--crate-name");
|
||||
|
||||
// When statically linking `std` into `rustc_driver`, remove `-C prefer-dynamic`
|
||||
if env::var("RUSTC_LINK_STD_INTO_RUSTC_DRIVER").unwrap() == "1"
|
||||
&& crate_name == Some("rustc_driver")
|
||||
&& stage != "0"
|
||||
{
|
||||
if let Some(pos) = args.iter().enumerate().position(|(i, a)| {
|
||||
a == "-C" && args.get(i + 1).map(|a| a == "prefer-dynamic").unwrap_or(false)
|
||||
}) {
|
||||
args.remove(pos);
|
||||
args.remove(pos);
|
||||
}
|
||||
if let Some(pos) = args.iter().position(|a| a == "-Cprefer-dynamic") {
|
||||
args.remove(pos);
|
||||
}
|
||||
}
|
||||
|
||||
let mut cmd = match env::var_os("RUSTC_WRAPPER_REAL") {
|
||||
Some(wrapper) if !wrapper.is_empty() => {
|
||||
let mut cmd = Command::new(wrapper);
|
||||
|
|
@ -99,9 +118,6 @@ fn main() {
|
|||
};
|
||||
cmd.args(&args).env(dylib_path_var(), env::join_paths(&dylib_path).unwrap());
|
||||
|
||||
// Get the name of the crate we're compiling, if any.
|
||||
let crate_name = parse_value_from_args(&orig_args, "--crate-name");
|
||||
|
||||
if let Some(crate_name) = crate_name {
|
||||
if let Some(target) = env::var_os("RUSTC_TIME") {
|
||||
if target == "all"
|
||||
|
|
@ -315,12 +331,10 @@ fn format_rusage_data(_child: Child) -> Option<String> {
|
|||
fn format_rusage_data(child: Child) -> Option<String> {
|
||||
use std::os::windows::io::AsRawHandle;
|
||||
|
||||
use windows::{
|
||||
Win32::Foundation::HANDLE,
|
||||
Win32::System::ProcessStatus::{K32GetProcessMemoryInfo, PROCESS_MEMORY_COUNTERS},
|
||||
Win32::System::Threading::GetProcessTimes,
|
||||
Win32::System::Time::FileTimeToSystemTime,
|
||||
};
|
||||
use windows::Win32::Foundation::HANDLE;
|
||||
use windows::Win32::System::ProcessStatus::{K32GetProcessMemoryInfo, PROCESS_MEMORY_COUNTERS};
|
||||
use windows::Win32::System::Threading::GetProcessTimes;
|
||||
use windows::Win32::System::Time::FileTimeToSystemTime;
|
||||
|
||||
let handle = HANDLE(child.as_raw_handle() as isize);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
//! Implementation of compiling the compiler and standard library, in "check"-based modes.
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::core::build_steps::compile::{
|
||||
add_to_sysroot, run_cargo, rustc_cargo, rustc_cargo_env, std_cargo,
|
||||
add_to_sysroot, run_cargo, rustc_cargo, rustc_cargo_env, std_cargo, std_crates_for_run_make,
|
||||
};
|
||||
use crate::core::build_steps::tool::{prepare_tool_cargo, SourceType};
|
||||
use crate::core::builder::{
|
||||
|
|
@ -9,17 +11,6 @@ use crate::core::builder::{
|
|||
};
|
||||
use crate::core::config::TargetSelection;
|
||||
use crate::{Compiler, Mode, Subcommand};
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
pub fn cargo_subcommand(kind: Kind) -> &'static str {
|
||||
match kind {
|
||||
Kind::Check
|
||||
// We ensure check steps for both std and rustc from build_steps/clippy, so handle `Kind::Clippy` as well.
|
||||
| Kind::Clippy => "check",
|
||||
Kind::Fix => "fix",
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Std {
|
||||
|
|
@ -30,11 +21,18 @@ pub struct Std {
|
|||
///
|
||||
/// [`compile::Rustc`]: crate::core::build_steps::compile::Rustc
|
||||
crates: Vec<String>,
|
||||
/// Override `Builder::kind` on cargo invocations.
|
||||
///
|
||||
/// By default, `Builder::kind` is propagated as the subcommand to the cargo invocations.
|
||||
/// However, there are cases when this is not desirable. For example, when running `x clippy $tool_name`,
|
||||
/// passing `Builder::kind` to cargo invocations would run clippy on the entire compiler and library,
|
||||
/// which is not useful if we only want to lint a few crates with specific rules.
|
||||
override_build_kind: Option<Kind>,
|
||||
}
|
||||
|
||||
impl Std {
|
||||
pub fn new(target: TargetSelection) -> Self {
|
||||
Self { target, crates: vec![] }
|
||||
pub fn new_with_build_kind(target: TargetSelection, kind: Option<Kind>) -> Self {
|
||||
Self { target, crates: vec![], override_build_kind: kind }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -47,12 +45,12 @@ impl Step for Std {
|
|||
}
|
||||
|
||||
fn make_run(run: RunConfig<'_>) {
|
||||
let crates = run.make_run_crates(Alias::Library);
|
||||
run.builder.ensure(Std { target: run.target, crates });
|
||||
let crates = std_crates_for_run_make(&run);
|
||||
run.builder.ensure(Std { target: run.target, crates, override_build_kind: None });
|
||||
}
|
||||
|
||||
fn run(self, builder: &Builder<'_>) {
|
||||
builder.update_submodule(&Path::new("library").join("stdarch"));
|
||||
builder.require_submodule("library/stdarch", None);
|
||||
|
||||
let target = self.target;
|
||||
let compiler = builder.compiler(builder.top_stage, builder.config.build);
|
||||
|
|
@ -63,7 +61,7 @@ impl Step for Std {
|
|||
Mode::Std,
|
||||
SourceType::InTree,
|
||||
target,
|
||||
cargo_subcommand(builder.kind),
|
||||
self.override_build_kind.unwrap_or(builder.kind),
|
||||
);
|
||||
|
||||
std_cargo(builder, target, compiler.stage, &mut cargo);
|
||||
|
|
@ -117,7 +115,7 @@ impl Step for Std {
|
|||
Mode::Std,
|
||||
SourceType::InTree,
|
||||
target,
|
||||
cargo_subcommand(builder.kind),
|
||||
self.override_build_kind.unwrap_or(builder.kind),
|
||||
);
|
||||
|
||||
// If we're not in stage 0, tests and examples will fail to compile
|
||||
|
|
@ -158,16 +156,31 @@ pub struct Rustc {
|
|||
///
|
||||
/// [`compile::Rustc`]: crate::core::build_steps::compile::Rustc
|
||||
crates: Vec<String>,
|
||||
/// Override `Builder::kind` on cargo invocations.
|
||||
///
|
||||
/// By default, `Builder::kind` is propagated as the subcommand to the cargo invocations.
|
||||
/// However, there are cases when this is not desirable. For example, when running `x clippy $tool_name`,
|
||||
/// passing `Builder::kind` to cargo invocations would run clippy on the entire compiler and library,
|
||||
/// which is not useful if we only want to lint a few crates with specific rules.
|
||||
override_build_kind: Option<Kind>,
|
||||
}
|
||||
|
||||
impl Rustc {
|
||||
pub fn new(target: TargetSelection, builder: &Builder<'_>) -> Self {
|
||||
Self::new_with_build_kind(target, builder, None)
|
||||
}
|
||||
|
||||
pub fn new_with_build_kind(
|
||||
target: TargetSelection,
|
||||
builder: &Builder<'_>,
|
||||
kind: Option<Kind>,
|
||||
) -> Self {
|
||||
let crates = builder
|
||||
.in_tree_crates("rustc-main", Some(target))
|
||||
.into_iter()
|
||||
.map(|krate| krate.name.to_string())
|
||||
.collect();
|
||||
Self { target, crates }
|
||||
Self { target, crates, override_build_kind: kind }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -182,7 +195,7 @@ impl Step for Rustc {
|
|||
|
||||
fn make_run(run: RunConfig<'_>) {
|
||||
let crates = run.make_run_crates(Alias::Compiler);
|
||||
run.builder.ensure(Rustc { target: run.target, crates });
|
||||
run.builder.ensure(Rustc { target: run.target, crates, override_build_kind: None });
|
||||
}
|
||||
|
||||
/// Builds the compiler.
|
||||
|
|
@ -203,7 +216,7 @@ impl Step for Rustc {
|
|||
builder.ensure(crate::core::build_steps::compile::Std::new(compiler, compiler.host));
|
||||
builder.ensure(crate::core::build_steps::compile::Std::new(compiler, target));
|
||||
} else {
|
||||
builder.ensure(Std::new(target));
|
||||
builder.ensure(Std::new_with_build_kind(target, self.override_build_kind));
|
||||
}
|
||||
|
||||
let mut cargo = builder::Cargo::new(
|
||||
|
|
@ -212,7 +225,7 @@ impl Step for Rustc {
|
|||
Mode::Rustc,
|
||||
SourceType::InTree,
|
||||
target,
|
||||
cargo_subcommand(builder.kind),
|
||||
self.override_build_kind.unwrap_or(builder.kind),
|
||||
);
|
||||
|
||||
rustc_cargo(builder, &mut cargo, target, &compiler);
|
||||
|
|
@ -290,7 +303,7 @@ impl Step for CodegenBackend {
|
|||
Mode::Codegen,
|
||||
SourceType::InTree,
|
||||
target,
|
||||
cargo_subcommand(builder.kind),
|
||||
builder.kind,
|
||||
);
|
||||
|
||||
cargo
|
||||
|
|
@ -348,7 +361,7 @@ impl Step for RustAnalyzer {
|
|||
compiler,
|
||||
Mode::ToolRustc,
|
||||
target,
|
||||
cargo_subcommand(builder.kind),
|
||||
builder.kind,
|
||||
"src/tools/rust-analyzer",
|
||||
SourceType::InTree,
|
||||
&["in-rust-tree".to_owned()],
|
||||
|
|
@ -416,7 +429,7 @@ macro_rules! tool_check_step {
|
|||
compiler,
|
||||
Mode::ToolRustc,
|
||||
target,
|
||||
cargo_subcommand(builder.kind),
|
||||
builder.kind,
|
||||
$path,
|
||||
$source_type,
|
||||
&[],
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ use std::path::Path;
|
|||
|
||||
use crate::core::builder::{crate_description, Builder, RunConfig, ShouldRun, Step};
|
||||
use crate::utils::helpers::t;
|
||||
use crate::{Build, Compiler, Mode, Subcommand};
|
||||
use crate::{Build, Compiler, Kind, Mode, Subcommand};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct CleanAll {}
|
||||
|
|
@ -66,7 +66,7 @@ macro_rules! clean_crate_tree {
|
|||
fn run(self, builder: &Builder<'_>) -> Self::Output {
|
||||
let compiler = self.compiler;
|
||||
let target = compiler.host;
|
||||
let mut cargo = builder.bare_cargo(compiler, $mode, target, "clean");
|
||||
let mut cargo = builder.bare_cargo(compiler, $mode, target, Kind::Clean);
|
||||
|
||||
// Since https://github.com/rust-lang/rust/pull/111076 enables
|
||||
// unstable cargo feature (`public-dependency`), we need to ensure
|
||||
|
|
@ -121,7 +121,7 @@ fn clean(build: &Build, all: bool, stage: Option<u32>) {
|
|||
|
||||
fn clean_specific_stage(build: &Build, stage: u32) {
|
||||
for host in &build.hosts {
|
||||
let entries = match build.out.join(host.triple).read_dir() {
|
||||
let entries = match build.out.join(host).read_dir() {
|
||||
Ok(iter) => iter,
|
||||
Err(_) => continue,
|
||||
};
|
||||
|
|
@ -148,7 +148,7 @@ fn clean_default(build: &Build) {
|
|||
rm_rf(&build.out.join("bootstrap-shims-dump"));
|
||||
rm_rf(&build.out.join("rustfmt.stamp"));
|
||||
|
||||
let mut hosts: Vec<_> = build.hosts.iter().map(|t| build.out.join(t.triple)).collect();
|
||||
let mut hosts: Vec<_> = build.hosts.iter().map(|t| build.out.join(t)).collect();
|
||||
// After cross-compilation, artifacts of the host architecture (which may differ from build.host)
|
||||
// might not get removed.
|
||||
// Adding its path (linked one for easier accessibility) will solve this problem.
|
||||
|
|
|
|||
|
|
@ -1,28 +1,13 @@
|
|||
//! Implementation of running clippy on the compiler, standard library and various tools.
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
use crate::builder::Builder;
|
||||
use crate::builder::ShouldRun;
|
||||
use super::compile::{librustc_stamp, libstd_stamp, run_cargo, rustc_cargo, std_cargo};
|
||||
use super::tool::{prepare_tool_cargo, SourceType};
|
||||
use super::{check, compile};
|
||||
use crate::builder::{Builder, ShouldRun};
|
||||
use crate::core::build_steps::compile::std_crates_for_run_make;
|
||||
use crate::core::builder;
|
||||
use crate::core::builder::crate_description;
|
||||
use crate::core::builder::Alias;
|
||||
use crate::core::builder::Kind;
|
||||
use crate::core::builder::RunConfig;
|
||||
use crate::core::builder::Step;
|
||||
use crate::Mode;
|
||||
use crate::Subcommand;
|
||||
use crate::TargetSelection;
|
||||
|
||||
use super::check;
|
||||
use super::compile;
|
||||
use super::compile::librustc_stamp;
|
||||
use super::compile::libstd_stamp;
|
||||
use super::compile::run_cargo;
|
||||
use super::compile::rustc_cargo;
|
||||
use super::compile::std_cargo;
|
||||
use super::tool::prepare_tool_cargo;
|
||||
use super::tool::SourceType;
|
||||
use crate::core::builder::{crate_description, Alias, Kind, RunConfig, Step};
|
||||
use crate::{Mode, Subcommand, TargetSelection};
|
||||
|
||||
/// Disable the most spammy clippy lints
|
||||
const IGNORED_RULES_FOR_STD_AND_RUSTC: &[&str] = &[
|
||||
|
|
@ -122,18 +107,24 @@ impl Step for Std {
|
|||
}
|
||||
|
||||
fn make_run(run: RunConfig<'_>) {
|
||||
let crates = run.make_run_crates(Alias::Library);
|
||||
let crates = std_crates_for_run_make(&run);
|
||||
run.builder.ensure(Std { target: run.target, crates });
|
||||
}
|
||||
|
||||
fn run(self, builder: &Builder<'_>) {
|
||||
builder.update_submodule(&Path::new("library").join("stdarch"));
|
||||
builder.require_submodule("library/stdarch", None);
|
||||
|
||||
let target = self.target;
|
||||
let compiler = builder.compiler(builder.top_stage, builder.config.build);
|
||||
|
||||
let mut cargo =
|
||||
builder::Cargo::new(builder, compiler, Mode::Std, SourceType::InTree, target, "clippy");
|
||||
let mut cargo = builder::Cargo::new(
|
||||
builder,
|
||||
compiler,
|
||||
Mode::Std,
|
||||
SourceType::InTree,
|
||||
target,
|
||||
Kind::Clippy,
|
||||
);
|
||||
|
||||
std_cargo(builder, target, compiler.stage, &mut cargo);
|
||||
|
||||
|
|
@ -194,7 +185,7 @@ impl Step for Rustc {
|
|||
builder.ensure(compile::Std::new(compiler, compiler.host));
|
||||
builder.ensure(compile::Std::new(compiler, target));
|
||||
} else {
|
||||
builder.ensure(check::Std::new(target));
|
||||
builder.ensure(check::Std::new_with_build_kind(target, Some(Kind::Check)));
|
||||
}
|
||||
|
||||
let mut cargo = builder::Cargo::new(
|
||||
|
|
@ -203,7 +194,7 @@ impl Step for Rustc {
|
|||
Mode::Rustc,
|
||||
SourceType::InTree,
|
||||
target,
|
||||
"clippy",
|
||||
Kind::Clippy,
|
||||
);
|
||||
|
||||
rustc_cargo(builder, &mut cargo, target, &compiler);
|
||||
|
|
@ -261,14 +252,14 @@ macro_rules! lint_any {
|
|||
let compiler = builder.compiler(builder.top_stage, builder.config.build);
|
||||
let target = self.target;
|
||||
|
||||
builder.ensure(check::Rustc::new(target, builder));
|
||||
builder.ensure(check::Rustc::new_with_build_kind(target, builder, Some(Kind::Check)));
|
||||
|
||||
let cargo = prepare_tool_cargo(
|
||||
builder,
|
||||
compiler,
|
||||
Mode::ToolRustc,
|
||||
target,
|
||||
"clippy",
|
||||
Kind::Clippy,
|
||||
$path,
|
||||
SourceType::InTree,
|
||||
&[],
|
||||
|
|
|
|||
|
|
@ -8,31 +8,28 @@
|
|||
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashSet;
|
||||
use std::env;
|
||||
use std::ffi::OsStr;
|
||||
use std::fs;
|
||||
use std::io::prelude::*;
|
||||
use std::io::BufReader;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::Stdio;
|
||||
use std::str;
|
||||
use std::{env, fs, str};
|
||||
|
||||
use serde_derive::Deserialize;
|
||||
|
||||
use crate::core::build_steps::dist;
|
||||
use crate::core::build_steps::llvm;
|
||||
use crate::core::build_steps::tool::SourceType;
|
||||
use crate::core::build_steps::{dist, llvm};
|
||||
use crate::core::builder;
|
||||
use crate::core::builder::crate_description;
|
||||
use crate::core::builder::Cargo;
|
||||
use crate::core::builder::{Builder, Kind, PathSet, RunConfig, ShouldRun, Step, TaskPath};
|
||||
use crate::core::builder::{
|
||||
crate_description, Builder, Cargo, Kind, PathSet, RunConfig, ShouldRun, Step, TaskPath,
|
||||
};
|
||||
use crate::core::config::{DebuginfoLevel, LlvmLibunwind, RustcLto, TargetSelection};
|
||||
use crate::utils::exec::command;
|
||||
use crate::utils::helpers::{
|
||||
exe, get_clang_cl_resource_dir, is_debug_info, is_dylib, symlink_dir, t, up_to_date,
|
||||
self, exe, get_clang_cl_resource_dir, get_closest_merge_base_commit, is_debug_info, is_dylib,
|
||||
symlink_dir, t, up_to_date,
|
||||
};
|
||||
use crate::LLVM_TOOLS;
|
||||
use crate::{CLang, Compiler, DependencyType, GitRepo, Mode};
|
||||
use crate::{CLang, Compiler, DependencyType, GitRepo, Mode, LLVM_TOOLS};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct Std {
|
||||
|
|
@ -118,25 +115,43 @@ impl Step for Std {
|
|||
const DEFAULT: bool = true;
|
||||
|
||||
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
|
||||
// When downloading stage1, the standard library has already been copied to the sysroot, so
|
||||
// there's no need to rebuild it.
|
||||
let builder = run.builder;
|
||||
run.crate_or_deps("sysroot")
|
||||
.path("library")
|
||||
.lazy_default_condition(Box::new(|| !builder.download_rustc()))
|
||||
run.crate_or_deps("sysroot").path("library")
|
||||
}
|
||||
|
||||
fn make_run(run: RunConfig<'_>) {
|
||||
// If the paths include "library", build the entire standard library.
|
||||
let has_alias =
|
||||
run.paths.iter().any(|set| set.assert_single_path().path.ends_with("library"));
|
||||
let crates = if has_alias { Default::default() } else { run.cargo_crates_in_set() };
|
||||
let crates = std_crates_for_run_make(&run);
|
||||
let builder = run.builder;
|
||||
|
||||
// Force compilation of the standard library from source if the `library` is modified. This allows
|
||||
// library team to compile the standard library without needing to compile the compiler with
|
||||
// the `rust.download-rustc=true` option.
|
||||
let force_recompile =
|
||||
if builder.rust_info().is_managed_git_subrepository() && builder.download_rustc() {
|
||||
let closest_merge_commit = get_closest_merge_base_commit(
|
||||
Some(&builder.src),
|
||||
&builder.config.git_config(),
|
||||
&builder.config.stage0_metadata.config.git_merge_commit_email,
|
||||
&[],
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// Check if `library` has changes (returns false otherwise)
|
||||
!t!(helpers::git(Some(&builder.src))
|
||||
.args(["diff-index", "--quiet", &closest_merge_commit])
|
||||
.arg("--")
|
||||
.arg(builder.src.join("library"))
|
||||
.as_command_mut()
|
||||
.status())
|
||||
.success()
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
run.builder.ensure(Std {
|
||||
compiler: run.builder.compiler(run.builder.top_stage, run.build_triple()),
|
||||
target: run.target,
|
||||
crates,
|
||||
force_recompile: false,
|
||||
force_recompile,
|
||||
extra_rust_args: &[],
|
||||
is_for_mir_opt_tests: false,
|
||||
});
|
||||
|
|
@ -182,11 +197,16 @@ impl Step for Std {
|
|||
return;
|
||||
}
|
||||
|
||||
builder.update_submodule(&Path::new("library").join("stdarch"));
|
||||
builder.require_submodule("library/stdarch", None);
|
||||
|
||||
// Profiler information requires LLVM's compiler-rt
|
||||
if builder.config.profiler {
|
||||
builder.update_submodule(Path::new("src/llvm-project"));
|
||||
builder.require_submodule(
|
||||
"src/llvm-project",
|
||||
Some(
|
||||
"The `build.profiler` config option requires `compiler-rt` sources from LLVM.",
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
let mut target_deps = builder.ensure(StartupObjects { compiler, target });
|
||||
|
|
@ -226,7 +246,7 @@ impl Step for Std {
|
|||
.rustc_snapshot_sysroot()
|
||||
.join("lib")
|
||||
.join("rustlib")
|
||||
.join(compiler.host.triple)
|
||||
.join(compiler.host)
|
||||
.join("bin");
|
||||
if src_sysroot_bin.exists() {
|
||||
let target_sysroot_bin =
|
||||
|
|
@ -246,7 +266,7 @@ impl Step for Std {
|
|||
Mode::Std,
|
||||
SourceType::InTree,
|
||||
target,
|
||||
"check",
|
||||
Kind::Check,
|
||||
);
|
||||
cargo.rustflag("-Zalways-encode-mir");
|
||||
cargo.arg("--manifest-path").arg(builder.src.join("library/sysroot/Cargo.toml"));
|
||||
|
|
@ -258,7 +278,7 @@ impl Step for Std {
|
|||
Mode::Std,
|
||||
SourceType::InTree,
|
||||
target,
|
||||
"build",
|
||||
Kind::Build,
|
||||
);
|
||||
std_cargo(builder, target, compiler.stage, &mut cargo);
|
||||
for krate in &*self.crates {
|
||||
|
|
@ -412,7 +432,7 @@ fn copy_self_contained_objects(
|
|||
DependencyType::TargetSelfContained,
|
||||
);
|
||||
}
|
||||
} else if target.ends_with("windows-gnu") {
|
||||
} else if target.is_windows_gnu() {
|
||||
for obj in ["crt2.o", "dllcrt2.o"].iter() {
|
||||
let src = compiler_file(builder, &builder.cc(target), target, CLang::C, obj);
|
||||
let target = libdir_self_contained.join(obj);
|
||||
|
|
@ -424,6 +444,28 @@ fn copy_self_contained_objects(
|
|||
target_deps
|
||||
}
|
||||
|
||||
/// Resolves standard library crates for `Std::run_make` for any build kind (like check, build, clippy, etc.).
|
||||
pub fn std_crates_for_run_make(run: &RunConfig<'_>) -> Vec<String> {
|
||||
// FIXME: Extend builder tests to cover the `crates` field of `Std` instances.
|
||||
if cfg!(feature = "bootstrap-self-test") {
|
||||
return vec![];
|
||||
}
|
||||
|
||||
let has_alias = run.paths.iter().any(|set| set.assert_single_path().path.ends_with("library"));
|
||||
let target_is_no_std = run.builder.no_std(run.target).unwrap_or(false);
|
||||
|
||||
// For no_std targets, do not add any additional crates to the compilation other than what `compile::std_cargo` already adds for no_std targets.
|
||||
if target_is_no_std {
|
||||
vec![]
|
||||
}
|
||||
// If the paths include "library", build the entire standard library.
|
||||
else if has_alias {
|
||||
run.make_run_crates(builder::Alias::Library)
|
||||
} else {
|
||||
run.cargo_crates_in_set()
|
||||
}
|
||||
}
|
||||
|
||||
/// Configure cargo to compile the standard library, adding appropriate env vars
|
||||
/// and such.
|
||||
pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, cargo: &mut Cargo) {
|
||||
|
|
@ -456,13 +498,15 @@ pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, car
|
|||
// That's probably ok? At least, the difference wasn't enforced before. There's a comment in
|
||||
// the compiler_builtins build script that makes me nervous, though:
|
||||
// https://github.com/rust-lang/compiler-builtins/blob/31ee4544dbe47903ce771270d6e3bea8654e9e50/build.rs#L575-L579
|
||||
builder.update_submodule(&Path::new("src").join("llvm-project"));
|
||||
builder.require_submodule(
|
||||
"src/llvm-project",
|
||||
Some(
|
||||
"The `build.optimized-compiler-builtins` config option \
|
||||
requires `compiler-rt` sources from LLVM.",
|
||||
),
|
||||
);
|
||||
let compiler_builtins_root = builder.src.join("src/llvm-project/compiler-rt");
|
||||
if !compiler_builtins_root.exists() {
|
||||
panic!(
|
||||
"need LLVM sources available to build `compiler-rt`, but they weren't present; consider enabling `build.submodules = true` or disabling `optimized-compiler-builtins`"
|
||||
);
|
||||
}
|
||||
assert!(compiler_builtins_root.exists());
|
||||
// Note that `libprofiler_builtins/build.rs` also computes this so if
|
||||
// you're changing something here please also change that.
|
||||
cargo.env("RUST_COMPILER_RT_ROOT", &compiler_builtins_root);
|
||||
|
|
@ -607,8 +651,8 @@ impl Step for StdLink {
|
|||
compiler: self.compiler,
|
||||
force_recompile: self.force_recompile,
|
||||
});
|
||||
let libdir = sysroot.join(lib).join("rustlib").join(target.triple).join("lib");
|
||||
let hostdir = sysroot.join(lib).join("rustlib").join(compiler.host.triple).join("lib");
|
||||
let libdir = sysroot.join(lib).join("rustlib").join(target).join("lib");
|
||||
let hostdir = sysroot.join(lib).join("rustlib").join(compiler.host).join("lib");
|
||||
(libdir, hostdir)
|
||||
} else {
|
||||
let libdir = builder.sysroot_libdir(target_compiler, target);
|
||||
|
|
@ -626,12 +670,12 @@ impl Step for StdLink {
|
|||
.build
|
||||
.config
|
||||
.initial_rustc
|
||||
.starts_with(builder.out.join(compiler.host.triple).join("stage0/bin"))
|
||||
.starts_with(builder.out.join(compiler.host).join("stage0/bin"))
|
||||
{
|
||||
// Copy bin files from stage0/bin to stage0-sysroot/bin
|
||||
let sysroot = builder.out.join(compiler.host.triple).join("stage0-sysroot");
|
||||
let sysroot = builder.out.join(compiler.host).join("stage0-sysroot");
|
||||
|
||||
let host = compiler.host.triple;
|
||||
let host = compiler.host;
|
||||
let stage0_bin_dir = builder.out.join(host).join("stage0/bin");
|
||||
let sysroot_bin_dir = sysroot.join("bin");
|
||||
t!(fs::create_dir_all(&sysroot_bin_dir));
|
||||
|
|
@ -749,7 +793,7 @@ impl Step for StartupObjects {
|
|||
fn run(self, builder: &Builder<'_>) -> Vec<(PathBuf, DependencyType)> {
|
||||
let for_compiler = self.compiler;
|
||||
let target = self.target;
|
||||
if !target.ends_with("windows-gnu") {
|
||||
if !target.is_windows_gnu() {
|
||||
return vec![];
|
||||
}
|
||||
|
||||
|
|
@ -916,7 +960,7 @@ impl Step for Rustc {
|
|||
Mode::Rustc,
|
||||
SourceType::InTree,
|
||||
target,
|
||||
"build",
|
||||
Kind::Build,
|
||||
);
|
||||
|
||||
rustc_cargo(builder, &mut cargo, target, &compiler);
|
||||
|
|
@ -1356,7 +1400,7 @@ impl Step for CodegenBackend {
|
|||
Mode::Codegen,
|
||||
SourceType::InTree,
|
||||
target,
|
||||
"build",
|
||||
Kind::Build,
|
||||
);
|
||||
cargo
|
||||
.arg("--manifest-path")
|
||||
|
|
@ -1510,7 +1554,7 @@ impl Step for Sysroot {
|
|||
/// For all other stages, it's the same stage directory that the compiler lives in.
|
||||
fn run(self, builder: &Builder<'_>) -> PathBuf {
|
||||
let compiler = self.compiler;
|
||||
let host_dir = builder.out.join(compiler.host.triple);
|
||||
let host_dir = builder.out.join(compiler.host);
|
||||
|
||||
let sysroot_dir = |stage| {
|
||||
if stage == 0 {
|
||||
|
|
|
|||
|
|
@ -9,19 +9,17 @@
|
|||
//! pieces of `rustup.rs`!
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::env;
|
||||
use std::ffi::OsStr;
|
||||
use std::fs;
|
||||
use std::io::Write;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::{env, fs};
|
||||
|
||||
use object::read::archive::ArchiveFile;
|
||||
use object::BinaryFormat;
|
||||
|
||||
use crate::core::build_steps::compile;
|
||||
use crate::core::build_steps::doc::DocumentationFormat;
|
||||
use crate::core::build_steps::llvm;
|
||||
use crate::core::build_steps::tool::{self, Tool};
|
||||
use crate::core::build_steps::{compile, llvm};
|
||||
use crate::core::builder::{Builder, Kind, RunConfig, ShouldRun, Step};
|
||||
use crate::core::config::TargetSelection;
|
||||
use crate::utils::channel::{self, Info};
|
||||
|
|
@ -108,7 +106,6 @@ impl Step for JsonDocs {
|
|||
builder.ensure(crate::core::build_steps::doc::Std::new(
|
||||
builder.top_stage,
|
||||
host,
|
||||
builder,
|
||||
DocumentationFormat::Json,
|
||||
));
|
||||
|
||||
|
|
@ -278,12 +275,8 @@ fn make_win_dist(
|
|||
}
|
||||
|
||||
//Copy platform tools to platform-specific bin directory
|
||||
let target_bin_dir = plat_root
|
||||
.join("lib")
|
||||
.join("rustlib")
|
||||
.join(target.triple)
|
||||
.join("bin")
|
||||
.join("self-contained");
|
||||
let target_bin_dir =
|
||||
plat_root.join("lib").join("rustlib").join(target).join("bin").join("self-contained");
|
||||
fs::create_dir_all(&target_bin_dir).expect("creating target_bin_dir failed");
|
||||
for src in target_tools {
|
||||
builder.copy_link_to_folder(&src, &target_bin_dir);
|
||||
|
|
@ -298,12 +291,8 @@ fn make_win_dist(
|
|||
);
|
||||
|
||||
//Copy platform libs to platform-specific lib directory
|
||||
let target_lib_dir = plat_root
|
||||
.join("lib")
|
||||
.join("rustlib")
|
||||
.join(target.triple)
|
||||
.join("lib")
|
||||
.join("self-contained");
|
||||
let target_lib_dir =
|
||||
plat_root.join("lib").join("rustlib").join(target).join("lib").join("self-contained");
|
||||
fs::create_dir_all(&target_lib_dir).expect("creating target_lib_dir failed");
|
||||
for src in target_libs {
|
||||
builder.copy_link_to_folder(&src, &target_lib_dir);
|
||||
|
|
@ -453,7 +442,7 @@ impl Step for Rustc {
|
|||
// component for now.
|
||||
maybe_install_llvm_runtime(builder, host, image);
|
||||
|
||||
let dst_dir = image.join("lib/rustlib").join(&*host.triple).join("bin");
|
||||
let dst_dir = image.join("lib/rustlib").join(host).join("bin");
|
||||
t!(fs::create_dir_all(&dst_dir));
|
||||
|
||||
// Copy over lld if it's there
|
||||
|
|
@ -610,7 +599,7 @@ fn verify_uefi_rlib_format(builder: &Builder<'_>, target: TargetSelection, stamp
|
|||
|
||||
/// Copy stamped files into an image's `target/lib` directory.
|
||||
fn copy_target_libs(builder: &Builder<'_>, target: TargetSelection, image: &Path, stamp: &Path) {
|
||||
let dst = image.join("lib/rustlib").join(target.triple).join("lib");
|
||||
let dst = image.join("lib/rustlib").join(target).join("lib");
|
||||
let self_contained_dst = dst.join("self-contained");
|
||||
t!(fs::create_dir_all(&dst));
|
||||
t!(fs::create_dir_all(&self_contained_dst));
|
||||
|
|
@ -772,7 +761,7 @@ impl Step for Analysis {
|
|||
|
||||
let src = builder
|
||||
.stage_out(compiler, Mode::Std)
|
||||
.join(target.triple)
|
||||
.join(target)
|
||||
.join(builder.cargo_dir())
|
||||
.join("deps")
|
||||
.join("save-analysis");
|
||||
|
|
@ -907,7 +896,7 @@ impl Step for Src {
|
|||
/// Creates the `rust-src` installer component
|
||||
fn run(self, builder: &Builder<'_>) -> GeneratedTarball {
|
||||
if !builder.config.dry_run() {
|
||||
builder.update_submodule(Path::new("src/llvm-project"));
|
||||
builder.require_submodule("src/llvm-project", None);
|
||||
}
|
||||
|
||||
let tarball = Tarball::new_targetless(builder, "rust-src");
|
||||
|
|
@ -921,7 +910,6 @@ impl Step for Src {
|
|||
// translation code in `imported_source_files` in `src/librustc_metadata/rmeta/decoder.rs`
|
||||
let dst_src = tarball.image_dir().join("lib/rustlib/src/rust");
|
||||
|
||||
let src_files = ["Cargo.lock"];
|
||||
// This is the reduced set of paths which will become the rust-src component
|
||||
// (essentially libstd and all of its path dependencies).
|
||||
copy_src_dirs(
|
||||
|
|
@ -940,9 +928,6 @@ impl Step for Src {
|
|||
],
|
||||
&dst_src,
|
||||
);
|
||||
for file in src_files.iter() {
|
||||
builder.copy_link(&builder.src.join(file), &dst_src.join(file));
|
||||
}
|
||||
|
||||
tarball.generate()
|
||||
}
|
||||
|
|
@ -1022,10 +1007,7 @@ impl Step for PlainSourceTarball {
|
|||
// FIXME: This code looks _very_ similar to what we have in `src/core/build_steps/vendor.rs`
|
||||
// perhaps it should be removed in favor of making `dist` perform the `vendor` step?
|
||||
|
||||
// Ensure we have all submodules from src and other directories checked out.
|
||||
for submodule in build_helper::util::parse_gitmodules(&builder.src) {
|
||||
builder.update_submodule(Path::new(submodule));
|
||||
}
|
||||
builder.require_and_update_all_submodules();
|
||||
|
||||
// Vendor all Cargo dependencies
|
||||
let mut cmd = command(&builder.initial_cargo);
|
||||
|
|
@ -1040,6 +1022,8 @@ impl Step for PlainSourceTarball {
|
|||
.arg("--sync")
|
||||
.arg(builder.src.join("./compiler/rustc_codegen_gcc/Cargo.toml"))
|
||||
.arg("--sync")
|
||||
.arg(builder.src.join("./library/Cargo.toml"))
|
||||
.arg("--sync")
|
||||
.arg(builder.src.join("./src/bootstrap/Cargo.toml"))
|
||||
.arg("--sync")
|
||||
.arg(builder.src.join("./src/tools/opt-dist/Cargo.toml"))
|
||||
|
|
@ -1517,7 +1501,7 @@ impl Step for Extended {
|
|||
tarballs.push(builder.ensure(Rustc { compiler: builder.compiler(stage, target) }));
|
||||
tarballs.push(builder.ensure(Std { compiler, target }).expect("missing std"));
|
||||
|
||||
if target.ends_with("windows-gnu") {
|
||||
if target.is_windows_gnu() {
|
||||
tarballs.push(builder.ensure(Mingw { host: target }).expect("missing mingw"));
|
||||
}
|
||||
|
||||
|
|
@ -1691,7 +1675,7 @@ impl Step for Extended {
|
|||
prepare(tool);
|
||||
}
|
||||
}
|
||||
if target.ends_with("windows-gnu") {
|
||||
if target.is_windows_gnu() {
|
||||
prepare("rust-mingw");
|
||||
}
|
||||
|
||||
|
|
@ -1838,7 +1822,7 @@ impl Step for Extended {
|
|||
.arg("-t")
|
||||
.arg(etc.join("msi/remove-duplicates.xsl"))
|
||||
.run(builder);
|
||||
if target.ends_with("windows-gnu") {
|
||||
if target.is_windows_gnu() {
|
||||
command(&heat)
|
||||
.current_dir(&exe)
|
||||
.arg("dir")
|
||||
|
|
@ -1884,7 +1868,7 @@ impl Step for Extended {
|
|||
if built_tools.contains("miri") {
|
||||
cmd.arg("-dMiriDir=miri");
|
||||
}
|
||||
if target.ends_with("windows-gnu") {
|
||||
if target.is_windows_gnu() {
|
||||
cmd.arg("-dGccDir=rust-mingw");
|
||||
}
|
||||
cmd.run(builder);
|
||||
|
|
@ -1909,7 +1893,7 @@ impl Step for Extended {
|
|||
}
|
||||
candle("AnalysisGroup.wxs".as_ref());
|
||||
|
||||
if target.ends_with("windows-gnu") {
|
||||
if target.is_windows_gnu() {
|
||||
candle("GccGroup.wxs".as_ref());
|
||||
}
|
||||
|
||||
|
|
@ -1949,7 +1933,7 @@ impl Step for Extended {
|
|||
cmd.arg("DocsGroup.wixobj");
|
||||
}
|
||||
|
||||
if target.ends_with("windows-gnu") {
|
||||
if target.is_windows_gnu() {
|
||||
cmd.arg("GccGroup.wixobj");
|
||||
}
|
||||
// ICE57 wrongly complains about the shortcuts
|
||||
|
|
@ -1981,7 +1965,7 @@ fn add_env(builder: &Builder<'_>, cmd: &mut BootstrapCommand, target: TargetSele
|
|||
|
||||
if target.contains("windows-gnullvm") {
|
||||
cmd.env("CFG_MINGW", "1").env("CFG_ABI", "LLVM");
|
||||
} else if target.contains("windows-gnu") {
|
||||
} else if target.is_windows_gnu() {
|
||||
cmd.env("CFG_MINGW", "1").env("CFG_ABI", "GNU");
|
||||
} else {
|
||||
cmd.env("CFG_MINGW", "0").env("CFG_ABI", "MSVC");
|
||||
|
|
@ -2095,7 +2079,7 @@ fn maybe_install_llvm(
|
|||
|
||||
/// Maybe add libLLVM.so to the target lib-dir for linking.
|
||||
pub fn maybe_install_llvm_target(builder: &Builder<'_>, target: TargetSelection, sysroot: &Path) {
|
||||
let dst_libdir = sysroot.join("lib/rustlib").join(&*target.triple).join("lib");
|
||||
let dst_libdir = sysroot.join("lib/rustlib").join(target).join("lib");
|
||||
// We do not need to copy LLVM files into the sysroot if it is not
|
||||
// dynamically linked; it is already included into librustc_llvm
|
||||
// statically.
|
||||
|
|
@ -2128,8 +2112,13 @@ impl Step for LlvmTools {
|
|||
|
||||
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
|
||||
let default = should_build_extended_tool(run.builder, "llvm-tools");
|
||||
// FIXME: allow using the names of the tools themselves?
|
||||
run.alias("llvm-tools").default_condition(default)
|
||||
|
||||
let mut run = run.alias("llvm-tools");
|
||||
for tool in LLVM_TOOLS {
|
||||
run = run.alias(tool);
|
||||
}
|
||||
|
||||
run.default_condition(default)
|
||||
}
|
||||
|
||||
fn make_run(run: RunConfig<'_>) {
|
||||
|
|
@ -2137,6 +2126,32 @@ impl Step for LlvmTools {
|
|||
}
|
||||
|
||||
fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
|
||||
fn tools_to_install(paths: &[PathBuf]) -> Vec<&'static str> {
|
||||
let mut tools = vec![];
|
||||
|
||||
for path in paths {
|
||||
let path = path.to_str().unwrap();
|
||||
|
||||
// Include all tools if path is 'llvm-tools'.
|
||||
if path == "llvm-tools" {
|
||||
return LLVM_TOOLS.to_owned();
|
||||
}
|
||||
|
||||
for tool in LLVM_TOOLS {
|
||||
if path == *tool {
|
||||
tools.push(*tool);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If no specific tool is requested, include all tools.
|
||||
if tools.is_empty() {
|
||||
tools = LLVM_TOOLS.to_owned();
|
||||
}
|
||||
|
||||
tools
|
||||
}
|
||||
|
||||
let target = self.target;
|
||||
|
||||
/* run only if llvm-config isn't used */
|
||||
|
|
@ -2157,7 +2172,7 @@ impl Step for LlvmTools {
|
|||
// Prepare the image directory
|
||||
let src_bindir = builder.llvm_out(target).join("bin");
|
||||
let dst_bindir = format!("lib/rustlib/{}/bin", target.triple);
|
||||
for tool in LLVM_TOOLS {
|
||||
for tool in tools_to_install(&builder.paths) {
|
||||
let exe = src_bindir.join(exe(tool, target));
|
||||
tarball.add_file(&exe, &dst_bindir, 0o755);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,14 +9,15 @@
|
|||
|
||||
use std::io::{self, Write};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::{fs, mem};
|
||||
use std::{env, fs, mem};
|
||||
|
||||
use crate::core::build_steps::compile;
|
||||
use crate::core::build_steps::tool::{self, prepare_tool_cargo, SourceType, Tool};
|
||||
use crate::core::builder::{self, crate_description};
|
||||
use crate::core::builder::{Alias, Builder, Compiler, Kind, RunConfig, ShouldRun, Step};
|
||||
use crate::core::builder::{
|
||||
self, crate_description, Alias, Builder, Compiler, Kind, RunConfig, ShouldRun, Step,
|
||||
};
|
||||
use crate::core::config::{Config, TargetSelection};
|
||||
use crate::utils::helpers::{dir_is_empty, symlink_dir, t, up_to_date};
|
||||
use crate::utils::helpers::{symlink_dir, t, up_to_date};
|
||||
use crate::Mode;
|
||||
|
||||
macro_rules! submodule_helper {
|
||||
|
|
@ -53,8 +54,8 @@ macro_rules! book {
|
|||
|
||||
fn run(self, builder: &Builder<'_>) {
|
||||
$(
|
||||
let path = Path::new(submodule_helper!( $path, submodule $( = $submodule )? ));
|
||||
builder.update_submodule(&path);
|
||||
let path = submodule_helper!( $path, submodule $( = $submodule )? );
|
||||
builder.require_submodule(path, None);
|
||||
)?
|
||||
builder.ensure(RustbookSrc {
|
||||
target: self.target,
|
||||
|
|
@ -62,6 +63,7 @@ macro_rules! book {
|
|||
src: builder.src.join($path),
|
||||
parent: Some(self),
|
||||
languages: $lang.into(),
|
||||
rustdoc: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -80,7 +82,6 @@ book!(
|
|||
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", &[];
|
||||
|
|
@ -112,6 +113,7 @@ impl Step for UnstableBook {
|
|||
src: builder.md_doc_out(self.target).join("unstable-book"),
|
||||
parent: Some(self),
|
||||
languages: vec![],
|
||||
rustdoc: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -123,6 +125,7 @@ struct RustbookSrc<P: Step> {
|
|||
src: PathBuf,
|
||||
parent: Option<P>,
|
||||
languages: Vec<&'static str>,
|
||||
rustdoc: Option<PathBuf>,
|
||||
}
|
||||
|
||||
impl<P: Step> Step for RustbookSrc<P> {
|
||||
|
|
@ -153,13 +156,18 @@ impl<P: Step> Step for RustbookSrc<P> {
|
|||
builder.info(&format!("Rustbook ({target}) - {name}"));
|
||||
let _ = fs::remove_dir_all(&out);
|
||||
|
||||
builder
|
||||
.tool_cmd(Tool::Rustbook)
|
||||
.arg("build")
|
||||
.arg(&src)
|
||||
.arg("-d")
|
||||
.arg(&out)
|
||||
.run(builder);
|
||||
let mut rustbook_cmd = builder.tool_cmd(Tool::Rustbook);
|
||||
if let Some(mut rustdoc) = self.rustdoc {
|
||||
rustdoc.pop();
|
||||
let old_path = env::var_os("PATH").unwrap_or_default();
|
||||
let new_path =
|
||||
env::join_paths(std::iter::once(rustdoc).chain(env::split_paths(&old_path)))
|
||||
.expect("could not add rustdoc to PATH");
|
||||
|
||||
rustbook_cmd.env("PATH", new_path);
|
||||
}
|
||||
|
||||
rustbook_cmd.arg("build").arg(&src).arg("-d").arg(&out).run(builder);
|
||||
|
||||
for lang in &self.languages {
|
||||
let out = out.join(lang);
|
||||
|
|
@ -217,22 +225,14 @@ impl Step for TheBook {
|
|||
/// * Index page
|
||||
/// * Redirect pages
|
||||
fn run(self, builder: &Builder<'_>) {
|
||||
let relative_path = Path::new("src").join("doc").join("book");
|
||||
builder.update_submodule(&relative_path);
|
||||
builder.require_submodule("src/doc/book", None);
|
||||
|
||||
let compiler = self.compiler;
|
||||
let target = self.target;
|
||||
|
||||
let absolute_path = builder.src.join(&relative_path);
|
||||
let absolute_path = builder.src.join("src/doc/book");
|
||||
let redirect_path = absolute_path.join("redirects");
|
||||
if !absolute_path.exists()
|
||||
|| !redirect_path.exists()
|
||||
|| dir_is_empty(&absolute_path)
|
||||
|| dir_is_empty(&redirect_path)
|
||||
{
|
||||
eprintln!("Please checkout submodule: {}", relative_path.display());
|
||||
crate::exit!(1);
|
||||
}
|
||||
|
||||
// build book
|
||||
builder.ensure(RustbookSrc {
|
||||
target,
|
||||
|
|
@ -240,6 +240,7 @@ impl Step for TheBook {
|
|||
src: absolute_path.clone(),
|
||||
parent: Some(self),
|
||||
languages: vec![],
|
||||
rustdoc: None,
|
||||
});
|
||||
|
||||
// building older edition redirects
|
||||
|
|
@ -252,6 +253,7 @@ impl Step for TheBook {
|
|||
// treat the other editions as not having a parent.
|
||||
parent: Option::<Self>::None,
|
||||
languages: vec![],
|
||||
rustdoc: None,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -562,18 +564,8 @@ pub struct Std {
|
|||
}
|
||||
|
||||
impl Std {
|
||||
pub(crate) fn new(
|
||||
stage: u32,
|
||||
target: TargetSelection,
|
||||
builder: &Builder<'_>,
|
||||
format: DocumentationFormat,
|
||||
) -> Self {
|
||||
let crates = builder
|
||||
.in_tree_crates("sysroot", Some(target))
|
||||
.into_iter()
|
||||
.map(|krate| krate.name.to_string())
|
||||
.collect();
|
||||
Std { stage, target, format, crates }
|
||||
pub(crate) fn new(stage: u32, target: TargetSelection, format: DocumentationFormat) -> Self {
|
||||
Std { stage, target, format, crates: vec![] }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -587,6 +579,7 @@ impl Step for Std {
|
|||
}
|
||||
|
||||
fn make_run(run: RunConfig<'_>) {
|
||||
let crates = compile::std_crates_for_run_make(&run);
|
||||
run.builder.ensure(Std {
|
||||
stage: run.builder.top_stage,
|
||||
target: run.target,
|
||||
|
|
@ -595,7 +588,7 @@ impl Step for Std {
|
|||
} else {
|
||||
DocumentationFormat::Html
|
||||
},
|
||||
crates: run.make_run_crates(Alias::Library),
|
||||
crates,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -606,6 +599,16 @@ impl Step for Std {
|
|||
fn run(self, builder: &Builder<'_>) {
|
||||
let stage = self.stage;
|
||||
let target = self.target;
|
||||
let crates = if self.crates.is_empty() {
|
||||
builder
|
||||
.in_tree_crates("sysroot", Some(target))
|
||||
.iter()
|
||||
.map(|c| c.name.to_string())
|
||||
.collect()
|
||||
} else {
|
||||
self.crates
|
||||
};
|
||||
|
||||
let out = match self.format {
|
||||
DocumentationFormat::Html => builder.doc_out(target),
|
||||
DocumentationFormat::Json => builder.json_doc_out(target),
|
||||
|
|
@ -634,7 +637,7 @@ impl Step for Std {
|
|||
extra_args.push("--disable-minification");
|
||||
}
|
||||
|
||||
doc_std(builder, self.format, stage, target, &out, &extra_args, &self.crates);
|
||||
doc_std(builder, self.format, stage, target, &out, &extra_args, &crates);
|
||||
|
||||
// Don't open if the format is json
|
||||
if let DocumentationFormat::Json = self.format {
|
||||
|
|
@ -646,7 +649,7 @@ impl Step for Std {
|
|||
let index = out.join("std").join("index.html");
|
||||
builder.open_in_browser(index);
|
||||
} else {
|
||||
for requested_crate in &*self.crates {
|
||||
for requested_crate in crates {
|
||||
if STD_PUBLIC_CRATES.iter().any(|&k| k == requested_crate) {
|
||||
let index = out.join(requested_crate).join("index.html");
|
||||
builder.open_in_browser(index);
|
||||
|
|
@ -693,26 +696,18 @@ fn doc_std(
|
|||
extra_args: &[&str],
|
||||
requested_crates: &[String],
|
||||
) {
|
||||
if builder.no_std(target) == Some(true) {
|
||||
panic!(
|
||||
"building std documentation for no_std target {target} is not supported\n\
|
||||
Set `docs = false` in the config to disable documentation, or pass `--skip library`."
|
||||
);
|
||||
}
|
||||
|
||||
let compiler = builder.compiler(stage, builder.config.build);
|
||||
|
||||
let target_doc_dir_name = if format == DocumentationFormat::Json { "json-doc" } else { "doc" };
|
||||
let target_dir =
|
||||
builder.stage_out(compiler, Mode::Std).join(target.triple).join(target_doc_dir_name);
|
||||
let target_dir = builder.stage_out(compiler, Mode::Std).join(target).join(target_doc_dir_name);
|
||||
|
||||
// This is directory where the compiler will place the output of the command.
|
||||
// We will then copy the files from this directory into the final `out` directory, the specified
|
||||
// as a function parameter.
|
||||
let out_dir = target_dir.join(target.triple).join("doc");
|
||||
let out_dir = target_dir.join(target).join("doc");
|
||||
|
||||
let mut cargo =
|
||||
builder::Cargo::new(builder, compiler, Mode::Std, SourceType::InTree, target, "doc");
|
||||
builder::Cargo::new(builder, compiler, Mode::Std, SourceType::InTree, target, Kind::Doc);
|
||||
|
||||
compile::std_cargo(builder, target, compiler.stage, &mut cargo);
|
||||
cargo
|
||||
|
|
@ -814,8 +809,14 @@ impl Step for Rustc {
|
|||
);
|
||||
|
||||
// Build cargo command.
|
||||
let mut cargo =
|
||||
builder::Cargo::new(builder, compiler, Mode::Rustc, SourceType::InTree, target, "doc");
|
||||
let mut cargo = builder::Cargo::new(
|
||||
builder,
|
||||
compiler,
|
||||
Mode::Rustc,
|
||||
SourceType::InTree,
|
||||
target,
|
||||
Kind::Doc,
|
||||
);
|
||||
|
||||
cargo.rustdocflag("--document-private-items");
|
||||
// Since we always pass --document-private-items, there's no need to warn about linking to private items.
|
||||
|
|
@ -844,7 +845,7 @@ impl Step for Rustc {
|
|||
|
||||
let mut to_open = None;
|
||||
|
||||
let out_dir = builder.stage_out(compiler, Mode::Rustc).join(target.triple).join("doc");
|
||||
let out_dir = builder.stage_out(compiler, Mode::Rustc).join(target).join("doc");
|
||||
for krate in &*self.crates {
|
||||
// Create all crate output directories first to make sure rustdoc uses
|
||||
// relative links.
|
||||
|
|
@ -932,8 +933,8 @@ macro_rules! tool_doc {
|
|||
let _ = source_type; // silence the "unused variable" warning
|
||||
let source_type = SourceType::Submodule;
|
||||
|
||||
let path = Path::new(submodule_helper!( $path, submodule $( = $submodule )? ));
|
||||
builder.update_submodule(&path);
|
||||
let path = submodule_helper!( $path, submodule $( = $submodule )? );
|
||||
builder.require_submodule(path, None);
|
||||
)?
|
||||
|
||||
let stage = builder.top_stage;
|
||||
|
|
@ -962,7 +963,7 @@ macro_rules! tool_doc {
|
|||
compiler,
|
||||
Mode::ToolRustc,
|
||||
target,
|
||||
"doc",
|
||||
Kind::Doc,
|
||||
$path,
|
||||
source_type,
|
||||
&[],
|
||||
|
|
@ -990,7 +991,7 @@ macro_rules! tool_doc {
|
|||
// see https://github.com/rust-lang/rust/pull/122066#issuecomment-1983049222
|
||||
// cargo.rustdocflag("--generate-link-to-definition");
|
||||
|
||||
let out_dir = builder.stage_out(compiler, Mode::ToolRustc).join(target.triple).join("doc");
|
||||
let out_dir = builder.stage_out(compiler, Mode::ToolRustc).join(target).join("doc");
|
||||
$(for krate in $crates {
|
||||
let dir_name = krate.replace("-", "_");
|
||||
t!(fs::create_dir_all(out_dir.join(&*dir_name)));
|
||||
|
|
@ -1172,12 +1173,6 @@ impl Step for RustcBook {
|
|||
/// in the "md-doc" directory in the build output directory. Then
|
||||
/// "rustbook" is used to convert it to HTML.
|
||||
fn run(self, builder: &Builder<'_>) {
|
||||
// These submodules are required to be checked out to build rustbook
|
||||
// because they have Cargo dependencies that are needed.
|
||||
#[allow(clippy::single_element_loop)] // This will change soon.
|
||||
for path in ["src/doc/book"] {
|
||||
builder.update_submodule(Path::new(path));
|
||||
}
|
||||
let out_base = builder.md_doc_out(self.target).join("rustc");
|
||||
t!(fs::create_dir_all(&out_base));
|
||||
let out_listing = out_base.join("src/lints");
|
||||
|
|
@ -1228,6 +1223,50 @@ impl Step for RustcBook {
|
|||
src: out_base,
|
||||
parent: Some(self),
|
||||
languages: vec![],
|
||||
rustdoc: None,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Ord, PartialOrd, Debug, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct Reference {
|
||||
pub compiler: Compiler,
|
||||
pub target: TargetSelection,
|
||||
}
|
||||
|
||||
impl Step for Reference {
|
||||
type Output = ();
|
||||
const DEFAULT: bool = true;
|
||||
|
||||
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
|
||||
let builder = run.builder;
|
||||
run.path("src/doc/reference").default_condition(builder.config.docs)
|
||||
}
|
||||
|
||||
fn make_run(run: RunConfig<'_>) {
|
||||
run.builder.ensure(Reference {
|
||||
compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build),
|
||||
target: run.target,
|
||||
});
|
||||
}
|
||||
|
||||
/// Builds the reference book.
|
||||
fn run(self, builder: &Builder<'_>) {
|
||||
builder.require_submodule("src/doc/reference", None);
|
||||
|
||||
// This is needed for generating links to the standard library using
|
||||
// the mdbook-spec plugin.
|
||||
builder.ensure(compile::Std::new(self.compiler, builder.config.build));
|
||||
let rustdoc = builder.rustdoc(self.compiler);
|
||||
|
||||
// Run rustbook/mdbook to generate the HTML pages.
|
||||
builder.ensure(RustbookSrc {
|
||||
target: self.target,
|
||||
name: "reference".to_owned(),
|
||||
src: builder.src.join("src/doc/reference"),
|
||||
parent: Some(self),
|
||||
languages: vec![],
|
||||
rustdoc: Some(rustdoc),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,19 @@
|
|||
//! Runs rustfmt on the repository.
|
||||
|
||||
use crate::core::builder::Builder;
|
||||
use crate::utils::exec::command;
|
||||
use crate::utils::helpers::{self, program_out_of_date, t};
|
||||
use build_helper::ci::CiEnv;
|
||||
use build_helper::git::get_git_modified_files;
|
||||
use ignore::WalkBuilder;
|
||||
use std::collections::VecDeque;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
use std::sync::mpsc::SyncSender;
|
||||
use std::sync::Mutex;
|
||||
|
||||
use build_helper::ci::CiEnv;
|
||||
use build_helper::git::get_git_modified_files;
|
||||
use ignore::WalkBuilder;
|
||||
|
||||
use crate::core::builder::Builder;
|
||||
use crate::utils::exec::command;
|
||||
use crate::utils::helpers::{self, program_out_of_date, t};
|
||||
|
||||
fn rustfmt(src: &Path, rustfmt: &Path, paths: &[PathBuf], check: bool) -> impl FnMut(bool) -> bool {
|
||||
let mut cmd = Command::new(rustfmt);
|
||||
// Avoid the submodule config paths from coming into play. We only allow a single global config
|
||||
|
|
|
|||
|
|
@ -3,9 +3,8 @@
|
|||
//! This module is responsible for installing the standard library,
|
||||
//! compiler, and documentation.
|
||||
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::path::{Component, Path, PathBuf};
|
||||
use std::{env, fs};
|
||||
|
||||
use crate::core::build_steps::dist;
|
||||
use crate::core::builder::{Builder, RunConfig, ShouldRun, Step};
|
||||
|
|
|
|||
|
|
@ -8,25 +8,24 @@
|
|||
//! LLVM and compiler-rt are essentially just wired up to everything else to
|
||||
//! ensure that they're always in place if needed.
|
||||
|
||||
use std::env;
|
||||
use std::env::consts::EXE_EXTENSION;
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::fs::{self, File};
|
||||
use std::io;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::OnceLock;
|
||||
use std::{env, io};
|
||||
|
||||
use build_helper::ci::CiEnv;
|
||||
|
||||
use crate::core::builder::{Builder, RunConfig, ShouldRun, Step};
|
||||
use crate::core::config::{Config, TargetSelection};
|
||||
use crate::utils::channel;
|
||||
use crate::utils::exec::command;
|
||||
use crate::utils::helpers::{
|
||||
self, exe, get_clang_cl_resource_dir, output, t, unhashed_basename, up_to_date,
|
||||
};
|
||||
use crate::{generate_smart_stamp_hash, CLang, GitRepo, Kind};
|
||||
|
||||
use crate::utils::exec::command;
|
||||
use build_helper::ci::CiEnv;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct LlvmResult {
|
||||
/// Path to llvm-config binary.
|
||||
|
|
@ -89,7 +88,7 @@ impl LdFlags {
|
|||
/// if not).
|
||||
pub fn prebuilt_llvm_config(builder: &Builder<'_>, target: TargetSelection) -> LlvmBuildStatus {
|
||||
// If we have llvm submodule initialized already, sync it.
|
||||
builder.update_existing_submodule(&Path::new("src").join("llvm-project"));
|
||||
builder.update_existing_submodule("src/llvm-project");
|
||||
|
||||
builder.config.maybe_download_ci_llvm();
|
||||
|
||||
|
|
@ -110,7 +109,8 @@ pub fn prebuilt_llvm_config(builder: &Builder<'_>, target: TargetSelection) -> L
|
|||
}
|
||||
|
||||
// Initialize the llvm submodule if not initialized already.
|
||||
builder.update_submodule(&Path::new("src").join("llvm-project"));
|
||||
// If submodules are disabled, this does nothing.
|
||||
builder.update_submodule("src/llvm-project");
|
||||
|
||||
let root = "src/llvm-project/llvm";
|
||||
let out_dir = builder.llvm_out(target);
|
||||
|
|
@ -194,6 +194,7 @@ pub(crate) fn is_ci_llvm_available(config: &Config, asserts: bool) -> bool {
|
|||
let supported_platforms = [
|
||||
// tier 1
|
||||
("aarch64-unknown-linux-gnu", false),
|
||||
("aarch64-apple-darwin", false),
|
||||
("i686-pc-windows-gnu", false),
|
||||
("i686-pc-windows-msvc", false),
|
||||
("i686-unknown-linux-gnu", false),
|
||||
|
|
@ -202,7 +203,6 @@ pub(crate) fn is_ci_llvm_available(config: &Config, asserts: bool) -> bool {
|
|||
("x86_64-pc-windows-gnu", true),
|
||||
("x86_64-pc-windows-msvc", true),
|
||||
// tier 2 with host tools
|
||||
("aarch64-apple-darwin", false),
|
||||
("aarch64-pc-windows-msvc", false),
|
||||
("aarch64-unknown-linux-musl", false),
|
||||
("arm-unknown-linux-gnueabi", false),
|
||||
|
|
@ -368,9 +368,7 @@ impl Step for Llvm {
|
|||
cfg.define("LLVM_PROFDATA_FILE", path);
|
||||
}
|
||||
|
||||
// Disable zstd to avoid a dependency on libzstd.so.
|
||||
cfg.define("LLVM_ENABLE_ZSTD", "OFF");
|
||||
|
||||
// Libraries for ELF section compression.
|
||||
if !target.is_windows() {
|
||||
cfg.define("LLVM_ENABLE_ZLIB", "ON");
|
||||
} else {
|
||||
|
|
@ -824,6 +822,14 @@ fn configure_llvm(builder: &Builder<'_>, target: TargetSelection, cfg: &mut cmak
|
|||
}
|
||||
}
|
||||
|
||||
// Libraries for ELF section compression.
|
||||
if builder.config.llvm_libzstd {
|
||||
cfg.define("LLVM_ENABLE_ZSTD", "FORCE_ON");
|
||||
cfg.define("LLVM_USE_STATIC_ZSTD", "TRUE");
|
||||
} else {
|
||||
cfg.define("LLVM_ENABLE_ZSTD", "OFF");
|
||||
}
|
||||
|
||||
if let Some(ref linker) = builder.config.llvm_use_linker {
|
||||
cfg.define("LLVM_USE_LINKER", linker);
|
||||
}
|
||||
|
|
@ -1197,7 +1203,10 @@ impl Step for CrtBeginEnd {
|
|||
|
||||
/// Build crtbegin.o/crtend.o for musl target.
|
||||
fn run(self, builder: &Builder<'_>) -> Self::Output {
|
||||
builder.update_submodule(Path::new("src/llvm-project"));
|
||||
builder.require_submodule(
|
||||
"src/llvm-project",
|
||||
Some("The LLVM sources are required for the CRT from `compiler-rt`."),
|
||||
);
|
||||
|
||||
let out_dir = builder.native_dir(self.target).join("crt");
|
||||
|
||||
|
|
@ -1270,7 +1279,10 @@ impl Step for Libunwind {
|
|||
|
||||
/// Build libunwind.a
|
||||
fn run(self, builder: &Builder<'_>) -> Self::Output {
|
||||
builder.update_submodule(Path::new("src/llvm-project"));
|
||||
builder.require_submodule(
|
||||
"src/llvm-project",
|
||||
Some("The LLVM sources are required for libunwind."),
|
||||
);
|
||||
|
||||
if builder.config.dry_run() {
|
||||
return PathBuf::new();
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use std::path::PathBuf;
|
|||
use crate::core::build_steps::dist::distdir;
|
||||
use crate::core::build_steps::test;
|
||||
use crate::core::build_steps::tool::{self, SourceType, Tool};
|
||||
use crate::core::builder::{Builder, RunConfig, ShouldRun, Step};
|
||||
use crate::core::builder::{Builder, Kind, RunConfig, ShouldRun, Step};
|
||||
use crate::core::config::flags::get_completion;
|
||||
use crate::core::config::TargetSelection;
|
||||
use crate::utils::exec::command;
|
||||
|
|
@ -142,7 +142,7 @@ impl Step for Miri {
|
|||
host_compiler,
|
||||
Mode::ToolRustc,
|
||||
host,
|
||||
"run",
|
||||
Kind::Run,
|
||||
"src/tools/miri",
|
||||
SourceType::InTree,
|
||||
&[],
|
||||
|
|
@ -212,11 +212,13 @@ impl Step for GenerateCopyright {
|
|||
let license_metadata = builder.ensure(CollectLicenseMetadata);
|
||||
|
||||
// Temporary location, it will be moved to the proper one once it's accurate.
|
||||
let dest = builder.out.join("COPYRIGHT.md");
|
||||
let dest = builder.out.join("COPYRIGHT.html");
|
||||
|
||||
let mut cmd = builder.tool_cmd(Tool::GenerateCopyright);
|
||||
cmd.env("LICENSE_METADATA", &license_metadata);
|
||||
cmd.env("DEST", &dest);
|
||||
cmd.env("OUT_DIR", &builder.out);
|
||||
cmd.env("CARGO", &builder.initial_cargo);
|
||||
cmd.run(builder);
|
||||
|
||||
dest
|
||||
|
|
|
|||
|
|
@ -5,13 +5,6 @@
|
|||
//! allows setting up things that cannot be simply captured inside the config.toml, in addition to
|
||||
//! leading people away from manually editing most of the config.toml values.
|
||||
|
||||
use crate::core::builder::{Builder, RunConfig, ShouldRun, Step};
|
||||
use crate::t;
|
||||
use crate::utils::change_tracker::CONFIG_CHANGE_HISTORY;
|
||||
use crate::utils::exec::command;
|
||||
use crate::utils::helpers::{self, hex_encode};
|
||||
use crate::Config;
|
||||
use sha2::Digest;
|
||||
use std::env::consts::EXE_SUFFIX;
|
||||
use std::fmt::Write as _;
|
||||
use std::fs::File;
|
||||
|
|
@ -20,6 +13,14 @@ use std::path::{Path, PathBuf, MAIN_SEPARATOR_STR};
|
|||
use std::str::FromStr;
|
||||
use std::{fmt, fs, io};
|
||||
|
||||
use sha2::Digest;
|
||||
|
||||
use crate::core::builder::{Builder, RunConfig, ShouldRun, Step};
|
||||
use crate::utils::change_tracker::CONFIG_CHANGE_HISTORY;
|
||||
use crate::utils::exec::command;
|
||||
use crate::utils::helpers::{self, hex_encode};
|
||||
use crate::{t, Config};
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use sha2::Digest;
|
||||
|
||||
use super::{RUST_ANALYZER_SETTINGS, SETTINGS_HASHES};
|
||||
use crate::utils::helpers::hex_encode;
|
||||
use sha2::Digest;
|
||||
|
||||
#[test]
|
||||
fn check_matching_settings_hash() {
|
||||
|
|
|
|||
|
|
@ -2,10 +2,11 @@
|
|||
|
||||
#![cfg_attr(feature = "build-metrics", allow(unused))]
|
||||
|
||||
use clap::Parser;
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
|
||||
use clap::Parser;
|
||||
|
||||
use crate::core::build_steps::tool::Tool;
|
||||
use crate::core::builder::Builder;
|
||||
|
||||
|
|
|
|||
|
|
@ -3,27 +3,22 @@
|
|||
//! `./x.py test` (aka [`Kind::Test`]) is currently allowed to reach build steps in other modules.
|
||||
//! However, this contains ~all test parts we expect people to be able to build and run locally.
|
||||
|
||||
use std::env;
|
||||
use std::ffi::OsStr;
|
||||
use std::ffi::OsString;
|
||||
use std::fs;
|
||||
use std::iter;
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::{env, fs, iter};
|
||||
|
||||
use clap_complete::shells;
|
||||
|
||||
use crate::core::build_steps::compile;
|
||||
use crate::core::build_steps::dist;
|
||||
use crate::core::build_steps::doc::DocumentationFormat;
|
||||
use crate::core::build_steps::llvm;
|
||||
use crate::core::build_steps::synthetic_targets::MirOptPanicAbortSyntheticTarget;
|
||||
use crate::core::build_steps::tool::{self, SourceType, Tool};
|
||||
use crate::core::build_steps::toolstate::ToolState;
|
||||
use crate::core::build_steps::{compile, dist, llvm};
|
||||
use crate::core::builder;
|
||||
use crate::core::builder::crate_description;
|
||||
use crate::core::builder::{Builder, Compiler, Kind, RunConfig, ShouldRun, Step};
|
||||
use crate::core::config::flags::get_completion;
|
||||
use crate::core::config::flags::Subcommand;
|
||||
use crate::core::builder::{
|
||||
crate_description, Builder, Compiler, Kind, RunConfig, ShouldRun, Step,
|
||||
};
|
||||
use crate::core::config::flags::{get_completion, Subcommand};
|
||||
use crate::core::config::TargetSelection;
|
||||
use crate::utils::exec::{command, BootstrapCommand};
|
||||
use crate::utils::helpers::{
|
||||
|
|
@ -73,7 +68,7 @@ impl Step for CrateBootstrap {
|
|||
compiler,
|
||||
Mode::ToolBootstrap,
|
||||
bootstrap_host,
|
||||
"test",
|
||||
Kind::Test,
|
||||
path,
|
||||
SourceType::InTree,
|
||||
&[],
|
||||
|
|
@ -124,7 +119,7 @@ You can skip linkcheck with --skip src/tools/linkchecker"
|
|||
compiler,
|
||||
Mode::ToolBootstrap,
|
||||
bootstrap_host,
|
||||
"test",
|
||||
Kind::Test,
|
||||
"src/tools/linkchecker",
|
||||
SourceType::InTree,
|
||||
&[],
|
||||
|
|
@ -154,7 +149,7 @@ You can skip linkcheck with --skip src/tools/linkchecker"
|
|||
let _guard =
|
||||
builder.msg(Kind::Test, compiler.stage, "Linkcheck", bootstrap_host, bootstrap_host);
|
||||
let _time = helpers::timeit(builder);
|
||||
linkchecker.delay_failure().arg(builder.out.join(host.triple).join("doc")).run(builder);
|
||||
linkchecker.delay_failure().arg(builder.out.join(host).join("doc")).run(builder);
|
||||
}
|
||||
|
||||
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
|
||||
|
|
@ -289,7 +284,7 @@ impl Step for Cargo {
|
|||
compiler,
|
||||
Mode::ToolRustc,
|
||||
self.host,
|
||||
"test",
|
||||
Kind::Test,
|
||||
"src/tools/cargo",
|
||||
SourceType::Submodule,
|
||||
&[],
|
||||
|
|
@ -360,7 +355,7 @@ impl Step for RustAnalyzer {
|
|||
compiler,
|
||||
Mode::ToolRustc,
|
||||
host,
|
||||
"test",
|
||||
Kind::Test,
|
||||
crate_path,
|
||||
SourceType::InTree,
|
||||
&["in-rust-tree".to_owned()],
|
||||
|
|
@ -412,7 +407,7 @@ impl Step for Rustfmt {
|
|||
compiler,
|
||||
Mode::ToolRustc,
|
||||
host,
|
||||
"test",
|
||||
Kind::Test,
|
||||
"src/tools/rustfmt",
|
||||
SourceType::InTree,
|
||||
&[],
|
||||
|
|
@ -439,15 +434,15 @@ impl Miri {
|
|||
builder: &Builder<'_>,
|
||||
compiler: Compiler,
|
||||
target: TargetSelection,
|
||||
) -> String {
|
||||
let miri_sysroot = builder.out.join(compiler.host.triple).join("miri-sysroot");
|
||||
) -> PathBuf {
|
||||
let miri_sysroot = builder.out.join(compiler.host).join("miri-sysroot");
|
||||
let mut cargo = builder::Cargo::new(
|
||||
builder,
|
||||
compiler,
|
||||
Mode::Std,
|
||||
SourceType::Submodule,
|
||||
target,
|
||||
"miri-setup",
|
||||
Kind::MiriSetup,
|
||||
);
|
||||
|
||||
// Tell `cargo miri setup` where to find the sources.
|
||||
|
|
@ -472,7 +467,7 @@ impl Miri {
|
|||
// Output is "<sysroot>\n".
|
||||
let sysroot = stdout.trim_end();
|
||||
builder.verbose(|| println!("`cargo miri setup --print-sysroot` said: {sysroot:?}"));
|
||||
sysroot.to_owned()
|
||||
PathBuf::from(sysroot)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -525,6 +520,16 @@ impl Step for Miri {
|
|||
builder.ensure(compile::Std::new(target_compiler, host));
|
||||
let host_sysroot = builder.sysroot(target_compiler);
|
||||
|
||||
// Miri has its own "target dir" for ui test dependencies. Make sure it gets cleared when
|
||||
// the sysroot gets rebuilt, to avoid "found possibly newer version of crate `std`" errors.
|
||||
if !builder.config.dry_run() {
|
||||
let ui_test_dep_dir = builder.stage_out(host_compiler, Mode::ToolStd).join("miri_ui");
|
||||
// The mtime of `miri_sysroot` changes when the sysroot gets rebuilt (also see
|
||||
// <https://github.com/RalfJung/rustc-build-sysroot/commit/10ebcf60b80fe2c3dc765af0ff19fdc0da4b7466>).
|
||||
// We can hence use that directly as a signal to clear the ui test dir.
|
||||
builder.clear_if_dirty(&ui_test_dep_dir, &miri_sysroot);
|
||||
}
|
||||
|
||||
// Run `cargo test`.
|
||||
// This is with the Miri crate, so it uses the host compiler.
|
||||
let mut cargo = tool::prepare_tool_cargo(
|
||||
|
|
@ -532,7 +537,7 @@ impl Step for Miri {
|
|||
host_compiler,
|
||||
Mode::ToolRustc,
|
||||
host,
|
||||
"test",
|
||||
Kind::Test,
|
||||
"src/tools/miri",
|
||||
SourceType::InTree,
|
||||
&[],
|
||||
|
|
@ -622,7 +627,7 @@ impl Step for CargoMiri {
|
|||
compiler,
|
||||
Mode::ToolStd, // it's unclear what to use here, we're not building anything just doing a smoke test!
|
||||
target,
|
||||
"miri-test",
|
||||
Kind::MiriTest,
|
||||
"src/tools/miri/test-cargo-miri",
|
||||
SourceType::Submodule,
|
||||
&[],
|
||||
|
|
@ -682,7 +687,7 @@ impl Step for CompiletestTest {
|
|||
// when std sources change.
|
||||
Mode::ToolStd,
|
||||
host,
|
||||
"test",
|
||||
Kind::Test,
|
||||
"src/tools/compiletest",
|
||||
SourceType::InTree,
|
||||
&[],
|
||||
|
|
@ -732,7 +737,7 @@ impl Step for Clippy {
|
|||
compiler,
|
||||
Mode::ToolRustc,
|
||||
host,
|
||||
"test",
|
||||
Kind::Test,
|
||||
"src/tools/clippy",
|
||||
SourceType::InTree,
|
||||
&[],
|
||||
|
|
@ -852,7 +857,6 @@ impl Step for RustdocJSStd {
|
|||
builder.ensure(crate::core::build_steps::doc::Std::new(
|
||||
builder.top_stage,
|
||||
self.target,
|
||||
builder,
|
||||
DocumentationFormat::Html,
|
||||
));
|
||||
let _guard = builder.msg(
|
||||
|
|
@ -1111,7 +1115,7 @@ HELP: to skip test's attempt to check tidiness, pass `--skip src/tools/tidy` to
|
|||
}
|
||||
|
||||
fn testdir(builder: &Builder<'_>, host: TargetSelection) -> PathBuf {
|
||||
builder.out.join(host.triple).join("test")
|
||||
builder.out.join(host).join("test")
|
||||
}
|
||||
|
||||
macro_rules! default_test {
|
||||
|
|
@ -1282,7 +1286,7 @@ impl Step for RunMakeSupport {
|
|||
self.compiler,
|
||||
Mode::ToolStd,
|
||||
self.target,
|
||||
"build",
|
||||
Kind::Build,
|
||||
"src/tools/run-make-support",
|
||||
SourceType::InTree,
|
||||
&[],
|
||||
|
|
@ -1326,7 +1330,7 @@ impl Step for CrateRunMakeSupport {
|
|||
compiler,
|
||||
Mode::ToolBootstrap,
|
||||
host,
|
||||
"test",
|
||||
Kind::Test,
|
||||
"src/tools/run-make-support",
|
||||
SourceType::InTree,
|
||||
&[],
|
||||
|
|
@ -1372,7 +1376,7 @@ impl Step for CrateBuildHelper {
|
|||
compiler,
|
||||
Mode::ToolBootstrap,
|
||||
host,
|
||||
"test",
|
||||
Kind::Test,
|
||||
"src/tools/build_helper",
|
||||
SourceType::InTree,
|
||||
&[],
|
||||
|
|
@ -1813,7 +1817,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
|
|||
|
||||
let mut flags = if is_rustdoc { Vec::new() } else { vec!["-Crpath".to_string()] };
|
||||
flags.push(format!("-Cdebuginfo={}", builder.config.rust_debuginfo_level_tests));
|
||||
flags.extend(builder.config.cmd.rustc_args().iter().map(|s| s.to_string()));
|
||||
flags.extend(builder.config.cmd.compiletest_rustc_args().iter().map(|s| s.to_string()));
|
||||
|
||||
if suite != "mir-opt" {
|
||||
if let Some(linker) = builder.linker(target) {
|
||||
|
|
@ -2092,7 +2096,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
|
|||
let git_config = builder.config.git_config();
|
||||
cmd.arg("--git-repository").arg(git_config.git_repository);
|
||||
cmd.arg("--nightly-branch").arg(git_config.nightly_branch);
|
||||
cmd.force_coloring_in_ci(builder.ci_env);
|
||||
cmd.force_coloring_in_ci();
|
||||
|
||||
#[cfg(feature = "build-metrics")]
|
||||
builder.metrics.begin_test_suite(
|
||||
|
|
@ -2254,7 +2258,12 @@ impl BookTest {
|
|||
}
|
||||
|
||||
macro_rules! test_book {
|
||||
($($name:ident, $path:expr, $book_name:expr, default=$default:expr;)+) => {
|
||||
($(
|
||||
$name:ident, $path:expr, $book_name:expr,
|
||||
default=$default:expr
|
||||
$(,submodules = $submodules:expr)?
|
||||
;
|
||||
)+) => {
|
||||
$(
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct $name {
|
||||
|
|
@ -2277,6 +2286,11 @@ macro_rules! test_book {
|
|||
}
|
||||
|
||||
fn run(self, builder: &Builder<'_>) {
|
||||
$(
|
||||
for submodule in $submodules {
|
||||
builder.require_submodule(submodule, None);
|
||||
}
|
||||
)*
|
||||
builder.ensure(BookTest {
|
||||
compiler: self.compiler,
|
||||
path: PathBuf::from($path),
|
||||
|
|
@ -2290,15 +2304,15 @@ macro_rules! test_book {
|
|||
}
|
||||
|
||||
test_book!(
|
||||
Nomicon, "src/doc/nomicon", "nomicon", default=false;
|
||||
Reference, "src/doc/reference", "reference", default=false;
|
||||
Nomicon, "src/doc/nomicon", "nomicon", default=false, submodules=["src/doc/nomicon"];
|
||||
Reference, "src/doc/reference", "reference", default=false, submodules=["src/doc/reference"];
|
||||
RustdocBook, "src/doc/rustdoc", "rustdoc", default=true;
|
||||
RustcBook, "src/doc/rustc", "rustc", default=true;
|
||||
RustByExample, "src/doc/rust-by-example", "rust-by-example", default=false;
|
||||
EmbeddedBook, "src/doc/embedded-book", "embedded-book", default=false;
|
||||
TheBook, "src/doc/book", "book", default=false;
|
||||
RustByExample, "src/doc/rust-by-example", "rust-by-example", default=false, submodules=["src/doc/rust-by-example"];
|
||||
EmbeddedBook, "src/doc/embedded-book", "embedded-book", default=false, submodules=["src/doc/embedded-book"];
|
||||
TheBook, "src/doc/book", "book", default=false, submodules=["src/doc/book"];
|
||||
UnstableBook, "src/doc/unstable-book", "unstable-book", default=true;
|
||||
EditionGuide, "src/doc/edition-guide", "edition-guide", default=false;
|
||||
EditionGuide, "src/doc/edition-guide", "edition-guide", default=false, submodules=["src/doc/edition-guide"];
|
||||
);
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
|
|
@ -2396,8 +2410,8 @@ impl Step for RustcGuide {
|
|||
}
|
||||
|
||||
fn run(self, builder: &Builder<'_>) {
|
||||
let relative_path = Path::new("src").join("doc").join("rustc-dev-guide");
|
||||
builder.update_submodule(&relative_path);
|
||||
let relative_path = "src/doc/rustc-dev-guide";
|
||||
builder.require_submodule(relative_path, None);
|
||||
|
||||
let src = builder.src.join(relative_path);
|
||||
let mut rustbook_cmd = builder.tool_cmd(Tool::Rustbook).delay_failure();
|
||||
|
|
@ -2626,7 +2640,7 @@ impl Step for Crate {
|
|||
mode,
|
||||
SourceType::InTree,
|
||||
target,
|
||||
"miri-test",
|
||||
Kind::MiriTest,
|
||||
);
|
||||
// This hack helps bootstrap run standard library tests in Miri. The issue is as
|
||||
// follows: when running `cargo miri test` on libcore, cargo builds a local copy of core
|
||||
|
|
@ -2649,14 +2663,7 @@ impl Step for Crate {
|
|||
}
|
||||
|
||||
// Build `cargo test` command
|
||||
builder::Cargo::new(
|
||||
builder,
|
||||
compiler,
|
||||
mode,
|
||||
SourceType::InTree,
|
||||
target,
|
||||
builder.kind.as_str(),
|
||||
)
|
||||
builder::Cargo::new(builder, compiler, mode, SourceType::InTree, target, builder.kind)
|
||||
};
|
||||
|
||||
match mode {
|
||||
|
|
@ -2678,7 +2685,7 @@ impl Step for Crate {
|
|||
if builder.download_rustc() && compiler.stage > 0 {
|
||||
let sysroot = builder
|
||||
.out
|
||||
.join(compiler.host.triple)
|
||||
.join(compiler.host)
|
||||
.join(format!("stage{}-test-sysroot", compiler.stage));
|
||||
cargo.env("RUSTC_SYSROOT", sysroot);
|
||||
}
|
||||
|
|
@ -2748,7 +2755,7 @@ impl Step for CrateRustdoc {
|
|||
compiler,
|
||||
Mode::ToolRustc,
|
||||
target,
|
||||
builder.kind.as_str(),
|
||||
builder.kind,
|
||||
"src/tools/rustdoc",
|
||||
SourceType::InTree,
|
||||
&[],
|
||||
|
|
@ -2840,7 +2847,7 @@ impl Step for CrateRustdocJsonTypes {
|
|||
compiler,
|
||||
Mode::ToolRustc,
|
||||
target,
|
||||
builder.kind.as_str(),
|
||||
builder.kind,
|
||||
"src/rustdoc-json-types",
|
||||
SourceType::InTree,
|
||||
&[],
|
||||
|
|
@ -3003,7 +3010,7 @@ impl Step for Bootstrap {
|
|||
let _guard = builder.msg(Kind::Test, 0, "bootstrap", host, host);
|
||||
|
||||
// Some tests require cargo submodule to be present.
|
||||
builder.build.update_submodule(Path::new("src/tools/cargo"));
|
||||
builder.build.require_submodule("src/tools/cargo", None);
|
||||
|
||||
let mut check_bootstrap = command(builder.python());
|
||||
check_bootstrap
|
||||
|
|
@ -3074,7 +3081,7 @@ impl Step for TierCheck {
|
|||
self.compiler,
|
||||
Mode::ToolStd,
|
||||
self.compiler.host,
|
||||
"run",
|
||||
Kind::Run,
|
||||
"src/tools/tier-check",
|
||||
SourceType::InTree,
|
||||
&[],
|
||||
|
|
@ -3146,7 +3153,7 @@ impl Step for RustInstaller {
|
|||
compiler,
|
||||
Mode::ToolBootstrap,
|
||||
bootstrap_host,
|
||||
"test",
|
||||
Kind::Test,
|
||||
"src/tools/rust-installer",
|
||||
SourceType::InTree,
|
||||
&[],
|
||||
|
|
@ -3316,7 +3323,7 @@ impl Step for CodegenCranelift {
|
|||
Mode::Codegen, // Must be codegen to ensure dlopen on compiled dylibs works
|
||||
SourceType::InTree,
|
||||
target,
|
||||
"run",
|
||||
Kind::Run,
|
||||
);
|
||||
|
||||
cargo.current_dir(&builder.src.join("compiler/rustc_codegen_cranelift"));
|
||||
|
|
@ -3448,7 +3455,7 @@ impl Step for CodegenGCC {
|
|||
Mode::Codegen, // Must be codegen to ensure dlopen on compiled dylibs works
|
||||
SourceType::InTree,
|
||||
target,
|
||||
"run",
|
||||
Kind::Run,
|
||||
);
|
||||
|
||||
cargo.current_dir(&builder.src.join("compiler/rustc_codegen_gcc"));
|
||||
|
|
@ -3536,7 +3543,7 @@ impl Step for TestFloatParse {
|
|||
compiler,
|
||||
Mode::ToolStd,
|
||||
bootstrap_host,
|
||||
"test",
|
||||
Kind::Test,
|
||||
path,
|
||||
SourceType::InTree,
|
||||
&[],
|
||||
|
|
@ -3559,7 +3566,7 @@ impl Step for TestFloatParse {
|
|||
compiler,
|
||||
Mode::ToolStd,
|
||||
bootstrap_host,
|
||||
"run",
|
||||
Kind::Run,
|
||||
path,
|
||||
SourceType::InTree,
|
||||
&[],
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
use std::env;
|
||||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::path::PathBuf;
|
||||
use std::{env, fs};
|
||||
|
||||
use crate::core::build_steps::compile;
|
||||
use crate::core::build_steps::toolstate::ToolState;
|
||||
|
|
@ -10,9 +9,7 @@ use crate::core::config::TargetSelection;
|
|||
use crate::utils::channel::GitInfo;
|
||||
use crate::utils::exec::{command, BootstrapCommand};
|
||||
use crate::utils::helpers::{add_dylib_path, exe, get_closest_merge_base_commit, git, t};
|
||||
use crate::Compiler;
|
||||
use crate::Mode;
|
||||
use crate::{gha, Kind};
|
||||
use crate::{gha, Compiler, Kind, Mode};
|
||||
|
||||
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
|
||||
pub enum SourceType {
|
||||
|
|
@ -93,7 +90,7 @@ impl Step for ToolBuild {
|
|||
compiler,
|
||||
self.mode,
|
||||
target,
|
||||
"build",
|
||||
Kind::Build,
|
||||
path,
|
||||
self.source_type,
|
||||
&self.extra_features,
|
||||
|
|
@ -139,12 +136,12 @@ pub fn prepare_tool_cargo(
|
|||
compiler: Compiler,
|
||||
mode: Mode,
|
||||
target: TargetSelection,
|
||||
command: &'static str,
|
||||
cmd_kind: Kind,
|
||||
path: &str,
|
||||
source_type: SourceType,
|
||||
extra_features: &[String],
|
||||
) -> CargoCommand {
|
||||
let mut cargo = builder::Cargo::new(builder, compiler, mode, source_type, target, command);
|
||||
let mut cargo = builder::Cargo::new(builder, compiler, mode, source_type, target, cmd_kind);
|
||||
|
||||
let dir = builder.src.join(path);
|
||||
cargo.arg("--manifest-path").arg(dir.join("Cargo.toml"));
|
||||
|
|
@ -241,6 +238,7 @@ macro_rules! bootstrap_tool {
|
|||
$(,is_external_tool = $external:expr)*
|
||||
$(,is_unstable_tool = $unstable:expr)*
|
||||
$(,allow_features = $allow_features:expr)?
|
||||
$(,submodules = $submodules:expr)?
|
||||
;
|
||||
)+) => {
|
||||
#[derive(PartialEq, Eq, Clone)]
|
||||
|
|
@ -287,6 +285,11 @@ macro_rules! bootstrap_tool {
|
|||
}
|
||||
|
||||
fn run(self, builder: &Builder<'_>) -> PathBuf {
|
||||
$(
|
||||
for submodule in $submodules {
|
||||
builder.require_submodule(submodule, None);
|
||||
}
|
||||
)*
|
||||
builder.ensure(ToolBuild {
|
||||
compiler: self.compiler,
|
||||
target: self.target,
|
||||
|
|
@ -314,7 +317,7 @@ macro_rules! bootstrap_tool {
|
|||
}
|
||||
|
||||
bootstrap_tool!(
|
||||
Rustbook, "src/tools/rustbook", "rustbook";
|
||||
Rustbook, "src/tools/rustbook", "rustbook", submodules = SUBMODULES_FOR_RUSTBOOK;
|
||||
UnstableBookGen, "src/tools/unstable-book-gen", "unstable-book-gen";
|
||||
Tidy, "src/tools/tidy", "tidy";
|
||||
Linkchecker, "src/tools/linkchecker", "linkchecker";
|
||||
|
|
@ -340,6 +343,10 @@ bootstrap_tool!(
|
|||
WasmComponentLd, "src/tools/wasm-component-ld", "wasm-component-ld", is_unstable_tool = true, allow_features = "min_specialization";
|
||||
);
|
||||
|
||||
/// These are the submodules that are required for rustbook to work due to
|
||||
/// depending on mdbook plugins.
|
||||
pub static SUBMODULES_FOR_RUSTBOOK: &[&str] = &["src/doc/book", "src/doc/reference"];
|
||||
|
||||
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct OptimizedDist {
|
||||
pub compiler: Compiler,
|
||||
|
|
@ -363,7 +370,7 @@ impl Step for OptimizedDist {
|
|||
fn run(self, builder: &Builder<'_>) -> PathBuf {
|
||||
// We need to ensure the rustc-perf submodule is initialized when building opt-dist since
|
||||
// the tool requires it to be in place to run.
|
||||
builder.update_submodule(Path::new("src/tools/rustc-perf"));
|
||||
builder.require_submodule("src/tools/rustc-perf", None);
|
||||
|
||||
builder.ensure(ToolBuild {
|
||||
compiler: self.compiler,
|
||||
|
|
@ -404,7 +411,7 @@ impl Step for RustcPerf {
|
|||
|
||||
fn run(self, builder: &Builder<'_>) -> PathBuf {
|
||||
// We need to ensure the rustc-perf submodule is initialized.
|
||||
builder.update_submodule(Path::new("src/tools/rustc-perf"));
|
||||
builder.require_submodule("src/tools/rustc-perf", None);
|
||||
|
||||
let tool = ToolBuild {
|
||||
compiler: self.compiler,
|
||||
|
|
@ -639,7 +646,7 @@ impl Step for Rustdoc {
|
|||
build_compiler,
|
||||
Mode::ToolRustc,
|
||||
target,
|
||||
"build",
|
||||
Kind::Build,
|
||||
"src/tools/rustdoc",
|
||||
SourceType::InTree,
|
||||
features.as_slice(),
|
||||
|
|
@ -704,7 +711,7 @@ impl Step for Cargo {
|
|||
}
|
||||
|
||||
fn run(self, builder: &Builder<'_>) -> PathBuf {
|
||||
builder.build.update_submodule(Path::new("src/tools/cargo"));
|
||||
builder.build.require_submodule("src/tools/cargo", None);
|
||||
|
||||
builder.ensure(ToolBuild {
|
||||
compiler: self.compiler,
|
||||
|
|
@ -898,7 +905,7 @@ impl Step for LlvmBitcodeLinker {
|
|||
self.compiler,
|
||||
Mode::ToolRustc,
|
||||
self.target,
|
||||
"build",
|
||||
Kind::Build,
|
||||
"src/tools/llvm-bitcode-linker",
|
||||
SourceType::InTree,
|
||||
&self.extra_features,
|
||||
|
|
@ -1086,8 +1093,6 @@ macro_rules! tool_extended {
|
|||
|
||||
// NOTE: tools need to be also added to `Builder::get_step_descriptions` in `builder.rs`
|
||||
// to make `./x.py build <tool>` work.
|
||||
// NOTE: Most submodule updates for tools are handled by bootstrap.py, since they're needed just to
|
||||
// invoke Cargo to build bootstrap. See the comment there for more details.
|
||||
tool_extended!((self, builder),
|
||||
Cargofmt, "src/tools/rustfmt", "cargo-fmt", stable=true;
|
||||
CargoClippy, "src/tools/clippy", "cargo-clippy", stable=true;
|
||||
|
|
|
|||
|
|
@ -4,16 +4,15 @@
|
|||
//!
|
||||
//! [Toolstate]: https://forge.rust-lang.org/infra/toolstate.html
|
||||
|
||||
use crate::core::builder::{Builder, RunConfig, ShouldRun, Step};
|
||||
use crate::utils::helpers::{self, t};
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
use std::fmt;
|
||||
use std::fs;
|
||||
use std::io::{Seek, SeekFrom};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::time;
|
||||
use std::{env, fmt, fs, time};
|
||||
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
|
||||
use crate::core::builder::{Builder, RunConfig, ShouldRun, Step};
|
||||
use crate::utils::helpers::{self, t};
|
||||
|
||||
// Each cycle is 42 days long (6 weeks); the last week is 35..=42 then.
|
||||
const BETA_WEEK_START: u64 = 35;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
use std::path::PathBuf;
|
||||
|
||||
use crate::core::build_steps::tool::SUBMODULES_FOR_RUSTBOOK;
|
||||
use crate::core::builder::{Builder, RunConfig, ShouldRun, Step};
|
||||
use crate::utils::exec::command;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
|
||||
pub(crate) struct Vendor {
|
||||
|
|
@ -35,8 +37,8 @@ impl Step for Vendor {
|
|||
}
|
||||
|
||||
// These submodules must be present for `x vendor` to work.
|
||||
for path in ["src/tools/cargo", "src/doc/book"] {
|
||||
builder.build.update_submodule(Path::new(path));
|
||||
for submodule in SUBMODULES_FOR_RUSTBOOK.iter().chain(["src/tools/cargo"].iter()) {
|
||||
builder.build.require_submodule(submodule, None);
|
||||
}
|
||||
|
||||
// Sync these paths by default.
|
||||
|
|
@ -45,6 +47,7 @@ impl Step for Vendor {
|
|||
"src/tools/rust-analyzer/Cargo.toml",
|
||||
"compiler/rustc_codegen_cranelift/Cargo.toml",
|
||||
"compiler/rustc_codegen_gcc/Cargo.toml",
|
||||
"library/Cargo.toml",
|
||||
"src/bootstrap/Cargo.toml",
|
||||
"src/tools/rustbook/Cargo.toml",
|
||||
] {
|
||||
|
|
|
|||
|
|
@ -1,15 +1,16 @@
|
|||
use std::any::{type_name, Any};
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::collections::BTreeSet;
|
||||
use std::env;
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::fmt::{Debug, Write};
|
||||
use std::fs;
|
||||
use std::hash::Hash;
|
||||
use std::ops::Deref;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::LazyLock;
|
||||
use std::time::{Duration, Instant};
|
||||
use std::{env, fs};
|
||||
|
||||
use clap::ValueEnum;
|
||||
|
||||
use crate::core::build_steps::tool::{self, SourceType};
|
||||
use crate::core::build_steps::{
|
||||
|
|
@ -17,17 +18,16 @@ use crate::core::build_steps::{
|
|||
};
|
||||
use crate::core::config::flags::{Color, Subcommand};
|
||||
use crate::core::config::{DryRun, SplitDebuginfo, TargetSelection};
|
||||
use crate::prepare_behaviour_dump_dir;
|
||||
use crate::utils::cache::Cache;
|
||||
use crate::utils::helpers::{self, add_dylib_path, add_link_lib_path, exe, linker_args};
|
||||
use crate::utils::helpers::{check_cfg_arg, libdir, linker_flags, t, LldThreads};
|
||||
use crate::EXTRA_CHECK_CFGS;
|
||||
use crate::{Build, CLang, Crate, DocTests, GitRepo, Mode};
|
||||
|
||||
use crate::utils::exec::{command, BootstrapCommand};
|
||||
use crate::utils::helpers::{
|
||||
self, add_dylib_path, add_link_lib_path, check_cfg_arg, exe, libdir, linker_args, linker_flags,
|
||||
t, LldThreads,
|
||||
};
|
||||
pub use crate::Compiler;
|
||||
|
||||
use clap::ValueEnum;
|
||||
use crate::{
|
||||
prepare_behaviour_dump_dir, Build, CLang, Crate, DocTests, GitRepo, Mode, EXTRA_CHECK_CFGS,
|
||||
};
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
|
@ -689,7 +689,7 @@ impl<'a> ShouldRun<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)]
|
||||
#[derive(Debug, Copy, Clone, Eq, Hash, PartialEq, PartialOrd, Ord, ValueEnum)]
|
||||
pub enum Kind {
|
||||
#[value(alias = "b")]
|
||||
Build,
|
||||
|
|
@ -701,6 +701,8 @@ pub enum Kind {
|
|||
#[value(alias = "t")]
|
||||
Test,
|
||||
Miri,
|
||||
MiriSetup,
|
||||
MiriTest,
|
||||
Bench,
|
||||
#[value(alias = "d")]
|
||||
Doc,
|
||||
|
|
@ -725,6 +727,8 @@ impl Kind {
|
|||
Kind::Format => "fmt",
|
||||
Kind::Test => "test",
|
||||
Kind::Miri => "miri",
|
||||
Kind::MiriSetup => panic!("`as_str` is not supported for `Kind::MiriSetup`."),
|
||||
Kind::MiriTest => panic!("`as_str` is not supported for `Kind::MiriTest`."),
|
||||
Kind::Bench => "bench",
|
||||
Kind::Doc => "doc",
|
||||
Kind::Clean => "clean",
|
||||
|
|
@ -1000,6 +1004,7 @@ impl<'a> Builder<'a> {
|
|||
Kind::Vendor => describe!(vendor::Vendor),
|
||||
// special-cased in Build::build()
|
||||
Kind::Format | Kind::Suggest | Kind::Perf => vec![],
|
||||
Kind::MiriTest | Kind::MiriSetup => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1101,6 +1106,12 @@ impl<'a> Builder<'a> {
|
|||
StepDescription::run(v, self, paths);
|
||||
}
|
||||
|
||||
/// Returns if `std` should be statically linked into `rustc_driver`.
|
||||
/// It's currently not done on `windows-gnu` due to linker bugs.
|
||||
pub fn link_std_into_rustc_driver(&self, target: TargetSelection) -> bool {
|
||||
!target.triple.ends_with("-windows-gnu")
|
||||
}
|
||||
|
||||
/// Obtain a compiler at a given stage and for a given host (i.e., this is the target that the
|
||||
/// compiler will run on, *not* the target it will build code for). Explicitly does not take
|
||||
/// `Compiler` since all `Compiler` instances are meant to be obtained through this function,
|
||||
|
|
@ -1160,7 +1171,7 @@ impl<'a> Builder<'a> {
|
|||
.sysroot(self.compiler)
|
||||
.join(lib)
|
||||
.join("rustlib")
|
||||
.join(self.target.triple)
|
||||
.join(self.target)
|
||||
.join("lib");
|
||||
// Avoid deleting the rustlib/ directory we just copied
|
||||
// (in `impl Step for Sysroot`).
|
||||
|
|
@ -1243,7 +1254,7 @@ impl<'a> Builder<'a> {
|
|||
|
||||
// Ensure that the downloaded LLVM libraries can be found.
|
||||
if self.config.llvm_from_ci {
|
||||
let ci_llvm_lib = self.out.join(&*compiler.host.triple).join("ci-llvm").join("lib");
|
||||
let ci_llvm_lib = self.out.join(compiler.host).join("ci-llvm").join("lib");
|
||||
dylib_dirs.push(ci_llvm_lib);
|
||||
}
|
||||
|
||||
|
|
@ -1386,23 +1397,30 @@ impl<'a> Builder<'a> {
|
|||
compiler: Compiler,
|
||||
mode: Mode,
|
||||
target: TargetSelection,
|
||||
cmd: &str, // FIXME make this properly typed
|
||||
cmd_kind: Kind,
|
||||
) -> BootstrapCommand {
|
||||
let mut cargo;
|
||||
if cmd == "clippy" {
|
||||
cargo = self.cargo_clippy_cmd(compiler);
|
||||
cargo.arg(cmd);
|
||||
} else if let Some(subcmd) = cmd.strip_prefix("miri") {
|
||||
// Command must be "miri-X".
|
||||
let subcmd = subcmd
|
||||
.strip_prefix('-')
|
||||
.unwrap_or_else(|| panic!("expected `miri-$subcommand`, but got {}", cmd));
|
||||
cargo = self.cargo_miri_cmd(compiler);
|
||||
cargo.arg("miri").arg(subcmd);
|
||||
} else {
|
||||
cargo = command(&self.initial_cargo);
|
||||
cargo.arg(cmd);
|
||||
}
|
||||
let mut cargo = match cmd_kind {
|
||||
Kind::Clippy => {
|
||||
let mut cargo = self.cargo_clippy_cmd(compiler);
|
||||
cargo.arg(cmd_kind.as_str());
|
||||
cargo
|
||||
}
|
||||
Kind::MiriSetup => {
|
||||
let mut cargo = self.cargo_miri_cmd(compiler);
|
||||
cargo.arg("miri").arg("setup");
|
||||
cargo
|
||||
}
|
||||
Kind::MiriTest => {
|
||||
let mut cargo = self.cargo_miri_cmd(compiler);
|
||||
cargo.arg("miri").arg("test");
|
||||
cargo
|
||||
}
|
||||
_ => {
|
||||
let mut cargo = command(&self.initial_cargo);
|
||||
cargo.arg(cmd_kind.as_str());
|
||||
cargo
|
||||
}
|
||||
};
|
||||
|
||||
// Run cargo from the source root so it can find .cargo/config.
|
||||
// This matters when using vendoring and the working directory is outside the repository.
|
||||
|
|
@ -1431,7 +1449,7 @@ impl<'a> Builder<'a> {
|
|||
Color::Auto => {} // nothing to do
|
||||
}
|
||||
|
||||
if cmd != "install" {
|
||||
if cmd_kind != Kind::Install {
|
||||
cargo.arg("--target").arg(target.rustc_target_arg());
|
||||
} else {
|
||||
assert_eq!(target, compiler.host);
|
||||
|
|
@ -1440,8 +1458,11 @@ impl<'a> Builder<'a> {
|
|||
if self.config.rust_optimize.is_release() {
|
||||
// FIXME: cargo bench/install do not accept `--release`
|
||||
// and miri doesn't want it
|
||||
if cmd != "bench" && cmd != "install" && !cmd.starts_with("miri-") {
|
||||
cargo.arg("--release");
|
||||
match cmd_kind {
|
||||
Kind::Bench | Kind::Install | Kind::Miri | Kind::MiriSetup | Kind::MiriTest => {}
|
||||
_ => {
|
||||
cargo.arg("--release");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1464,9 +1485,9 @@ impl<'a> Builder<'a> {
|
|||
mode: Mode,
|
||||
source_type: SourceType,
|
||||
target: TargetSelection,
|
||||
cmd: &str, // FIXME make this properly typed
|
||||
cmd_kind: Kind,
|
||||
) -> Cargo {
|
||||
let mut cargo = self.bare_cargo(compiler, mode, target, cmd);
|
||||
let mut cargo = self.bare_cargo(compiler, mode, target, cmd_kind);
|
||||
let out_dir = self.stage_out(compiler, mode);
|
||||
|
||||
let mut hostflags = HostFlags::default();
|
||||
|
|
@ -1477,15 +1498,15 @@ impl<'a> Builder<'a> {
|
|||
self.clear_if_dirty(&out_dir, &backend);
|
||||
}
|
||||
|
||||
if cmd == "doc" || cmd == "rustdoc" {
|
||||
if cmd_kind == Kind::Doc {
|
||||
let my_out = match mode {
|
||||
// This is the intended out directory for compiler documentation.
|
||||
Mode::Rustc | Mode::ToolRustc => self.compiler_doc_out(target),
|
||||
Mode::Std => {
|
||||
if self.config.cmd.json() {
|
||||
out_dir.join(target.triple).join("json-doc")
|
||||
out_dir.join(target).join("json-doc")
|
||||
} else {
|
||||
out_dir.join(target.triple).join("doc")
|
||||
out_dir.join(target).join("doc")
|
||||
}
|
||||
}
|
||||
_ => panic!("doc mode {mode:?} not expected"),
|
||||
|
|
@ -1508,7 +1529,7 @@ impl<'a> Builder<'a> {
|
|||
|
||||
// Set a flag for `check`/`clippy`/`fix`, so that certain build
|
||||
// scripts can do less work (i.e. not building/requiring LLVM).
|
||||
if cmd == "check" || cmd == "clippy" || cmd == "fix" {
|
||||
if matches!(cmd_kind, Kind::Check | Kind::Clippy | Kind::Fix) {
|
||||
// If we've not yet built LLVM, or it's stale, then bust
|
||||
// the rustc_llvm cache. That will always work, even though it
|
||||
// may mean that on the next non-check build we'll need to rebuild
|
||||
|
|
@ -1558,7 +1579,7 @@ impl<'a> Builder<'a> {
|
|||
rustflags.arg("--cfg=bootstrap");
|
||||
}
|
||||
|
||||
if cmd == "clippy" {
|
||||
if cmd_kind == Kind::Clippy {
|
||||
// clippy overwrites sysroot if we pass it to cargo.
|
||||
// Pass it directly to clippy instead.
|
||||
// NOTE: this can't be fixed in clippy because we explicitly don't set `RUSTC`,
|
||||
|
|
@ -1654,7 +1675,7 @@ impl<'a> Builder<'a> {
|
|||
Mode::Std | Mode::ToolBootstrap | Mode::ToolStd => {}
|
||||
Mode::Rustc | Mode::Codegen | Mode::ToolRustc => {
|
||||
// Build proc macros both for the host and the target
|
||||
if target != compiler.host && cmd != "check" {
|
||||
if target != compiler.host && cmd_kind != Kind::Check {
|
||||
cargo.arg("-Zdual-proc-macros");
|
||||
rustflags.arg("-Zdual-proc-macros");
|
||||
}
|
||||
|
|
@ -1739,7 +1760,7 @@ impl<'a> Builder<'a> {
|
|||
}
|
||||
cargo.env("__CARGO_DEFAULT_LIB_METADATA", &metadata);
|
||||
|
||||
if cmd == "clippy" {
|
||||
if cmd_kind == Kind::Clippy {
|
||||
rustflags.arg("-Zforce-unstable-if-unmarked");
|
||||
}
|
||||
|
||||
|
|
@ -1755,10 +1776,15 @@ impl<'a> Builder<'a> {
|
|||
//
|
||||
// Only clear out the directory if we're compiling std; otherwise, we
|
||||
// should let Cargo take care of things for us (via depdep info)
|
||||
if !self.config.dry_run() && mode == Mode::Std && cmd == "build" {
|
||||
if !self.config.dry_run() && mode == Mode::Std && cmd_kind == Kind::Build {
|
||||
self.clear_if_dirty(&out_dir, &self.rustc(compiler));
|
||||
}
|
||||
|
||||
let rustdoc_path = match cmd_kind {
|
||||
Kind::Doc | Kind::Test | Kind::MiriTest => self.rustdoc(compiler),
|
||||
_ => PathBuf::from("/path/to/nowhere/rustdoc/not/required"),
|
||||
};
|
||||
|
||||
// Customize the compiler we're running. Specify the compiler to cargo
|
||||
// as our shim and then pass it some various options used to configure
|
||||
// how the actual compiler itself is called.
|
||||
|
|
@ -1772,15 +1798,7 @@ impl<'a> Builder<'a> {
|
|||
.env("RUSTC_SYSROOT", sysroot)
|
||||
.env("RUSTC_LIBDIR", libdir)
|
||||
.env("RUSTDOC", self.bootstrap_out.join("rustdoc"))
|
||||
.env(
|
||||
"RUSTDOC_REAL",
|
||||
// Make sure to handle both `test` and `miri-test` commands.
|
||||
if cmd == "doc" || cmd == "rustdoc" || (cmd.ends_with("test") && want_rustdoc) {
|
||||
self.rustdoc(compiler)
|
||||
} else {
|
||||
PathBuf::from("/path/to/nowhere/rustdoc/not/required")
|
||||
},
|
||||
)
|
||||
.env("RUSTDOC_REAL", rustdoc_path)
|
||||
.env("RUSTC_ERROR_METADATA_DST", self.extended_error_dir())
|
||||
.env("RUSTC_BREAK_ON_ICE", "1");
|
||||
|
||||
|
|
@ -1799,7 +1817,7 @@ impl<'a> Builder<'a> {
|
|||
}
|
||||
|
||||
// If this is for `miri-test`, prepare the sysroots.
|
||||
if cmd == "miri-test" {
|
||||
if cmd_kind == Kind::MiriTest {
|
||||
self.ensure(compile::Std::new(compiler, compiler.host));
|
||||
let host_sysroot = self.sysroot(compiler);
|
||||
let miri_sysroot = test::Miri::build_miri_sysroot(self, compiler, target);
|
||||
|
|
@ -1813,7 +1831,8 @@ impl<'a> Builder<'a> {
|
|||
rustflags.arg(&format!("-Zstack-protector={stack_protector}"));
|
||||
}
|
||||
|
||||
if !(["build", "check", "clippy", "fix", "rustc"].contains(&cmd)) && want_rustdoc {
|
||||
if !matches!(cmd_kind, Kind::Build | Kind::Check | Kind::Clippy | Kind::Fix) && want_rustdoc
|
||||
{
|
||||
cargo.env("RUSTDOC_LIBDIR", self.rustc_libdir(compiler));
|
||||
}
|
||||
|
||||
|
|
@ -2144,14 +2163,22 @@ impl<'a> Builder<'a> {
|
|||
// Try to use a sysroot-relative bindir, in case it was configured absolutely.
|
||||
cargo.env("RUSTC_INSTALL_BINDIR", self.config.bindir_relative());
|
||||
|
||||
cargo.force_coloring_in_ci(self.ci_env);
|
||||
cargo.force_coloring_in_ci();
|
||||
|
||||
// When we build Rust dylibs they're all intended for intermediate
|
||||
// usage, so make sure we pass the -Cprefer-dynamic flag instead of
|
||||
// linking all deps statically into the dylib.
|
||||
if matches!(mode, Mode::Std | Mode::Rustc) {
|
||||
if matches!(mode, Mode::Std) {
|
||||
rustflags.arg("-Cprefer-dynamic");
|
||||
}
|
||||
if matches!(mode, Mode::Rustc) && !self.link_std_into_rustc_driver(target) {
|
||||
rustflags.arg("-Cprefer-dynamic");
|
||||
}
|
||||
|
||||
cargo.env(
|
||||
"RUSTC_LINK_STD_INTO_RUSTC_DRIVER",
|
||||
if self.link_std_into_rustc_driver(target) { "1" } else { "0" },
|
||||
);
|
||||
|
||||
// When building incrementally we default to a lower ThinLTO import limit
|
||||
// (unless explicitly specified otherwise). This will produce a somewhat
|
||||
|
|
@ -2199,11 +2226,6 @@ impl<'a> Builder<'a> {
|
|||
rustdocflags.arg("--cfg=parallel_compiler");
|
||||
}
|
||||
|
||||
// Pass the value of `--rustc-args` from test command. If it's not a test command, this won't set anything.
|
||||
self.config.cmd.rustc_args().iter().for_each(|v| {
|
||||
rustflags.arg(v);
|
||||
});
|
||||
|
||||
Cargo {
|
||||
command: cargo,
|
||||
compiler,
|
||||
|
|
@ -2430,9 +2452,9 @@ impl Cargo {
|
|||
mode: Mode,
|
||||
source_type: SourceType,
|
||||
target: TargetSelection,
|
||||
cmd: &str, // FIXME make this properly typed
|
||||
cmd_kind: Kind,
|
||||
) -> Cargo {
|
||||
let mut cargo = builder.cargo(compiler, mode, source_type, target, cmd);
|
||||
let mut cargo = builder.cargo(compiler, mode, source_type, target, cmd_kind);
|
||||
cargo.configure_linker(builder);
|
||||
cargo
|
||||
}
|
||||
|
|
@ -2448,9 +2470,9 @@ impl Cargo {
|
|||
mode: Mode,
|
||||
source_type: SourceType,
|
||||
target: TargetSelection,
|
||||
cmd: &str, // FIXME make this properly typed
|
||||
cmd_kind: Kind,
|
||||
) -> Cargo {
|
||||
builder.cargo(compiler, mode, source_type, target, cmd)
|
||||
builder.cargo(compiler, mode, source_type, target, cmd_kind)
|
||||
}
|
||||
|
||||
pub fn rustdocflag(&mut self, arg: &str) -> &mut Cargo {
|
||||
|
|
|
|||
|
|
@ -1,27 +1,32 @@
|
|||
use std::thread;
|
||||
|
||||
use super::*;
|
||||
use crate::core::build_steps::doc::DocumentationFormat;
|
||||
use crate::core::config::Config;
|
||||
use std::thread;
|
||||
use crate::Flags;
|
||||
|
||||
fn configure(cmd: &str, host: &[&str], target: &[&str]) -> Config {
|
||||
configure_with_args(&[cmd.to_owned()], host, target)
|
||||
}
|
||||
|
||||
fn configure_with_args(cmd: &[String], host: &[&str], target: &[&str]) -> Config {
|
||||
let mut config = Config::parse(cmd);
|
||||
let mut config = Config::parse(Flags::parse(cmd));
|
||||
// don't save toolstates
|
||||
config.save_toolstates = None;
|
||||
config.dry_run = DryRun::SelfCheck;
|
||||
|
||||
// Ignore most submodules, since we don't need them for a dry run.
|
||||
// But make sure to check out the `doc` and `rust-analyzer` submodules, since some steps need them
|
||||
// just to know which commands to run.
|
||||
// Ignore most submodules, since we don't need them for a dry run, and the
|
||||
// tests run much faster without them.
|
||||
//
|
||||
// The src/doc/book submodule is needed because TheBook step tries to
|
||||
// access files even during a dry-run (may want to consider just skipping
|
||||
// that in a dry run).
|
||||
let submodule_build = Build::new(Config {
|
||||
// don't include LLVM, so CI doesn't require ninja/cmake to be installed
|
||||
rust_codegen_backends: vec![],
|
||||
..Config::parse(&["check".to_owned()])
|
||||
..Config::parse(Flags::parse(&["check".to_owned()]))
|
||||
});
|
||||
submodule_build.update_submodule(Path::new("src/doc/book"));
|
||||
submodule_build.require_submodule("src/doc/book", None);
|
||||
config.submodules = Some(false);
|
||||
|
||||
config.ninja_in_file = false;
|
||||
|
|
@ -75,13 +80,9 @@ macro_rules! std {
|
|||
|
||||
macro_rules! doc_std {
|
||||
($host:ident => $target:ident, stage = $stage:literal) => {{
|
||||
let config = configure("doc", &["A-A"], &["A-A"]);
|
||||
let build = Build::new(config);
|
||||
let builder = Builder::new(&build);
|
||||
doc::Std::new(
|
||||
$stage,
|
||||
TargetSelection::from_user(concat!(stringify!($target), "-", stringify!($target))),
|
||||
&builder,
|
||||
DocumentationFormat::Html,
|
||||
)
|
||||
}};
|
||||
|
|
@ -212,10 +213,11 @@ fn alias_and_path_for_library() {
|
|||
}
|
||||
|
||||
mod defaults {
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
use super::{configure, first, run_build};
|
||||
use crate::core::builder::*;
|
||||
use crate::Config;
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
#[test]
|
||||
fn build_default() {
|
||||
|
|
@ -323,9 +325,10 @@ mod defaults {
|
|||
}
|
||||
|
||||
mod dist {
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
use super::{first, run_build, Config};
|
||||
use crate::core::builder::*;
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
fn configure(host: &[&str], target: &[&str]) -> Config {
|
||||
Config { stage: 2, ..super::configure("dist", host, target) }
|
||||
|
|
@ -630,7 +633,7 @@ mod dist {
|
|||
config.paths = vec!["library/std".into()];
|
||||
config.cmd = Subcommand::Test {
|
||||
test_args: vec![],
|
||||
rustc_args: vec![],
|
||||
compiletest_rustc_args: vec![],
|
||||
no_fail_fast: false,
|
||||
no_doc: true,
|
||||
doc: false,
|
||||
|
|
@ -701,7 +704,7 @@ mod dist {
|
|||
let mut config = configure(&["A-A"], &["A-A"]);
|
||||
config.cmd = Subcommand::Test {
|
||||
test_args: vec![],
|
||||
rustc_args: vec![],
|
||||
compiletest_rustc_args: vec![],
|
||||
no_fail_fast: false,
|
||||
doc: true,
|
||||
no_doc: false,
|
||||
|
|
|
|||
|
|
@ -4,29 +4,27 @@
|
|||
//! how the build runs.
|
||||
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::cmp;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::env;
|
||||
use std::fmt::{self, Display};
|
||||
use std::fs;
|
||||
use std::io::IsTerminal;
|
||||
use std::path::{absolute, Path, PathBuf};
|
||||
use std::process::Command;
|
||||
use std::str::FromStr;
|
||||
use std::sync::OnceLock;
|
||||
use std::{cmp, env, fs};
|
||||
|
||||
use build_helper::exit;
|
||||
use build_helper::git::GitConfig;
|
||||
use serde::{Deserialize, Deserializer};
|
||||
use serde_derive::Deserialize;
|
||||
|
||||
use crate::core::build_steps::compile::CODEGEN_BACKEND_PREFIX;
|
||||
use crate::core::build_steps::llvm;
|
||||
pub use crate::core::config::flags::Subcommand;
|
||||
use crate::core::config::flags::{Color, Flags, Warnings};
|
||||
use crate::utils::cache::{Interned, INTERNER};
|
||||
use crate::utils::channel::{self, GitInfo};
|
||||
use crate::utils::helpers::{self, exe, get_closest_merge_base_commit, output, t};
|
||||
use build_helper::exit;
|
||||
use serde::{Deserialize, Deserializer};
|
||||
use serde_derive::Deserialize;
|
||||
|
||||
pub use crate::core::config::flags::Subcommand;
|
||||
use build_helper::git::GitConfig;
|
||||
|
||||
macro_rules! check_ci_llvm {
|
||||
($name:expr) => {
|
||||
|
|
@ -220,6 +218,7 @@ pub struct Config {
|
|||
pub llvm_thin_lto: bool,
|
||||
pub llvm_release_debuginfo: bool,
|
||||
pub llvm_static_stdcpp: bool,
|
||||
pub llvm_libzstd: bool,
|
||||
/// `None` if `llvm_from_ci` is true and we haven't yet downloaded llvm.
|
||||
#[cfg(not(test))]
|
||||
llvm_link_shared: Cell<Option<bool>>,
|
||||
|
|
@ -514,6 +513,15 @@ impl TargetSelection {
|
|||
pub fn is_windows(&self) -> bool {
|
||||
self.contains("windows")
|
||||
}
|
||||
|
||||
pub fn is_windows_gnu(&self) -> bool {
|
||||
self.ends_with("windows-gnu")
|
||||
}
|
||||
|
||||
/// Path to the file defining the custom target, if any.
|
||||
pub fn filepath(&self) -> Option<&Path> {
|
||||
self.file.as_ref().map(Path::new)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for TargetSelection {
|
||||
|
|
@ -538,6 +546,14 @@ impl PartialEq<&str> for TargetSelection {
|
|||
}
|
||||
}
|
||||
|
||||
// Targets are often used as directory names throughout bootstrap.
|
||||
// This impl makes it more ergonomics to use them as such.
|
||||
impl AsRef<Path> for TargetSelection {
|
||||
fn as_ref(&self) -> &Path {
|
||||
self.triple.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
/// Per-target configuration stored in the global configuration structure.
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq)]
|
||||
pub struct Target {
|
||||
|
|
@ -875,6 +891,7 @@ define_config! {
|
|||
plugins: Option<bool> = "plugins",
|
||||
ccache: Option<StringOrBool> = "ccache",
|
||||
static_libstdcpp: Option<bool> = "static-libstdcpp",
|
||||
libzstd: Option<bool> = "libzstd",
|
||||
ninja: Option<bool> = "ninja",
|
||||
targets: Option<String> = "targets",
|
||||
experimental_targets: Option<String> = "experimental-targets",
|
||||
|
|
@ -1150,6 +1167,7 @@ impl Config {
|
|||
llvm_optimize: true,
|
||||
ninja_in_file: true,
|
||||
llvm_static_stdcpp: false,
|
||||
llvm_libzstd: false,
|
||||
backtrace: true,
|
||||
rust_optimize: RustOptimize::Bool(true),
|
||||
rust_optimize_tests: true,
|
||||
|
|
@ -1185,7 +1203,7 @@ impl Config {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn parse(args: &[String]) -> Config {
|
||||
pub fn parse(flags: Flags) -> Config {
|
||||
#[cfg(test)]
|
||||
fn get_toml(_: &Path) -> TomlConfig {
|
||||
TomlConfig::default()
|
||||
|
|
@ -1215,11 +1233,10 @@ impl Config {
|
|||
exit!(2);
|
||||
})
|
||||
}
|
||||
Self::parse_inner(args, get_toml)
|
||||
Self::parse_inner(flags, get_toml)
|
||||
}
|
||||
|
||||
pub(crate) fn parse_inner(args: &[String], get_toml: impl Fn(&Path) -> TomlConfig) -> Config {
|
||||
let mut flags = Flags::parse(args);
|
||||
pub(crate) fn parse_inner(mut flags: Flags, get_toml: impl Fn(&Path) -> TomlConfig) -> Config {
|
||||
let mut config = Config::default_opts();
|
||||
|
||||
// Set flags.
|
||||
|
|
@ -1322,7 +1339,11 @@ impl Config {
|
|||
// Give a hard error if `--config` or `RUST_BOOTSTRAP_CONFIG` are set to a missing path,
|
||||
// but not if `config.toml` hasn't been created.
|
||||
let mut toml = if !using_default_path || toml_path.exists() {
|
||||
config.config = Some(toml_path.clone());
|
||||
config.config = Some(if cfg!(not(feature = "bootstrap-self-test")) {
|
||||
toml_path.canonicalize().unwrap()
|
||||
} else {
|
||||
toml_path.clone()
|
||||
});
|
||||
get_toml(&toml_path)
|
||||
} else {
|
||||
config.config = None;
|
||||
|
|
@ -1460,7 +1481,7 @@ impl Config {
|
|||
config.download_beta_toolchain();
|
||||
config
|
||||
.out
|
||||
.join(config.build.triple)
|
||||
.join(config.build)
|
||||
.join("stage0")
|
||||
.join("bin")
|
||||
.join(exe("rustc", config.build))
|
||||
|
|
@ -1475,7 +1496,7 @@ impl Config {
|
|||
config.download_beta_toolchain();
|
||||
config
|
||||
.out
|
||||
.join(config.build.triple)
|
||||
.join(config.build)
|
||||
.join("stage0")
|
||||
.join("bin")
|
||||
.join(exe("cargo", config.build))
|
||||
|
|
@ -1784,6 +1805,7 @@ impl Config {
|
|||
plugins,
|
||||
ccache,
|
||||
static_libstdcpp,
|
||||
libzstd,
|
||||
ninja,
|
||||
targets,
|
||||
experimental_targets,
|
||||
|
|
@ -1818,6 +1840,7 @@ impl Config {
|
|||
set(&mut config.llvm_thin_lto, thin_lto);
|
||||
set(&mut config.llvm_release_debuginfo, release_debuginfo);
|
||||
set(&mut config.llvm_static_stdcpp, static_libstdcpp);
|
||||
set(&mut config.llvm_libzstd, libzstd);
|
||||
if let Some(v) = link_shared {
|
||||
config.llvm_link_shared.set(Some(v));
|
||||
}
|
||||
|
|
@ -1842,6 +1865,23 @@ impl Config {
|
|||
config.llvm_from_ci = config.parse_download_ci_llvm(download_ci_llvm, asserts);
|
||||
|
||||
if config.llvm_from_ci {
|
||||
let warn = |option: &str| {
|
||||
println!(
|
||||
"WARNING: `{option}` will only be used on `compiler/rustc_llvm` build, not for the LLVM build."
|
||||
);
|
||||
println!(
|
||||
"HELP: To use `{option}` for LLVM builds, set `download-ci-llvm` option to false."
|
||||
);
|
||||
};
|
||||
|
||||
if static_libstdcpp.is_some() {
|
||||
warn("static-libstdcpp");
|
||||
}
|
||||
|
||||
if link_shared.is_some() {
|
||||
warn("link-shared");
|
||||
}
|
||||
|
||||
// None of the LLVM options, except assertions, are supported
|
||||
// when using downloaded LLVM. We could just ignore these but
|
||||
// that's potentially confusing, so force them to not be
|
||||
|
|
@ -1851,9 +1891,7 @@ impl Config {
|
|||
check_ci_llvm!(optimize_toml);
|
||||
check_ci_llvm!(thin_lto);
|
||||
check_ci_llvm!(release_debuginfo);
|
||||
// CI-built LLVM can be either dynamic or static. We won't know until we download it.
|
||||
check_ci_llvm!(link_shared);
|
||||
check_ci_llvm!(static_libstdcpp);
|
||||
check_ci_llvm!(libzstd);
|
||||
check_ci_llvm!(targets);
|
||||
check_ci_llvm!(experimental_targets);
|
||||
check_ci_llvm!(clang_cl);
|
||||
|
|
@ -2094,7 +2132,7 @@ impl Config {
|
|||
|
||||
// CI should always run stage 2 builds, unless it specifically states otherwise
|
||||
#[cfg(not(test))]
|
||||
if flags.stage.is_none() && crate::CiEnv::current() != crate::CiEnv::None {
|
||||
if flags.stage.is_none() && build_helper::ci::CiEnv::is_ci() {
|
||||
match config.cmd {
|
||||
Subcommand::Test { .. }
|
||||
| Subcommand::Miri { .. }
|
||||
|
|
@ -2251,13 +2289,13 @@ impl Config {
|
|||
/// The absolute path to the downloaded LLVM artifacts.
|
||||
pub(crate) fn ci_llvm_root(&self) -> PathBuf {
|
||||
assert!(self.llvm_from_ci);
|
||||
self.out.join(&*self.build.triple).join("ci-llvm")
|
||||
self.out.join(self.build).join("ci-llvm")
|
||||
}
|
||||
|
||||
/// Directory where the extracted `rustc-dev` component is stored.
|
||||
pub(crate) fn ci_rustc_dir(&self) -> PathBuf {
|
||||
assert!(self.download_rustc());
|
||||
self.out.join(self.build.triple).join("ci-rustc")
|
||||
self.out.join(self.build).join("ci-rustc")
|
||||
}
|
||||
|
||||
/// Determine whether llvm should be linked dynamically.
|
||||
|
|
@ -2404,8 +2442,11 @@ impl Config {
|
|||
.unwrap_or_else(|| SplitDebuginfo::default_for_platform(target))
|
||||
}
|
||||
|
||||
pub fn submodules(&self, rust_info: &GitInfo) -> bool {
|
||||
self.submodules.unwrap_or(rust_info.is_managed_git_subrepository())
|
||||
/// Returns whether or not submodules should be managed by bootstrap.
|
||||
pub fn submodules(&self) -> bool {
|
||||
// If not specified in config, the default is to only manage
|
||||
// submodules if we're currently inside a git repository.
|
||||
self.submodules.unwrap_or(self.rust_info.is_managed_git_subrepository())
|
||||
}
|
||||
|
||||
pub fn codegen_backends(&self, target: TargetSelection) -> &[String] {
|
||||
|
|
|
|||
|
|
@ -183,9 +183,9 @@ pub struct Flags {
|
|||
}
|
||||
|
||||
impl Flags {
|
||||
pub fn parse(args: &[String]) -> Self {
|
||||
let first = String::from("x.py");
|
||||
let it = std::iter::once(&first).chain(args.iter());
|
||||
/// Check if `<cmd> -h -v` was passed.
|
||||
/// If yes, print the available paths and return `true`.
|
||||
pub fn try_parse_verbose_help(args: &[String]) -> bool {
|
||||
// We need to check for `<cmd> -h -v`, in which case we list the paths
|
||||
#[derive(Parser)]
|
||||
#[command(disable_help_flag(true))]
|
||||
|
|
@ -198,10 +198,10 @@ impl Flags {
|
|||
cmd: Kind,
|
||||
}
|
||||
if let Ok(HelpVerboseOnly { help: true, verbose: 1.., cmd: subcommand }) =
|
||||
HelpVerboseOnly::try_parse_from(it.clone())
|
||||
HelpVerboseOnly::try_parse_from(normalize_args(args))
|
||||
{
|
||||
println!("NOTE: updating submodules before printing available paths");
|
||||
let config = Config::parse(&[String::from("build")]);
|
||||
let config = Config::parse(Self::parse(&[String::from("build")]));
|
||||
let build = Build::new(config);
|
||||
let paths = Builder::get_help(&build, subcommand);
|
||||
if let Some(s) = paths {
|
||||
|
|
@ -209,11 +209,21 @@ impl Flags {
|
|||
} else {
|
||||
panic!("No paths available for subcommand `{}`", subcommand.as_str());
|
||||
}
|
||||
crate::exit!(0);
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
||||
Flags::parse_from(it)
|
||||
}
|
||||
|
||||
pub fn parse(args: &[String]) -> Self {
|
||||
Flags::parse_from(normalize_args(args))
|
||||
}
|
||||
}
|
||||
|
||||
fn normalize_args(args: &[String]) -> Vec<String> {
|
||||
let first = String::from("x.py");
|
||||
let it = std::iter::once(first).chain(args.iter().cloned());
|
||||
it.collect()
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, clap::Subcommand)]
|
||||
|
|
@ -347,9 +357,9 @@ pub enum Subcommand {
|
|||
/// extra arguments to be passed for the test tool being used
|
||||
/// (e.g. libtest, compiletest or rustdoc)
|
||||
test_args: Vec<String>,
|
||||
/// extra options to pass the compiler when running tests
|
||||
/// extra options to pass the compiler when running compiletest tests
|
||||
#[arg(long, value_name = "ARGS", allow_hyphen_values(true))]
|
||||
rustc_args: Vec<String>,
|
||||
compiletest_rustc_args: Vec<String>,
|
||||
#[arg(long)]
|
||||
/// do not run doc tests
|
||||
no_doc: bool,
|
||||
|
|
@ -392,9 +402,6 @@ pub enum Subcommand {
|
|||
/// extra arguments to be passed for the test tool being used
|
||||
/// (e.g. libtest, compiletest or rustdoc)
|
||||
test_args: Vec<String>,
|
||||
/// extra options to pass the compiler when running tests
|
||||
#[arg(long, value_name = "ARGS", allow_hyphen_values(true))]
|
||||
rustc_args: Vec<String>,
|
||||
#[arg(long)]
|
||||
/// do not run doc tests
|
||||
no_doc: bool,
|
||||
|
|
@ -499,10 +506,10 @@ impl Subcommand {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn rustc_args(&self) -> Vec<&str> {
|
||||
pub fn compiletest_rustc_args(&self) -> Vec<&str> {
|
||||
match *self {
|
||||
Subcommand::Test { ref rustc_args, .. } | Subcommand::Miri { ref rustc_args, .. } => {
|
||||
rustc_args.iter().flat_map(|s| s.split_whitespace()).collect()
|
||||
Subcommand::Test { ref compiletest_rustc_args, .. } => {
|
||||
compiletest_rustc_args.iter().flat_map(|s| s.split_whitespace()).collect()
|
||||
}
|
||||
_ => vec![],
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#[allow(clippy::module_inception)]
|
||||
mod config;
|
||||
pub(crate) mod flags;
|
||||
pub mod flags;
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,22 +1,21 @@
|
|||
use super::{flags::Flags, ChangeIdWrapper, Config};
|
||||
use crate::core::build_steps::clippy::get_clippy_rules_in_order;
|
||||
use crate::core::config::Target;
|
||||
use crate::core::config::TargetSelection;
|
||||
use crate::core::config::{LldMode, TomlConfig};
|
||||
use std::env;
|
||||
use std::fs::{remove_file, File};
|
||||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
|
||||
use clap::CommandFactory;
|
||||
use serde::Deserialize;
|
||||
use std::{
|
||||
env,
|
||||
fs::{remove_file, File},
|
||||
io::Write,
|
||||
path::Path,
|
||||
};
|
||||
|
||||
use super::flags::Flags;
|
||||
use super::{ChangeIdWrapper, Config};
|
||||
use crate::core::build_steps::clippy::get_clippy_rules_in_order;
|
||||
use crate::core::config::{LldMode, Target, TargetSelection, TomlConfig};
|
||||
|
||||
fn parse(config: &str) -> Config {
|
||||
Config::parse_inner(&["check".to_string(), "--config=/does/not/exist".to_string()], |&_| {
|
||||
toml::from_str(&config).unwrap()
|
||||
})
|
||||
Config::parse_inner(
|
||||
Flags::parse(&["check".to_string(), "--config=/does/not/exist".to_string()]),
|
||||
|&_| toml::from_str(&config).unwrap(),
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -110,7 +109,7 @@ fn clap_verify() {
|
|||
#[test]
|
||||
fn override_toml() {
|
||||
let config = Config::parse_inner(
|
||||
&[
|
||||
Flags::parse(&[
|
||||
"check".to_owned(),
|
||||
"--config=/does/not/exist".to_owned(),
|
||||
"--set=change-id=1".to_owned(),
|
||||
|
|
@ -123,7 +122,7 @@ fn override_toml() {
|
|||
"--set=target.x86_64-unknown-linux-gnu.rpath=false".to_owned(),
|
||||
"--set=target.aarch64-unknown-linux-gnu.sanitizers=false".to_owned(),
|
||||
"--set=target.aarch64-apple-darwin.runner=apple".to_owned(),
|
||||
],
|
||||
]),
|
||||
|&_| {
|
||||
toml::from_str(
|
||||
r#"
|
||||
|
|
@ -203,12 +202,12 @@ runner = "x86_64-runner"
|
|||
#[should_panic]
|
||||
fn override_toml_duplicate() {
|
||||
Config::parse_inner(
|
||||
&[
|
||||
Flags::parse(&[
|
||||
"check".to_owned(),
|
||||
"--config=/does/not/exist".to_string(),
|
||||
"--set=change-id=1".to_owned(),
|
||||
"--set=change-id=2".to_owned(),
|
||||
],
|
||||
]),
|
||||
|&_| toml::from_str("change-id = 0").unwrap(),
|
||||
);
|
||||
}
|
||||
|
|
@ -228,7 +227,7 @@ fn profile_user_dist() {
|
|||
.and_then(|table: toml::Value| TomlConfig::deserialize(table))
|
||||
.unwrap()
|
||||
}
|
||||
Config::parse_inner(&["check".to_owned()], get_toml);
|
||||
Config::parse_inner(Flags::parse(&["check".to_owned()]), get_toml);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -303,7 +302,7 @@ fn order_of_clippy_rules() {
|
|||
"-Aclippy::foo1".to_string(),
|
||||
"-Aclippy::foo2".to_string(),
|
||||
];
|
||||
let config = Config::parse(&args);
|
||||
let config = Config::parse(Flags::parse(&args));
|
||||
|
||||
let actual = match &config.cmd {
|
||||
crate::Subcommand::Clippy { allow, deny, warn, forbid, .. } => {
|
||||
|
|
|
|||
|
|
@ -1,19 +1,16 @@
|
|||
use std::{
|
||||
env,
|
||||
ffi::OsString,
|
||||
fs::{self, File},
|
||||
io::{BufRead, BufReader, BufWriter, ErrorKind, Write},
|
||||
path::{Path, PathBuf},
|
||||
process::{Command, Stdio},
|
||||
sync::OnceLock,
|
||||
};
|
||||
use std::env;
|
||||
use std::ffi::OsString;
|
||||
use std::fs::{self, File};
|
||||
use std::io::{BufRead, BufReader, BufWriter, ErrorKind, Write};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::{Command, Stdio};
|
||||
use std::sync::OnceLock;
|
||||
|
||||
use build_helper::ci::CiEnv;
|
||||
use xz2::bufread::XzDecoder;
|
||||
|
||||
use crate::utils::exec::{command, BootstrapCommand};
|
||||
use crate::utils::helpers::hex_encode;
|
||||
use crate::utils::helpers::{check_run, exe, move_file, program_out_of_date};
|
||||
use crate::utils::helpers::{check_run, exe, hex_encode, move_file, program_out_of_date};
|
||||
use crate::{t, Config};
|
||||
|
||||
static SHOULD_FIX_BINS_AND_DYLIBS: OnceLock<bool> = OnceLock::new();
|
||||
|
|
@ -382,7 +379,7 @@ impl Config {
|
|||
let version = &self.stage0_metadata.compiler.version;
|
||||
let host = self.build;
|
||||
|
||||
let bin_root = self.out.join(host.triple).join("stage0");
|
||||
let bin_root = self.out.join(host).join("stage0");
|
||||
let clippy_stamp = bin_root.join(".clippy-stamp");
|
||||
let cargo_clippy = bin_root.join("bin").join(exe("cargo-clippy", host));
|
||||
if cargo_clippy.exists() && !program_out_of_date(&clippy_stamp, date) {
|
||||
|
|
@ -415,7 +412,7 @@ impl Config {
|
|||
let channel = format!("{version}-{date}");
|
||||
|
||||
let host = self.build;
|
||||
let bin_root = self.out.join(host.triple).join("rustfmt");
|
||||
let bin_root = self.out.join(host).join("rustfmt");
|
||||
let rustfmt_path = bin_root.join("bin").join(exe("rustfmt", host));
|
||||
let rustfmt_stamp = bin_root.join(".rustfmt-stamp");
|
||||
if rustfmt_path.exists() && !program_out_of_date(&rustfmt_stamp, &channel) {
|
||||
|
|
@ -522,7 +519,7 @@ impl Config {
|
|||
extra_components: &[&str],
|
||||
download_component: fn(&Config, String, &str, &str),
|
||||
) {
|
||||
let host = self.build.triple;
|
||||
let host = self.build;
|
||||
let bin_root = self.out.join(host).join(sysroot);
|
||||
let rustc_stamp = bin_root.join(".rustc-stamp");
|
||||
|
||||
|
|
@ -595,7 +592,7 @@ impl Config {
|
|||
t!(fs::create_dir_all(&cache_dir));
|
||||
}
|
||||
|
||||
let bin_root = self.out.join(self.build.triple).join(destination);
|
||||
let bin_root = self.out.join(self.build).join(destination);
|
||||
let tarball = cache_dir.join(&filename);
|
||||
let (base_url, url, should_verify) = match mode {
|
||||
DownloadSource::CI => {
|
||||
|
|
|
|||
|
|
@ -86,6 +86,9 @@ fn workspace_members(build: &Build) -> Vec<Package> {
|
|||
packages
|
||||
};
|
||||
|
||||
// Collects `metadata.packages` from all workspaces.
|
||||
collect_metadata("Cargo.toml")
|
||||
// Collects `metadata.packages` from the root and library workspaces.
|
||||
let mut packages = vec![];
|
||||
packages.extend(collect_metadata("Cargo.toml"));
|
||||
packages.extend(collect_metadata("library/Cargo.toml"));
|
||||
packages
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,19 +9,17 @@
|
|||
//! practice that's likely not true!
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
#[cfg(not(feature = "bootstrap-self-test"))]
|
||||
use std::collections::HashSet;
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
use std::{env, fs};
|
||||
|
||||
#[cfg(not(feature = "bootstrap-self-test"))]
|
||||
use crate::builder::Builder;
|
||||
use crate::builder::Kind;
|
||||
#[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;
|
||||
use crate::utils::exec::command;
|
||||
use crate::Build;
|
||||
|
|
@ -262,7 +260,9 @@ than building it.
|
|||
|
||||
if !has_target {
|
||||
// This might also be a custom target, so check the target file that could have been specified by the user.
|
||||
if let Some(custom_target_path) = env::var_os("RUST_TARGET_PATH") {
|
||||
if target.filepath().is_some_and(|p| p.exists()) {
|
||||
has_target = true;
|
||||
} else if let Some(custom_target_path) = env::var_os("RUST_TARGET_PATH") {
|
||||
let mut target_filename = OsString::from(&target_str);
|
||||
// Target filename ends with `.json`.
|
||||
target_filename.push(".json");
|
||||
|
|
@ -277,8 +277,12 @@ than building it.
|
|||
|
||||
if !has_target {
|
||||
panic!(
|
||||
"No such target exists in the target list,
|
||||
specify a correct location of the JSON specification file for custom targets!"
|
||||
"No such target exists in the target list,\n\
|
||||
make sure to correctly specify the location \
|
||||
of the JSON specification file \
|
||||
for custom targets!\n\
|
||||
Use BOOTSTRAP_SKIP_TARGET_SANITY=1 to \
|
||||
bypass this check."
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,17 +18,15 @@
|
|||
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::env;
|
||||
use std::fmt::Display;
|
||||
use std::fs::{self, File};
|
||||
use std::io;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
use std::str;
|
||||
use std::sync::OnceLock;
|
||||
use std::time::SystemTime;
|
||||
use std::{env, io, str};
|
||||
|
||||
use build_helper::ci::{gha, CiEnv};
|
||||
use build_helper::ci::gha;
|
||||
use build_helper::exit;
|
||||
use sha2::digest::Digest;
|
||||
use termcolor::{ColorChoice, StandardStream, WriteColor};
|
||||
|
|
@ -37,9 +35,7 @@ use utils::helpers::hex_encode;
|
|||
|
||||
use crate::core::builder;
|
||||
use crate::core::builder::{Builder, Kind};
|
||||
use crate::core::config::{flags, LldMode};
|
||||
use crate::core::config::{DryRun, Target};
|
||||
use crate::core::config::{LlvmLibunwind, TargetSelection};
|
||||
use crate::core::config::{flags, DryRun, LldMode, LlvmLibunwind, Target, TargetSelection};
|
||||
use crate::utils::exec::{command, BehaviorOnFailure, BootstrapCommand, CommandOutput, OutputMode};
|
||||
use crate::utils::helpers::{self, dir_is_empty, exe, libdir, mtime, output, symlink_dir};
|
||||
|
||||
|
|
@ -47,8 +43,9 @@ mod core;
|
|||
mod utils;
|
||||
|
||||
pub use core::builder::PathSet;
|
||||
pub use core::config::flags::Subcommand;
|
||||
pub use core::config::flags::{Flags, Subcommand};
|
||||
pub use core::config::Config;
|
||||
|
||||
pub use utils::change_tracker::{
|
||||
find_recent_config_change_ids, human_readable_changes, CONFIG_CHANGE_HISTORY,
|
||||
};
|
||||
|
|
@ -171,7 +168,6 @@ pub struct Build {
|
|||
crates: HashMap<String, Crate>,
|
||||
crate_paths: HashMap<PathBuf, String>,
|
||||
is_sudo: bool,
|
||||
ci_env: CiEnv,
|
||||
delayed_failures: RefCell<Vec<String>>,
|
||||
prerelease_version: Cell<Option<u32>>,
|
||||
|
||||
|
|
@ -403,7 +399,6 @@ impl Build {
|
|||
crates: HashMap::new(),
|
||||
crate_paths: HashMap::new(),
|
||||
is_sudo,
|
||||
ci_env: CiEnv::current(),
|
||||
delayed_failures: RefCell::new(Vec::new()),
|
||||
prerelease_version: Cell::new(None),
|
||||
|
||||
|
|
@ -441,7 +436,13 @@ impl Build {
|
|||
// Cargo.toml files.
|
||||
let rust_submodules = ["library/backtrace", "library/stdarch"];
|
||||
for s in rust_submodules {
|
||||
build.update_submodule(Path::new(s));
|
||||
build.require_submodule(
|
||||
s,
|
||||
Some(
|
||||
"The submodule is required for the standard library \
|
||||
and the main Cargo workspace.",
|
||||
),
|
||||
);
|
||||
}
|
||||
// Now, update all existing submodules.
|
||||
build.update_existing_submodules();
|
||||
|
|
@ -451,7 +452,7 @@ impl Build {
|
|||
}
|
||||
|
||||
// Make a symbolic link so we can use a consistent directory in the documentation.
|
||||
let build_triple = build.out.join(build.build.triple);
|
||||
let build_triple = build.out.join(build.build);
|
||||
t!(fs::create_dir_all(&build_triple));
|
||||
let host = build.out.join("host");
|
||||
if host.is_symlink() {
|
||||
|
|
@ -470,12 +471,17 @@ impl Build {
|
|||
build
|
||||
}
|
||||
|
||||
// modified from `check_submodule` and `update_submodule` in bootstrap.py
|
||||
/// Given a path to the directory of a submodule, update it.
|
||||
///
|
||||
/// `relative_path` should be relative to the root of the git repository, not an absolute path.
|
||||
pub(crate) fn update_submodule(&self, relative_path: &Path) {
|
||||
if !self.config.submodules(self.rust_info()) {
|
||||
///
|
||||
/// This *does not* update the submodule if `config.toml` explicitly says
|
||||
/// not to, or if we're not in a git repository (like a plain source
|
||||
/// tarball). Typically [`Build::require_submodule`] should be
|
||||
/// used instead to provide a nice error to the user if the submodule is
|
||||
/// missing.
|
||||
fn update_submodule(&self, relative_path: &str) {
|
||||
if !self.config.submodules() {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -522,7 +528,7 @@ impl Build {
|
|||
return;
|
||||
}
|
||||
|
||||
println!("Updating submodule {}", relative_path.display());
|
||||
println!("Updating submodule {relative_path}");
|
||||
helpers::git(Some(&self.src))
|
||||
.run_always()
|
||||
.args(["submodule", "-q", "sync"])
|
||||
|
|
@ -576,11 +582,53 @@ impl Build {
|
|||
}
|
||||
}
|
||||
|
||||
/// Updates a submodule, and exits with a failure if submodule management
|
||||
/// is disabled and the submodule does not exist.
|
||||
///
|
||||
/// The given submodule name should be its path relative to the root of
|
||||
/// the main repository.
|
||||
///
|
||||
/// The given `err_hint` will be shown to the user if the submodule is not
|
||||
/// checked out and submodule management is disabled.
|
||||
pub fn require_submodule(&self, submodule: &str, err_hint: Option<&str>) {
|
||||
// When testing bootstrap itself, it is much faster to ignore
|
||||
// submodules. Almost all Steps work fine without their submodules.
|
||||
if cfg!(test) && !self.config.submodules() {
|
||||
return;
|
||||
}
|
||||
self.update_submodule(submodule);
|
||||
let absolute_path = self.config.src.join(submodule);
|
||||
if dir_is_empty(&absolute_path) {
|
||||
let maybe_enable = if !self.config.submodules()
|
||||
&& self.config.rust_info.is_managed_git_subrepository()
|
||||
{
|
||||
"\nConsider setting `build.submodules = true` or manually initializing the submodules."
|
||||
} else {
|
||||
""
|
||||
};
|
||||
let err_hint = err_hint.map_or_else(String::new, |e| format!("\n{e}"));
|
||||
eprintln!(
|
||||
"submodule {submodule} does not appear to be checked out, \
|
||||
but it is required for this step{maybe_enable}{err_hint}"
|
||||
);
|
||||
exit!(1);
|
||||
}
|
||||
}
|
||||
|
||||
/// Updates all submodules, and exits with an error if submodule
|
||||
/// management is disabled and the submodule does not exist.
|
||||
pub fn require_and_update_all_submodules(&self) {
|
||||
for submodule in build_helper::util::parse_gitmodules(&self.src) {
|
||||
self.require_submodule(submodule, None);
|
||||
}
|
||||
}
|
||||
|
||||
/// If any submodule has been initialized already, sync it unconditionally.
|
||||
/// This avoids contributors checking in a submodule change by accident.
|
||||
pub fn update_existing_submodules(&self) {
|
||||
// Avoid running git when there isn't a git checkout.
|
||||
if !self.config.submodules(self.rust_info()) {
|
||||
fn update_existing_submodules(&self) {
|
||||
// Avoid running git when there isn't a git checkout, or the user has
|
||||
// explicitly disabled submodules in `config.toml`.
|
||||
if !self.config.submodules() {
|
||||
return;
|
||||
}
|
||||
let output = helpers::git(Some(&self.src))
|
||||
|
|
@ -592,22 +640,23 @@ impl Build {
|
|||
for line in output.lines() {
|
||||
// Look for `submodule.$name.path = $path`
|
||||
// Sample output: `submodule.src/rust-installer.path src/tools/rust-installer`
|
||||
let submodule = Path::new(line.split_once(' ').unwrap().1);
|
||||
let submodule = line.split_once(' ').unwrap().1;
|
||||
let path = Path::new(submodule);
|
||||
// Don't update the submodule unless it's already been cloned.
|
||||
if GitInfo::new(false, submodule).is_managed_git_subrepository() {
|
||||
if GitInfo::new(false, path).is_managed_git_subrepository() {
|
||||
self.update_submodule(submodule);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Updates the given submodule only if it's initialized already; nothing happens otherwise.
|
||||
pub fn update_existing_submodule(&self, submodule: &Path) {
|
||||
pub fn update_existing_submodule(&self, submodule: &str) {
|
||||
// Avoid running git when there isn't a git checkout.
|
||||
if !self.config.submodules(self.rust_info()) {
|
||||
if !self.config.submodules() {
|
||||
return;
|
||||
}
|
||||
|
||||
if GitInfo::new(false, submodule).is_managed_git_subrepository() {
|
||||
if GitInfo::new(false, Path::new(submodule)).is_managed_git_subrepository() {
|
||||
self.update_submodule(submodule);
|
||||
}
|
||||
}
|
||||
|
|
@ -758,10 +807,7 @@ impl Build {
|
|||
}
|
||||
|
||||
fn tools_dir(&self, compiler: Compiler) -> PathBuf {
|
||||
let out = self
|
||||
.out
|
||||
.join(&*compiler.host.triple)
|
||||
.join(format!("stage{}-tools-bin", compiler.stage));
|
||||
let out = self.out.join(compiler.host).join(format!("stage{}-tools-bin", compiler.stage));
|
||||
t!(fs::create_dir_all(&out));
|
||||
out
|
||||
}
|
||||
|
|
@ -778,14 +824,14 @@ impl Build {
|
|||
Mode::ToolBootstrap => "-bootstrap-tools",
|
||||
Mode::ToolStd | Mode::ToolRustc => "-tools",
|
||||
};
|
||||
self.out.join(&*compiler.host.triple).join(format!("stage{}{}", compiler.stage, suffix))
|
||||
self.out.join(compiler.host).join(format!("stage{}{}", compiler.stage, suffix))
|
||||
}
|
||||
|
||||
/// Returns the root output directory for all Cargo output in a given stage,
|
||||
/// running a particular compiler, whether or not we're building the
|
||||
/// standard library, and targeting the specified architecture.
|
||||
fn cargo_out(&self, compiler: Compiler, mode: Mode, target: TargetSelection) -> PathBuf {
|
||||
self.stage_out(compiler, mode).join(&*target.triple).join(self.cargo_dir())
|
||||
self.stage_out(compiler, mode).join(target).join(self.cargo_dir())
|
||||
}
|
||||
|
||||
/// Root output directory of LLVM for `target`
|
||||
|
|
@ -796,36 +842,36 @@ impl Build {
|
|||
if self.config.llvm_from_ci && self.config.build == target {
|
||||
self.config.ci_llvm_root()
|
||||
} else {
|
||||
self.out.join(&*target.triple).join("llvm")
|
||||
self.out.join(target).join("llvm")
|
||||
}
|
||||
}
|
||||
|
||||
fn lld_out(&self, target: TargetSelection) -> PathBuf {
|
||||
self.out.join(&*target.triple).join("lld")
|
||||
self.out.join(target).join("lld")
|
||||
}
|
||||
|
||||
/// Output directory for all documentation for a target
|
||||
fn doc_out(&self, target: TargetSelection) -> PathBuf {
|
||||
self.out.join(&*target.triple).join("doc")
|
||||
self.out.join(target).join("doc")
|
||||
}
|
||||
|
||||
/// Output directory for all JSON-formatted documentation for a target
|
||||
fn json_doc_out(&self, target: TargetSelection) -> PathBuf {
|
||||
self.out.join(&*target.triple).join("json-doc")
|
||||
self.out.join(target).join("json-doc")
|
||||
}
|
||||
|
||||
fn test_out(&self, target: TargetSelection) -> PathBuf {
|
||||
self.out.join(&*target.triple).join("test")
|
||||
self.out.join(target).join("test")
|
||||
}
|
||||
|
||||
/// Output directory for all documentation for a target
|
||||
fn compiler_doc_out(&self, target: TargetSelection) -> PathBuf {
|
||||
self.out.join(&*target.triple).join("compiler-doc")
|
||||
self.out.join(target).join("compiler-doc")
|
||||
}
|
||||
|
||||
/// Output directory for some generated md crate documentation for a target (temporary)
|
||||
fn md_doc_out(&self, target: TargetSelection) -> PathBuf {
|
||||
self.out.join(&*target.triple).join("md-doc")
|
||||
self.out.join(target).join("md-doc")
|
||||
}
|
||||
|
||||
/// Returns `true` if this is an external version of LLVM not managed by bootstrap.
|
||||
|
|
@ -905,7 +951,7 @@ impl Build {
|
|||
|
||||
/// Directory for libraries built from C/C++ code and shared between stages.
|
||||
fn native_dir(&self, target: TargetSelection) -> PathBuf {
|
||||
self.out.join(&*target.triple).join("native")
|
||||
self.out.join(target).join("native")
|
||||
}
|
||||
|
||||
/// Root output directory for rust_test_helpers library compiled for
|
||||
|
|
@ -937,7 +983,8 @@ impl Build {
|
|||
}
|
||||
|
||||
/// Execute a command and return its output.
|
||||
/// This method should be used for all command executions in bootstrap.
|
||||
/// Note: Ideally, you should use one of the BootstrapCommand::run* functions to
|
||||
/// execute commands. They internally call this method.
|
||||
#[track_caller]
|
||||
fn run(
|
||||
&self,
|
||||
|
|
@ -1008,20 +1055,28 @@ Executed at: {executed_at}"#,
|
|||
CommandOutput::did_not_start(stdout, stderr)
|
||||
}
|
||||
};
|
||||
|
||||
let fail = |message: &str| {
|
||||
if self.is_verbose() {
|
||||
println!("{message}");
|
||||
} else {
|
||||
println!("Command has failed. Rerun with -v to see more details.");
|
||||
}
|
||||
exit!(1);
|
||||
};
|
||||
|
||||
if !output.is_success() {
|
||||
match command.failure_behavior {
|
||||
BehaviorOnFailure::DelayFail => {
|
||||
if self.fail_fast {
|
||||
println!("{message}");
|
||||
exit!(1);
|
||||
fail(&message);
|
||||
}
|
||||
|
||||
let mut failures = self.delayed_failures.borrow_mut();
|
||||
failures.push(message);
|
||||
}
|
||||
BehaviorOnFailure::Exit => {
|
||||
println!("{message}");
|
||||
exit!(1);
|
||||
fail(&message);
|
||||
}
|
||||
BehaviorOnFailure::Ignore => {
|
||||
// If failures are allowed, either the error has been printed already
|
||||
|
|
|
|||
|
|
@ -3,13 +3,12 @@ use std::borrow::Borrow;
|
|||
use std::cell::RefCell;
|
||||
use std::cmp::Ordering;
|
||||
use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::marker::PhantomData;
|
||||
use std::mem;
|
||||
use std::ops::Deref;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::{LazyLock, Mutex};
|
||||
use std::{fmt, mem};
|
||||
|
||||
use crate::core::builder::Step;
|
||||
|
||||
|
|
|
|||
|
|
@ -220,4 +220,14 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
|
|||
severity: ChangeSeverity::Warning,
|
||||
summary: "For tarball sources, default value for `rust.channel` will be taken from `src/ci/channel` file.",
|
||||
},
|
||||
ChangeInfo {
|
||||
change_id: 125642,
|
||||
severity: ChangeSeverity::Info,
|
||||
summary: "New option `llvm.libzstd` to control whether llvm is built with zstd support.",
|
||||
},
|
||||
ChangeInfo {
|
||||
change_id: 128841,
|
||||
severity: ChangeSeverity::Warning,
|
||||
summary: "./x test --rustc-args was renamed to --compiletest-rustc-args as it only applies there. ./x miri --rustc-args was also removed.",
|
||||
},
|
||||
];
|
||||
|
|
|
|||
|
|
@ -8,11 +8,10 @@
|
|||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
use super::helpers;
|
||||
use crate::utils::helpers::{output, t};
|
||||
use crate::Build;
|
||||
|
||||
use super::helpers;
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
pub enum GitInfo {
|
||||
/// This is not a git repository.
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
use crate::Build;
|
||||
use build_helper::ci::CiEnv;
|
||||
use build_helper::drop_bomb::DropBomb;
|
||||
use std::ffi::OsStr;
|
||||
use std::fmt::{Debug, Formatter};
|
||||
use std::path::Path;
|
||||
use std::process::{Command, CommandArgs, CommandEnvs, ExitStatus, Output, Stdio};
|
||||
|
||||
use build_helper::ci::CiEnv;
|
||||
use build_helper::drop_bomb::DropBomb;
|
||||
|
||||
use crate::Build;
|
||||
|
||||
/// What should be done when the command fails.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum BehaviorOnFailure {
|
||||
|
|
@ -173,8 +175,8 @@ impl BootstrapCommand {
|
|||
}
|
||||
|
||||
/// If in a CI environment, forces the command to run with colors.
|
||||
pub fn force_coloring_in_ci(&mut self, ci_env: CiEnv) {
|
||||
if ci_env != CiEnv::None {
|
||||
pub fn force_coloring_in_ci(&mut self) {
|
||||
if CiEnv::is_ci() {
|
||||
// Due to use of stamp/docker, the output stream of bootstrap is not
|
||||
// a TTY in CI, so coloring is by-default turned off.
|
||||
// The explicit `TERM=xterm` environment is needed for
|
||||
|
|
|
|||
|
|
@ -3,23 +3,20 @@
|
|||
//! Simple things like testing the various filesystem operations here and there,
|
||||
//! not a lot of interesting happenings here unfortunately.
|
||||
|
||||
use build_helper::git::{get_git_merge_base, output_result, GitConfig};
|
||||
use build_helper::util::fail;
|
||||
use std::env;
|
||||
use std::ffi::OsStr;
|
||||
use std::fs;
|
||||
use std::io;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::{Command, Stdio};
|
||||
use std::str;
|
||||
use std::sync::OnceLock;
|
||||
use std::time::{Instant, SystemTime, UNIX_EPOCH};
|
||||
use std::{env, fs, io, str};
|
||||
|
||||
use build_helper::git::{get_git_merge_base, output_result, GitConfig};
|
||||
use build_helper::util::fail;
|
||||
|
||||
use crate::core::builder::Builder;
|
||||
use crate::core::config::{Config, TargetSelection};
|
||||
use crate::LldMode;
|
||||
|
||||
pub use crate::utils::shared_helpers::{dylib_path, dylib_path_var};
|
||||
use crate::LldMode;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
|
@ -48,9 +45,10 @@ macro_rules! t {
|
|||
}
|
||||
};
|
||||
}
|
||||
use crate::utils::exec::{command, BootstrapCommand};
|
||||
pub use t;
|
||||
|
||||
use crate::utils::exec::{command, BootstrapCommand};
|
||||
|
||||
pub fn exe(name: &str, target: TargetSelection) -> String {
|
||||
crate::utils::shared_helpers::exe(name, &target.triple)
|
||||
}
|
||||
|
|
@ -538,8 +536,7 @@ pub fn get_closest_merge_base_commit(
|
|||
|
||||
let merge_base = get_git_merge_base(config, source_dir).unwrap_or_else(|_| "HEAD".into());
|
||||
|
||||
git.arg(Path::new("rev-list"));
|
||||
git.args([&format!("--author={author}"), "-n1", "--first-parent", &merge_base]);
|
||||
git.args(["rev-list", &format!("--author={author}"), "-n1", "--first-parent", &merge_base]);
|
||||
|
||||
if !target_paths.is_empty() {
|
||||
git.arg("--").args(target_paths);
|
||||
|
|
|
|||
|
|
@ -1,14 +1,11 @@
|
|||
use crate::{
|
||||
utils::helpers::{
|
||||
check_cfg_arg, extract_beta_rev, hex_encode, make, program_out_of_date, symlink_dir,
|
||||
},
|
||||
Config,
|
||||
};
|
||||
use std::{
|
||||
fs::{self, remove_file, File},
|
||||
io::Write,
|
||||
path::PathBuf,
|
||||
use std::fs::{self, remove_file, File};
|
||||
use std::io::Write;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::utils::helpers::{
|
||||
check_cfg_arg, extract_beta_rev, hex_encode, make, program_out_of_date, symlink_dir,
|
||||
};
|
||||
use crate::{Config, Flags};
|
||||
|
||||
#[test]
|
||||
fn test_make() {
|
||||
|
|
@ -61,7 +58,8 @@ fn test_check_cfg_arg() {
|
|||
|
||||
#[test]
|
||||
fn test_program_out_of_date() {
|
||||
let config = Config::parse(&["check".to_owned(), "--config=/does/not/exist".to_owned()]);
|
||||
let config =
|
||||
Config::parse(Flags::parse(&["check".to_owned(), "--config=/does/not/exist".to_owned()]));
|
||||
let tempfile = config.tempdir().join(".tmp-stamp-file");
|
||||
File::create(&tempfile).unwrap().write_all(b"dummy value").unwrap();
|
||||
assert!(tempfile.exists());
|
||||
|
|
@ -76,7 +74,8 @@ fn test_program_out_of_date() {
|
|||
|
||||
#[test]
|
||||
fn test_symlink_dir() {
|
||||
let config = Config::parse(&["check".to_owned(), "--config=/does/not/exist".to_owned()]);
|
||||
let config =
|
||||
Config::parse(Flags::parse(&["check".to_owned(), "--config=/does/not/exist".to_owned()]));
|
||||
let tempdir = config.tempdir().join(".tmp-dir");
|
||||
let link_path = config.tempdir().join(".tmp-link");
|
||||
|
||||
|
|
|
|||
|
|
@ -40,27 +40,24 @@ pub unsafe fn setup(build: &mut crate::Build) {
|
|||
/// Note that this is a Windows specific module as none of this logic is required on Unix.
|
||||
#[cfg(windows)]
|
||||
mod for_windows {
|
||||
use crate::Build;
|
||||
use std::env;
|
||||
use std::ffi::c_void;
|
||||
use std::io;
|
||||
use std::mem;
|
||||
use std::{env, io, mem};
|
||||
|
||||
use windows::{
|
||||
core::PCWSTR,
|
||||
Win32::Foundation::{CloseHandle, DuplicateHandle, DUPLICATE_SAME_ACCESS, HANDLE},
|
||||
Win32::System::Diagnostics::Debug::{
|
||||
SetErrorMode, SEM_NOGPFAULTERRORBOX, THREAD_ERROR_MODE,
|
||||
},
|
||||
Win32::System::JobObjects::{
|
||||
AssignProcessToJobObject, CreateJobObjectW, JobObjectExtendedLimitInformation,
|
||||
SetInformationJobObject, JOBOBJECT_EXTENDED_LIMIT_INFORMATION,
|
||||
JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE, JOB_OBJECT_LIMIT_PRIORITY_CLASS,
|
||||
},
|
||||
Win32::System::Threading::{
|
||||
GetCurrentProcess, OpenProcess, BELOW_NORMAL_PRIORITY_CLASS, PROCESS_DUP_HANDLE,
|
||||
},
|
||||
use windows::core::PCWSTR;
|
||||
use windows::Win32::Foundation::{CloseHandle, DuplicateHandle, DUPLICATE_SAME_ACCESS, HANDLE};
|
||||
use windows::Win32::System::Diagnostics::Debug::{
|
||||
SetErrorMode, SEM_NOGPFAULTERRORBOX, THREAD_ERROR_MODE,
|
||||
};
|
||||
use windows::Win32::System::JobObjects::{
|
||||
AssignProcessToJobObject, CreateJobObjectW, JobObjectExtendedLimitInformation,
|
||||
SetInformationJobObject, JOBOBJECT_EXTENDED_LIMIT_INFORMATION,
|
||||
JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE, JOB_OBJECT_LIMIT_PRIORITY_CLASS,
|
||||
};
|
||||
use windows::Win32::System::Threading::{
|
||||
GetCurrentProcess, OpenProcess, BELOW_NORMAL_PRIORITY_CLASS, PROCESS_DUP_HANDLE,
|
||||
};
|
||||
|
||||
use crate::Build;
|
||||
|
||||
pub unsafe fn setup(build: &mut Build) {
|
||||
// Enable the Windows Error Reporting dialog which msys disables,
|
||||
|
|
|
|||
|
|
@ -4,18 +4,20 @@
|
|||
//! As this module requires additional dependencies not present during local builds, it's cfg'd
|
||||
//! away whenever the `build.metrics` config option is not set to `true`.
|
||||
|
||||
use crate::core::builder::{Builder, Step};
|
||||
use crate::utils::helpers::t;
|
||||
use crate::Build;
|
||||
use build_helper::metrics::{
|
||||
JsonInvocation, JsonInvocationSystemStats, JsonNode, JsonRoot, JsonStepSystemStats, Test,
|
||||
TestOutcome, TestSuite, TestSuiteMetadata,
|
||||
};
|
||||
use std::cell::RefCell;
|
||||
use std::fs::File;
|
||||
use std::io::BufWriter;
|
||||
use std::time::{Duration, Instant, SystemTime};
|
||||
use sysinfo::System;
|
||||
|
||||
use build_helper::metrics::{
|
||||
JsonInvocation, JsonInvocationSystemStats, JsonNode, JsonRoot, JsonStepSystemStats, Test,
|
||||
TestOutcome, TestSuite, TestSuiteMetadata,
|
||||
};
|
||||
use sysinfo::{CpuRefreshKind, RefreshKind, System};
|
||||
|
||||
use crate::core::builder::{Builder, Step};
|
||||
use crate::utils::helpers::t;
|
||||
use crate::Build;
|
||||
|
||||
// Update this number whenever a breaking change is made to the build metrics.
|
||||
//
|
||||
|
|
@ -53,7 +55,9 @@ impl BuildMetrics {
|
|||
finished_steps: Vec::new(),
|
||||
running_steps: Vec::new(),
|
||||
|
||||
system_info: System::new(),
|
||||
system_info: System::new_with_specifics(
|
||||
RefreshKind::new().with_cpu(CpuRefreshKind::everything()),
|
||||
),
|
||||
timer_start: None,
|
||||
invocation_timer_start: Instant::now(),
|
||||
invocation_start: SystemTime::now(),
|
||||
|
|
@ -75,7 +79,7 @@ impl BuildMetrics {
|
|||
self.collect_stats(&mut *state);
|
||||
}
|
||||
|
||||
state.system_info.refresh_cpu();
|
||||
state.system_info.refresh_cpu_usage();
|
||||
state.timer_start = Some(Instant::now());
|
||||
|
||||
state.running_steps.push(StepMetrics {
|
||||
|
|
@ -108,7 +112,7 @@ impl BuildMetrics {
|
|||
state.running_steps.last_mut().unwrap().children.push(step);
|
||||
|
||||
// Start collecting again for the parent step.
|
||||
state.system_info.refresh_cpu();
|
||||
state.system_info.refresh_cpu_usage();
|
||||
state.timer_start = Some(Instant::now());
|
||||
}
|
||||
}
|
||||
|
|
@ -146,7 +150,7 @@ impl BuildMetrics {
|
|||
let elapsed = state.timer_start.unwrap().elapsed();
|
||||
step.duration_excluding_children_sec += elapsed;
|
||||
|
||||
state.system_info.refresh_cpu();
|
||||
state.system_info.refresh_cpu_usage();
|
||||
let cpu = state.system_info.cpus().iter().map(|p| p.cpu_usage()).sum::<f32>();
|
||||
step.cpu_usage_time_sec += cpu as f64 / 100.0 * elapsed.as_secs_f64();
|
||||
}
|
||||
|
|
@ -157,8 +161,9 @@ impl BuildMetrics {
|
|||
|
||||
let dest = build.out.join("metrics.json");
|
||||
|
||||
let mut system = System::new();
|
||||
system.refresh_cpu();
|
||||
let mut system =
|
||||
System::new_with_specifics(RefreshKind::new().with_cpu(CpuRefreshKind::everything()));
|
||||
system.refresh_cpu_usage();
|
||||
system.refresh_memory();
|
||||
|
||||
let system_stats = JsonInvocationSystemStats {
|
||||
|
|
|
|||
|
|
@ -6,13 +6,15 @@
|
|||
//! and rustc) libtest doesn't include the rendered human-readable output as a JSON field. We had
|
||||
//! to reimplement all the rendering logic in this module because of that.
|
||||
|
||||
use crate::core::builder::Builder;
|
||||
use crate::utils::exec::BootstrapCommand;
|
||||
use std::io::{BufRead, BufReader, Read, Write};
|
||||
use std::process::{ChildStdout, Stdio};
|
||||
use std::time::Duration;
|
||||
|
||||
use termcolor::{Color, ColorSpec, WriteColor};
|
||||
|
||||
use crate::core::builder::Builder;
|
||||
use crate::utils::exec::BootstrapCommand;
|
||||
|
||||
const TERSE_TESTS_PER_LINE: usize = 88;
|
||||
|
||||
pub(crate) fn add_flags_and_try_run_tests(
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@
|
|||
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use crate::core::builder::Builder;
|
||||
use crate::core::{build_steps::dist::distdir, builder::Kind};
|
||||
use crate::core::build_steps::dist::distdir;
|
||||
use crate::core::builder::{Builder, Kind};
|
||||
use crate::utils::exec::BootstrapCommand;
|
||||
use crate::utils::helpers::{move_file, t};
|
||||
use crate::utils::{channel, helpers};
|
||||
|
|
@ -317,6 +317,12 @@ impl<'a> Tarball<'a> {
|
|||
channel::write_commit_hash_file(&self.overlay_dir, &info.sha);
|
||||
channel::write_commit_info_file(&self.overlay_dir, info);
|
||||
}
|
||||
|
||||
// Add config file if present.
|
||||
if let Some(config) = &self.builder.config.config {
|
||||
self.add_renamed_file(config, &self.overlay_dir, "builder-config");
|
||||
}
|
||||
|
||||
for file in self.overlay.legal_and_readme() {
|
||||
self.builder.install(&self.builder.src.join(file), &self.overlay_dir, 0o644);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,8 @@ RUN apt-get update && apt-get build-dep -y clang llvm && apt-get install -y --no
|
|||
# Needed for apt-key to work:
|
||||
dirmngr \
|
||||
gpg-agent \
|
||||
g++-9-arm-linux-gnueabi
|
||||
g++-9-arm-linux-gnueabi \
|
||||
g++-11-riscv64-linux-gnu
|
||||
|
||||
RUN apt-key adv --batch --yes --keyserver keyserver.ubuntu.com --recv-keys 74DA7924C5513486
|
||||
RUN add-apt-repository -y 'deb https://apt.dilos.org/dilos dilos2 main'
|
||||
|
|
@ -73,6 +74,10 @@ RUN env \
|
|||
CC=arm-linux-gnueabi-gcc-9 CFLAGS="-march=armv7-a" \
|
||||
CXX=arm-linux-gnueabi-g++-9 CXXFLAGS="-march=armv7-a" \
|
||||
bash musl.sh armv7 && \
|
||||
env \
|
||||
CC=riscv64-linux-gnu-gcc-11 \
|
||||
CXX=riscv64-linux-gnu-g++-11 \
|
||||
bash musl.sh riscv64gc && \
|
||||
rm -rf /build/*
|
||||
|
||||
WORKDIR /tmp
|
||||
|
|
@ -125,6 +130,7 @@ ENV TARGETS=$TARGETS,x86_64-unknown-none
|
|||
ENV TARGETS=$TARGETS,aarch64-unknown-uefi
|
||||
ENV TARGETS=$TARGETS,i686-unknown-uefi
|
||||
ENV TARGETS=$TARGETS,x86_64-unknown-uefi
|
||||
ENV TARGETS=$TARGETS,riscv64gc-unknown-linux-musl
|
||||
|
||||
# As per https://bugs.launchpad.net/ubuntu/+source/gcc-defaults/+bug/1300211
|
||||
# we need asm in the search path for gcc-9 (for gnux32) but not in the search path of the
|
||||
|
|
@ -132,7 +138,11 @@ ENV TARGETS=$TARGETS,x86_64-unknown-uefi
|
|||
# Luckily one of the folders is /usr/local/include so symlink /usr/include/x86_64-linux-gnu/asm there
|
||||
RUN ln -s /usr/include/x86_64-linux-gnu/asm /usr/local/include/asm
|
||||
|
||||
# musl-gcc can't find libgcc_s.so.1 since it doesn't use the standard search paths.
|
||||
RUN ln -s /usr/riscv64-linux-gnu/lib/libgcc_s.so.1 /usr/lib/gcc-cross/riscv64-linux-gnu/11/
|
||||
|
||||
ENV RUST_CONFIGURE_ARGS --enable-extended --enable-lld --enable-llvm-bitcode-linker --disable-docs \
|
||||
--musl-root-armv7=/musl-armv7
|
||||
--musl-root-armv7=/musl-armv7 \
|
||||
--musl-root-riscv64gc=/musl-riscv64gc
|
||||
|
||||
ENV SCRIPT python3 ../x.py dist --host='' --target $TARGETS
|
||||
|
|
|
|||
|
|
@ -62,6 +62,10 @@ COPY host-x86_64/dist-x86_64-linux/build-clang.sh /tmp/
|
|||
RUN ./build-clang.sh
|
||||
ENV CC=clang CXX=clang++
|
||||
|
||||
# rustc's LLVM needs zstd.
|
||||
COPY scripts/zstd.sh /tmp/
|
||||
RUN ./zstd.sh
|
||||
|
||||
COPY scripts/sccache.sh /scripts/
|
||||
RUN sh /scripts/sccache.sh
|
||||
|
||||
|
|
@ -79,6 +83,7 @@ ENV RUST_CONFIGURE_ARGS \
|
|||
--set target.x86_64-unknown-linux-gnu.ranlib=/rustroot/bin/llvm-ranlib \
|
||||
--set llvm.thin-lto=true \
|
||||
--set llvm.ninja=false \
|
||||
--set llvm.libzstd=true \
|
||||
--set rust.jemalloc \
|
||||
--set rust.use-lld=true \
|
||||
--set rust.lto=thin \
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#![no_std]
|
||||
|
||||
use core::{panic, ptr};
|
||||
|
||||
use r_efi::efi::{Char16, Handle, Status, SystemTable, RESET_SHUTDOWN};
|
||||
|
||||
#[panic_handler]
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||
pkg-config \
|
||||
xz-utils \
|
||||
mingw-w64 \
|
||||
zlib1g-dev \
|
||||
libzstd-dev \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY scripts/sccache.sh /scripts/
|
||||
|
|
|
|||
|
|
@ -571,6 +571,19 @@ class TestEnvironment:
|
|||
)
|
||||
|
||||
# Start repository server
|
||||
# Note that we must first enable the repository server daemon.
|
||||
check_call_with_logging(
|
||||
[
|
||||
ffx_path,
|
||||
"config",
|
||||
"set",
|
||||
"repository.server.enabled",
|
||||
"true",
|
||||
],
|
||||
env=ffx_env,
|
||||
stdout_handler=self.subprocess_logger.debug,
|
||||
stderr_handler=self.subprocess_logger.debug,
|
||||
)
|
||||
check_call_with_logging(
|
||||
[
|
||||
ffx_path,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
set -euo pipefail
|
||||
|
||||
LINUX_VERSION=c13320499ba0efd93174ef6462ae8a7a2933f6e7
|
||||
LINUX_VERSION=v6.11-rc1
|
||||
|
||||
# Build rustc, rustdoc and cargo
|
||||
../x.py build --stage 1 library rustdoc
|
||||
|
|
@ -65,4 +65,8 @@ make -C linux LLVM=1 -j$(($(nproc) + 1)) \
|
|||
make -C linux LLVM=1 -j$(($(nproc) + 1)) \
|
||||
samples/rust/rust_minimal.o \
|
||||
samples/rust/rust_print.o \
|
||||
drivers/net/phy/ax88796b_rust.o
|
||||
drivers/net/phy/ax88796b_rust.o \
|
||||
rust/doctests_kernel_generated.o
|
||||
|
||||
make -C linux LLVM=1 -j$(($(nproc) + 1)) \
|
||||
rustdoc
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@ if [[ -z "${PR_CI_JOB}" ]]; then
|
|||
# compiler, and is sensitive to the addition of new flags.
|
||||
../x.py --stage 1 test tests/ui-fulldeps
|
||||
|
||||
# The tests are run a second time with the size optimizations enabled.
|
||||
../x.py --stage 1 test library/std library/alloc library/core \
|
||||
--rustc-args "--cfg feature=\"optimize_for_size\""
|
||||
# Rebuild the stdlib with the size optimizations enabled and run tests again.
|
||||
RUSTFLAGS_NOT_BOOTSTRAP="--cfg feature=\"optimize_for_size\"" ../x.py --stage 1 test \
|
||||
library/std library/alloc library/core
|
||||
fi
|
||||
|
||||
# NOTE: intentionally uses all of `x.py`, `x`, and `x.ps1` to make sure they all work on Linux.
|
||||
|
|
|
|||
29
src/ci/docker/scripts/zstd.sh
Executable file
29
src/ci/docker/scripts/zstd.sh
Executable file
|
|
@ -0,0 +1,29 @@
|
|||
#!/bin/bash
|
||||
set -ex
|
||||
|
||||
hide_output() {
|
||||
set +x
|
||||
on_err="
|
||||
echo ERROR: An error was encountered with the build.
|
||||
cat /tmp/zstd_build.log
|
||||
exit 1
|
||||
"
|
||||
trap "$on_err" ERR
|
||||
bash -c "while true; do sleep 30; echo \$(date) - building ...; done" &
|
||||
PING_LOOP_PID=$!
|
||||
"$@" &> /tmp/zstd_build.log
|
||||
trap - ERR
|
||||
kill $PING_LOOP_PID
|
||||
rm /tmp/zstd_build.log
|
||||
set -x
|
||||
}
|
||||
|
||||
ZSTD=1.5.6
|
||||
curl -L https://github.com/facebook/zstd/releases/download/v$ZSTD/zstd-$ZSTD.tar.gz | tar xzf -
|
||||
|
||||
cd zstd-$ZSTD
|
||||
CFLAGS=-fPIC hide_output make -j$(nproc) VERBOSE=1
|
||||
hide_output make install
|
||||
|
||||
cd ..
|
||||
rm -rf zstd-$ZSTD
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit e2f0bdc4031866734661dcdb548184bde1450baf
|
||||
Subproject commit 2e191814f163ee1e77e2d6094eee4dd78a289c5b
|
||||
|
|
@ -65,6 +65,8 @@
|
|||
- [riscv32im-risc0-zkvm-elf](platform-support/riscv32im-risc0-zkvm-elf.md)
|
||||
- [riscv32imac-unknown-xous-elf](platform-support/riscv32imac-unknown-xous-elf.md)
|
||||
- [riscv32*-unknown-none-elf](platform-support/riscv32-unknown-none-elf.md)
|
||||
- [riscv64gc-unknown-linux-gnu](platform-support/riscv64gc-unknown-linux-gnu.md)
|
||||
- [riscv64gc-unknown-linux-musl](platform-support/riscv64gc-unknown-linux-musl.md)
|
||||
- [sparc-unknown-none-elf](./platform-support/sparc-unknown-none-elf.md)
|
||||
- [*-pc-windows-gnullvm](platform-support/pc-windows-gnullvm.md)
|
||||
- [\*-nto-qnx-\*](platform-support/nto-qnx.md)
|
||||
|
|
@ -74,6 +76,7 @@
|
|||
- [*-unknown-openbsd](platform-support/openbsd.md)
|
||||
- [*-unknown-redox](platform-support/redox.md)
|
||||
- [\*-unknown-uefi](platform-support/unknown-uefi.md)
|
||||
- [\*-wrs-vxworks](platform-support/vxworks.md)
|
||||
- [wasm32-wasip1](platform-support/wasm32-wasip1.md)
|
||||
- [wasm32-wasip1-threads](platform-support/wasm32-wasip1-threads.md)
|
||||
- [wasm32-wasip2](platform-support/wasm32-wasip2.md)
|
||||
|
|
|
|||
|
|
@ -96,9 +96,7 @@ This modifier translates to `--whole-archive` for `ld`-like linkers,
|
|||
to `/WHOLEARCHIVE` for `link.exe`, and to `-force_load` for `ld64`.
|
||||
The modifier does nothing for linkers that don't support it.
|
||||
|
||||
The default for this modifier is `-whole-archive`. \
|
||||
NOTE: The default may currently be different in some cases for backward compatibility,
|
||||
but it is not guaranteed. If you need whole archive semantics use `+whole-archive` explicitly.
|
||||
The default for this modifier is `-whole-archive`.
|
||||
|
||||
### Linking modifiers: `bundle`
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ 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+)
|
||||
[`aarch64-apple-darwin`](platform-support/apple-darwin.md) | ARM64 macOS (11.0+, Big Sur+)
|
||||
`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]
|
||||
|
|
@ -86,7 +87,6 @@ so Rustup may install the documentation for a similar tier 1 target instead.
|
|||
|
||||
target | notes
|
||||
-------|-------
|
||||
[`aarch64-apple-darwin`](platform-support/apple-darwin.md) | ARM64 macOS (11.0+, Big Sur+)
|
||||
`aarch64-pc-windows-msvc` | ARM64 Windows MSVC
|
||||
`aarch64-unknown-linux-musl` | ARM64 Linux with musl 1.2.3
|
||||
`arm-unknown-linux-gnueabi` | Armv6 Linux (kernel 3.2, glibc 2.17)
|
||||
|
|
@ -97,7 +97,8 @@ target | notes
|
|||
`powerpc-unknown-linux-gnu` | PowerPC Linux (kernel 3.2, glibc 2.17)
|
||||
`powerpc64-unknown-linux-gnu` | PPC64 Linux (kernel 3.2, glibc 2.17)
|
||||
`powerpc64le-unknown-linux-gnu` | PPC64LE Linux (kernel 3.10, glibc 2.17)
|
||||
`riscv64gc-unknown-linux-gnu` | RISC-V Linux (kernel 4.20, glibc 2.29)
|
||||
[`riscv64gc-unknown-linux-gnu`](platform-support/riscv64gc-unknown-linux-gnu.md) | RISC-V Linux (kernel 4.20, glibc 2.29)
|
||||
[`riscv64gc-unknown-linux-musl`](platform-support/riscv64gc-unknown-linux-musl.md) | RISC-V Linux (kernel 4.20, musl 1.2.3)
|
||||
`s390x-unknown-linux-gnu` | S390x Linux (kernel 3.2, glibc 2.17)
|
||||
`x86_64-unknown-freebsd` | 64-bit FreeBSD
|
||||
`x86_64-unknown-illumos` | illumos
|
||||
|
|
@ -263,7 +264,7 @@ target | std | host | notes
|
|||
[`aarch64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | ARM64 OpenBSD
|
||||
[`aarch64-unknown-redox`](platform-support/redox.md) | ✓ | | ARM64 Redox OS
|
||||
`aarch64-uwp-windows-msvc` | ✓ | |
|
||||
`aarch64-wrs-vxworks` | ? | |
|
||||
[`aarch64-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | ARM64 VxWorks OS
|
||||
`aarch64_be-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (big-endian, ILP32 ABI)
|
||||
`aarch64_be-unknown-linux-gnu` | ✓ | ✓ | ARM64 Linux (big-endian)
|
||||
[`aarch64_be-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | ARM64 NetBSD (big-endian)
|
||||
|
|
@ -281,7 +282,7 @@ target | std | host | notes
|
|||
[`armv7-unknown-linux-uclibceabihf`](platform-support/armv7-unknown-linux-uclibceabihf.md) | ✓ | ? | Armv7-A Linux with uClibc, hardfloat
|
||||
`armv7-unknown-freebsd` | ✓ | ✓ | Armv7-A FreeBSD
|
||||
[`armv7-unknown-netbsd-eabihf`](platform-support/netbsd.md) | ✓ | ✓ | Armv7-A NetBSD w/hard-float
|
||||
`armv7-wrs-vxworks-eabihf` | ? | | Armv7-A for VxWorks
|
||||
[`armv7-wrs-vxworks-eabihf`](platform-support/vxworks.md) | ✓ | | Armv7-A for VxWorks
|
||||
[`armv7a-kmc-solid_asp3-eabi`](platform-support/kmc-solid.md) | ✓ | | ARM SOLID with TOPPERS/ASP3
|
||||
[`armv7a-kmc-solid_asp3-eabihf`](platform-support/kmc-solid.md) | ✓ | | ARM SOLID with TOPPERS/ASP3, hardfloat
|
||||
[`armv7a-none-eabihf`](platform-support/arm-none-eabi.md) | * | | Bare Armv7-A, hardfloat
|
||||
|
|
@ -307,7 +308,7 @@ target | std | host | notes
|
|||
`i686-uwp-windows-gnu` | ✓ | | [^x86_32-floats-return-ABI]
|
||||
`i686-uwp-windows-msvc` | ✓ | | [^x86_32-floats-return-ABI]
|
||||
[`i686-win7-windows-msvc`](platform-support/win7-windows-msvc.md) | ✓ | | 32-bit Windows 7 support [^x86_32-floats-return-ABI]
|
||||
`i686-wrs-vxworks` | ? | | [^x86_32-floats-return-ABI]
|
||||
[`i686-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | [^x86_32-floats-return-ABI]
|
||||
[`m68k-unknown-linux-gnu`](platform-support/m68k-unknown-linux-gnu.md) | ? | | Motorola 680x0 Linux
|
||||
`mips-unknown-linux-gnu` | ✓ | ✓ | MIPS Linux (kernel 4.4, glibc 2.23)
|
||||
`mips-unknown-linux-musl` | ✓ | | MIPS Linux with musl 1.2.3
|
||||
|
|
@ -333,13 +334,13 @@ target | std | host | notes
|
|||
`powerpc-unknown-linux-musl` | ? | | PowerPC Linux with musl 1.2.3
|
||||
[`powerpc-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | NetBSD 32-bit powerpc systems
|
||||
[`powerpc-unknown-openbsd`](platform-support/powerpc-unknown-openbsd.md) | * | |
|
||||
`powerpc-wrs-vxworks-spe` | ? | |
|
||||
`powerpc-wrs-vxworks` | ? | |
|
||||
[`powerpc-wrs-vxworks-spe`](platform-support/vxworks.md) | ✓ | |
|
||||
[`powerpc-wrs-vxworks`](platform-support/vxworks.md) | ✓ | |
|
||||
`powerpc64-unknown-freebsd` | ✓ | ✓ | PPC64 FreeBSD (ELFv1 and ELFv2)
|
||||
`powerpc64le-unknown-freebsd` | | | PPC64LE FreeBSD
|
||||
`powerpc-unknown-freebsd` | | | PowerPC FreeBSD
|
||||
`powerpc64-unknown-linux-musl` | ? | | 64-bit PowerPC Linux with musl 1.2.3
|
||||
`powerpc64-wrs-vxworks` | ? | |
|
||||
[`powerpc64-wrs-vxworks`](platform-support/vxworks.md) | ✓ | |
|
||||
`powerpc64le-unknown-linux-musl` | ? | | 64-bit PowerPC Linux with musl 1.2.3, Little Endian
|
||||
[`powerpc64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/powerpc64
|
||||
[`powerpc64-ibm-aix`](platform-support/aix.md) | ? | | 64-bit AIX (7.2 and newer)
|
||||
|
|
@ -354,7 +355,6 @@ target | std | host | notes
|
|||
[`riscv64gc-unknown-hermit`](platform-support/hermit.md) | ✓ | | RISC-V Hermit
|
||||
`riscv64gc-unknown-freebsd` | | | RISC-V FreeBSD
|
||||
`riscv64gc-unknown-fuchsia` | | | RISC-V Fuchsia
|
||||
`riscv64gc-unknown-linux-musl` | | | RISC-V Linux (kernel 4.20, musl 1.2.3)
|
||||
[`riscv64gc-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | RISC-V NetBSD
|
||||
[`riscv64gc-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/riscv64
|
||||
[`riscv64-linux-android`](platform-support/android.md) | | | RISC-V 64-bit Android
|
||||
|
|
@ -383,7 +383,7 @@ target | std | host | notes
|
|||
`x86_64-uwp-windows-gnu` | ✓ | |
|
||||
`x86_64-uwp-windows-msvc` | ✓ | |
|
||||
[`x86_64-win7-windows-msvc`](platform-support/win7-windows-msvc.md) | ✓ | | 64-bit Windows 7 support
|
||||
`x86_64-wrs-vxworks` | ? | |
|
||||
[`x86_64-wrs-vxworks`](platform-support/vxworks.md) | ✓ | |
|
||||
[`x86_64h-apple-darwin`](platform-support/x86_64h-apple-darwin.md) | ✓ | ✓ | macOS with late-gen Intel (at least Haswell)
|
||||
[`x86_64-unknown-linux-none`](platform-support/x86_64-unknown-linux-none.md) | * | | 64-bit Linux with no libc
|
||||
[`xtensa-esp32-none-elf`](platform-support/xtensa.md) | * | | Xtensa ESP32
|
||||
|
|
|
|||
|
|
@ -5,9 +5,6 @@ Apple macOS targets.
|
|||
**Tier: 1**
|
||||
|
||||
- `x86_64-apple-darwin`: macOS on 64-bit x86.
|
||||
|
||||
**Tier: 2 (with Host Tools)**
|
||||
|
||||
- `aarch64-apple-darwin`: macOS on ARM64 (M1-family or later Apple Silicon CPUs).
|
||||
|
||||
## Target maintainers
|
||||
|
|
|
|||
|
|
@ -0,0 +1,129 @@
|
|||
# `riscv64gc-unknown-linux-gnu`
|
||||
|
||||
**Tier: 2 (with Host Tools)**
|
||||
|
||||
RISC-V targets using the *RV64I* base instruction set with the *G* collection of extensions, as well as the *C* extension.
|
||||
|
||||
|
||||
## Target maintainers
|
||||
|
||||
- Kito Cheng, <kito.cheng@gmail.com>, [@kito-cheng](https://github.com/kito-cheng)
|
||||
- Michael Maitland, <michaeltmaitland@gmail.com>, [@michaelmaitland](https://github.com/michaelmaitland)
|
||||
- Robin Randhawa, <robin.randhawa@sifive.com>, [@robin-randhawa-sifive](https://github.com/robin-randhawa-sifive)
|
||||
- Craig Topper, <craig.topper@sifive.com>, [@topperc](https://github.com/topperc)
|
||||
|
||||
## Requirements
|
||||
|
||||
This target requires:
|
||||
|
||||
* Linux Kernel version 4.20 or later
|
||||
* glibc 2.17 or later
|
||||
|
||||
|
||||
## Building the target
|
||||
|
||||
These targets are distributed through `rustup`, and otherwise require no
|
||||
special configuration.
|
||||
|
||||
If you need to build your own Rust for some reason though, the targets can be
|
||||
enabled in `config.toml`. For example:
|
||||
|
||||
```toml
|
||||
[build]
|
||||
target = ["riscv64gc-unknown-linux-gnu"]
|
||||
```
|
||||
|
||||
|
||||
## Building Rust programs
|
||||
|
||||
|
||||
On a RISC-V host, the `riscv64gc-unknown-linux-gnu` target should be automatically
|
||||
installed and used by default.
|
||||
|
||||
On a non-RISC-V host, add the target:
|
||||
|
||||
```bash
|
||||
rustup target add riscv64gc-unknown-linux-gnu
|
||||
```
|
||||
|
||||
Then cross compile crates with:
|
||||
|
||||
```bash
|
||||
cargo build --target riscv64gc-unknown-linux-gnu
|
||||
```
|
||||
|
||||
|
||||
## Testing
|
||||
|
||||
There are no special requirements for testing and running the targets.
|
||||
For testing cross builds on the host, please refer to the "Cross-compilation
|
||||
toolchains and C code"
|
||||
section below.
|
||||
|
||||
|
||||
## Cross-compilation toolchains and C code
|
||||
|
||||
A RISC-V toolchain can be obtained for Windows/Mac/Linux from the
|
||||
[`riscv-gnu-toolchain`](https://github.com/riscv-collab/riscv-gnu-toolchain)
|
||||
repostory. Binaries are available via
|
||||
[embecosm](https://www.embecosm.com/resources/tool-chain-downloads/#riscv-linux),
|
||||
and may also be available from your OS's package manager.
|
||||
|
||||
On Ubuntu, a RISC-V toolchain can be installed with:
|
||||
|
||||
```bash
|
||||
apt install gcc-riscv64-linux-gnu g++-riscv64-linux-gnu libc6-dev-riscv64-cross
|
||||
```
|
||||
|
||||
Depending on your system, you may need to configure the target to use the GNU
|
||||
GCC linker. To use it, add the following to your `.cargo/config.toml`:
|
||||
|
||||
```toml
|
||||
[target.riscv64gc-unknown-linux-gnu]
|
||||
linker = "riscv64-linux-gnu-gcc"
|
||||
```
|
||||
|
||||
If your `riscv64-linux-gnu-*` toolchain is not in your `PATH` you may need to
|
||||
configure additional settings:
|
||||
|
||||
```toml
|
||||
[target.riscv64gc-unknown-linux-gnu]
|
||||
# Adjust the paths to point at your toolchain
|
||||
cc = "/TOOLCHAIN_PATH/bin/riscv64-linux-gnu-gcc"
|
||||
cxx = "/TOOLCHAIN_PATH/bin/riscv64-linux-gnu-g++"
|
||||
ar = "/TOOLCHAIN_PATH/bin/riscv64-linux-gnu-ar"
|
||||
ranlib = "/TOOLCHAIN_PATH/bin/riscv64-linux-gnu-ranlib"
|
||||
linker = "/TOOLCHAIN_PATH/bin/riscv64-linux-gnu-gcc"
|
||||
```
|
||||
|
||||
To test cross compiled binaries on a non-RISCV-V host, you can use
|
||||
[`qemu`](https://www.qemu.org/docs/master/system/target-riscv.html).
|
||||
On Ubuntu, a RISC-V emulator can be obtained with:
|
||||
|
||||
```bash
|
||||
apt install qemu-system-riscv64
|
||||
```
|
||||
|
||||
Then, in `.cargo/config.toml` set the `runner`:
|
||||
|
||||
```toml
|
||||
[target.riscv64gc-unknown-linux-gnu]
|
||||
runner = "qemu-riscv64-static -L /usr/riscv64-linux-gnu -cpu rv64"
|
||||
```
|
||||
|
||||
On Mac and Linux, it's also possible to use
|
||||
[`lima`](https://github.com/lima-vm/lima) to emulate RISC-V in a similar way to
|
||||
how WSL2 works on Windows:
|
||||
|
||||
```bash
|
||||
limactl start template://riscv
|
||||
limactl shell riscv
|
||||
```
|
||||
|
||||
Using [Docker (with BuildKit)](https://docs.docker.com/build/buildkit/) the
|
||||
[`riscv64/ubuntu`](https://hub.docker.com/r/riscv64/ubuntu) image can be used
|
||||
to buiild or run `riscv64gc-unknown-linux-gnu` binaries.
|
||||
|
||||
```bash
|
||||
docker run --platform linux/riscv64 -ti --rm --mount "type=bind,src=$(pwd),dst=/checkout" riscv64/ubuntu bash
|
||||
```
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
# riscv64gc-unknown-linux-musl
|
||||
|
||||
**Tier: 2**
|
||||
|
||||
Target for RISC-V Linux programs using musl libc.
|
||||
|
||||
## Target maintainers
|
||||
|
||||
- [@Amanieu](https://github.com/Amanieu)
|
||||
- [@kraj](https://github.com/kraj)
|
||||
|
||||
## Requirements
|
||||
|
||||
Building the target itself requires a RISC-V compiler that is supported by `cc-rs`.
|
||||
|
||||
## Building the target
|
||||
|
||||
The target can be built by enabling it for a `rustc` build.
|
||||
|
||||
```toml
|
||||
[build]
|
||||
target = ["riscv64gc-unknown-linux-musl"]
|
||||
```
|
||||
|
||||
Make sure your C compiler is included in `$PATH`, then add it to the `config.toml`:
|
||||
|
||||
```toml
|
||||
[target.riscv64gc-unknown-linux-musl]
|
||||
cc = "riscv64-linux-gnu-gcc"
|
||||
cxx = "riscv64-linux-gnu-g++"
|
||||
ar = "riscv64-linux-gnu-ar"
|
||||
linker = "riscv64-linux-gnu-gcc"
|
||||
```
|
||||
|
||||
## Building Rust programs
|
||||
|
||||
This target are distributed through `rustup`, and otherwise require no
|
||||
special configuration.
|
||||
|
||||
## Cross-compilation
|
||||
|
||||
This target can be cross-compiled from any host.
|
||||
|
||||
## Testing
|
||||
|
||||
This target can be tested as normal with `x.py` on a RISC-V host or via QEMU
|
||||
emulation.
|
||||
59
src/doc/rustc/src/platform-support/vxworks.md
Normal file
59
src/doc/rustc/src/platform-support/vxworks.md
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
# `*-wrs-vxworks`
|
||||
|
||||
**Tier: 3**
|
||||
|
||||
Targets for the VxWorks operating
|
||||
system.
|
||||
|
||||
Target triplets available:
|
||||
|
||||
- `x86_64-wrs-vxworks`
|
||||
- `aarch64-wrs-vxworks`
|
||||
- `i686-wrs-vxworks`
|
||||
- `armv7-wrs-vxworks-eabihf`
|
||||
- `powerpc-wrs-vxworks`
|
||||
- `powerpc64-wrs-vxworks`
|
||||
- `powerpc-wrs-vxworks-spe`
|
||||
|
||||
## Target maintainers
|
||||
|
||||
- B I Mohammed Abbas ([@biabbas](https://github.com/biabbas))
|
||||
|
||||
## Requirements
|
||||
|
||||
### OS version
|
||||
|
||||
The minimum supported version is VxWorks 7.
|
||||
|
||||
## Building
|
||||
|
||||
Rust for each target can be cross-compiled with its specific target vsb configuration. Std support is added but not yet fully tested.
|
||||
|
||||
## Building the target
|
||||
|
||||
You can build Rust with support for the targets by adding it to the `target` list in `config.toml`. In addition the workbench and wr-cc have to configured and activated.
|
||||
|
||||
```toml
|
||||
[build]
|
||||
build-stage = 1
|
||||
target = [
|
||||
"<HOST_TARGET>",
|
||||
"x86_64-wrs-vxworks",
|
||||
"aarch64-wrs-vxworks",
|
||||
"i686-wrs-vxworks",
|
||||
"armv7-wrs-vxworks-eabihf",
|
||||
"powerpc-wrs-vxworks",
|
||||
"powerpc64-wrs-vxworks",
|
||||
"powerpc-wrs-vxworks-spe",
|
||||
]
|
||||
```
|
||||
|
||||
## Building Rust programs
|
||||
|
||||
Rust does not yet ship pre-compiled artifacts for VxWorks.
|
||||
|
||||
The easiest way to build and test programs for VxWorks is to use the shipped rustc and cargo in VxWorks workbench, following the official windriver guidelines.
|
||||
|
||||
## Cross-compilation toolchains and C code
|
||||
|
||||
The target supports C code. Pre-compiled C toolchains can be found in provided VxWorks workbench.
|
||||
11
src/doc/unstable-book/src/language-features/rustc-private.md
Normal file
11
src/doc/unstable-book/src/language-features/rustc-private.md
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
# `rustc_private`
|
||||
|
||||
The tracking issue for this feature is: [#27812]
|
||||
|
||||
[#27812]: https://github.com/rust-lang/rust/issues/27812
|
||||
|
||||
------------------------
|
||||
|
||||
This feature allows access to unstable internal compiler crates.
|
||||
|
||||
Additionally it changes the linking behavior of crates which have this feature enabled. It will prevent linking to a dylib if there's a static variant of it already statically linked into another dylib dependency. This is required to successfully link to `rustc_driver`.
|
||||
|
|
@ -266,7 +266,7 @@ complete -c x.py -n "__fish_seen_subcommand_from doc" -l enable-bolt-settings -d
|
|||
complete -c x.py -n "__fish_seen_subcommand_from doc" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
|
||||
complete -c x.py -n "__fish_seen_subcommand_from doc" -s h -l help -d 'Print help (see more with \'--help\')'
|
||||
complete -c x.py -n "__fish_seen_subcommand_from test" -l test-args -d 'extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)' -r
|
||||
complete -c x.py -n "__fish_seen_subcommand_from test" -l rustc-args -d 'extra options to pass the compiler when running tests' -r
|
||||
complete -c x.py -n "__fish_seen_subcommand_from test" -l compiletest-rustc-args -d 'extra options to pass the compiler when running compiletest tests' -r
|
||||
complete -c x.py -n "__fish_seen_subcommand_from test" -l extra-checks -d 'comma-separated list of other files types to check (accepts py, py:lint, py:fmt, shell)' -r
|
||||
complete -c x.py -n "__fish_seen_subcommand_from test" -l compare-mode -d 'mode describing what file the actual ui output will be compared to' -r
|
||||
complete -c x.py -n "__fish_seen_subcommand_from test" -l pass -d 'force {check,build,run}-pass tests to this mode' -r
|
||||
|
|
@ -313,7 +313,6 @@ complete -c x.py -n "__fish_seen_subcommand_from test" -l enable-bolt-settings -
|
|||
complete -c x.py -n "__fish_seen_subcommand_from test" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
|
||||
complete -c x.py -n "__fish_seen_subcommand_from test" -s h -l help -d 'Print help (see more with \'--help\')'
|
||||
complete -c x.py -n "__fish_seen_subcommand_from miri" -l test-args -d 'extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)' -r
|
||||
complete -c x.py -n "__fish_seen_subcommand_from miri" -l rustc-args -d 'extra options to pass the compiler when running tests' -r
|
||||
complete -c x.py -n "__fish_seen_subcommand_from miri" -l config -d 'TOML configuration file for build' -r -F
|
||||
complete -c x.py -n "__fish_seen_subcommand_from miri" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
|
||||
complete -c x.py -n "__fish_seen_subcommand_from miri" -l build -d 'build target of the stage0 compiler' -r -f
|
||||
|
|
|
|||
|
|
@ -338,7 +338,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
|
|||
}
|
||||
'x.py;test' {
|
||||
[CompletionResult]::new('--test-args', 'test-args', [CompletionResultType]::ParameterName, 'extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)')
|
||||
[CompletionResult]::new('--rustc-args', 'rustc-args', [CompletionResultType]::ParameterName, 'extra options to pass the compiler when running tests')
|
||||
[CompletionResult]::new('--compiletest-rustc-args', 'compiletest-rustc-args', [CompletionResultType]::ParameterName, 'extra options to pass the compiler when running compiletest tests')
|
||||
[CompletionResult]::new('--extra-checks', 'extra-checks', [CompletionResultType]::ParameterName, 'comma-separated list of other files types to check (accepts py, py:lint, py:fmt, shell)')
|
||||
[CompletionResult]::new('--compare-mode', 'compare-mode', [CompletionResultType]::ParameterName, 'mode describing what file the actual ui output will be compared to')
|
||||
[CompletionResult]::new('--pass', 'pass', [CompletionResultType]::ParameterName, 'force {check,build,run}-pass tests to this mode')
|
||||
|
|
@ -392,7 +392,6 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
|
|||
}
|
||||
'x.py;miri' {
|
||||
[CompletionResult]::new('--test-args', 'test-args', [CompletionResultType]::ParameterName, 'extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)')
|
||||
[CompletionResult]::new('--rustc-args', 'rustc-args', [CompletionResultType]::ParameterName, 'extra options to pass the compiler when running tests')
|
||||
[CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'TOML configuration file for build')
|
||||
[CompletionResult]::new('--build-dir', 'build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`')
|
||||
[CompletionResult]::new('--build', 'build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler')
|
||||
|
|
|
|||
|
|
@ -1300,7 +1300,7 @@ _x.py() {
|
|||
return 0
|
||||
;;
|
||||
x.py__miri)
|
||||
opts="-v -i -j -h --no-fail-fast --test-args --rustc-args --no-doc --doc --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
|
||||
opts="-v -i -j -h --no-fail-fast --test-args --no-doc --doc --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
|
||||
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
|
||||
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
|
||||
return 0
|
||||
|
|
@ -1310,10 +1310,6 @@ _x.py() {
|
|||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--rustc-args)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--config)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
|
|
@ -1862,7 +1858,7 @@ _x.py() {
|
|||
return 0
|
||||
;;
|
||||
x.py__test)
|
||||
opts="-v -i -j -h --no-fail-fast --test-args --rustc-args --no-doc --doc --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
|
||||
opts="-v -i -j -h --no-fail-fast --test-args --compiletest-rustc-args --no-doc --doc --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
|
||||
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
|
||||
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
|
||||
return 0
|
||||
|
|
@ -1872,7 +1868,7 @@ _x.py() {
|
|||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--rustc-args)
|
||||
--compiletest-rustc-args)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
|
|
|
|||
|
|
@ -337,7 +337,7 @@ _arguments "${_arguments_options[@]}" \
|
|||
(test)
|
||||
_arguments "${_arguments_options[@]}" \
|
||||
'*--test-args=[extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)]:ARGS: ' \
|
||||
'*--rustc-args=[extra options to pass the compiler when running tests]:ARGS: ' \
|
||||
'*--compiletest-rustc-args=[extra options to pass the compiler when running compiletest tests]:ARGS: ' \
|
||||
'--extra-checks=[comma-separated list of other files types to check (accepts py, py\:lint, py\:fmt, shell)]:EXTRA_CHECKS: ' \
|
||||
'--compare-mode=[mode describing what file the actual ui output will be compared to]:COMPARE MODE: ' \
|
||||
'--pass=[force {check,build,run}-pass tests to this mode]:check | build | run: ' \
|
||||
|
|
@ -393,7 +393,6 @@ _arguments "${_arguments_options[@]}" \
|
|||
(miri)
|
||||
_arguments "${_arguments_options[@]}" \
|
||||
'*--test-args=[extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)]:ARGS: ' \
|
||||
'*--rustc-args=[extra options to pass the compiler when running tests]:ARGS: ' \
|
||||
'--config=[TOML configuration file for build]:FILE:_files' \
|
||||
'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \
|
||||
'--build=[build target of the stage0 compiler]:BUILD:( )' \
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ class StdStringProvider(printer_base):
|
|||
self._valobj = valobj
|
||||
vec = valobj["vec"]
|
||||
self._length = int(vec["len"])
|
||||
self._data_ptr = unwrap_unique_or_non_null(vec["buf"]["ptr"])
|
||||
self._data_ptr = unwrap_unique_or_non_null(vec["buf"]["inner"]["ptr"])
|
||||
|
||||
def to_string(self):
|
||||
return self._data_ptr.lazy_string(encoding="utf-8", length=self._length)
|
||||
|
|
@ -74,7 +74,7 @@ class StdOsStringProvider(printer_base):
|
|||
vec = buf[ZERO_FIELD] if is_windows else buf
|
||||
|
||||
self._length = int(vec["len"])
|
||||
self._data_ptr = unwrap_unique_or_non_null(vec["buf"]["ptr"])
|
||||
self._data_ptr = unwrap_unique_or_non_null(vec["buf"]["inner"]["ptr"])
|
||||
|
||||
def to_string(self):
|
||||
return self._data_ptr.lazy_string(encoding="utf-8", length=self._length)
|
||||
|
|
@ -96,6 +96,7 @@ class StdStrProvider(printer_base):
|
|||
def display_hint():
|
||||
return "string"
|
||||
|
||||
|
||||
def _enumerate_array_elements(element_ptrs):
|
||||
for (i, element_ptr) in enumerate(element_ptrs):
|
||||
key = "[{}]".format(i)
|
||||
|
|
@ -112,6 +113,7 @@ def _enumerate_array_elements(element_ptrs):
|
|||
|
||||
yield key, element
|
||||
|
||||
|
||||
class StdSliceProvider(printer_base):
|
||||
def __init__(self, valobj):
|
||||
self._valobj = valobj
|
||||
|
|
@ -130,11 +132,14 @@ class StdSliceProvider(printer_base):
|
|||
def display_hint():
|
||||
return "array"
|
||||
|
||||
|
||||
class StdVecProvider(printer_base):
|
||||
def __init__(self, valobj):
|
||||
self._valobj = valobj
|
||||
self._length = int(valobj["len"])
|
||||
self._data_ptr = unwrap_unique_or_non_null(valobj["buf"]["ptr"])
|
||||
self._data_ptr = unwrap_unique_or_non_null(valobj["buf"]["inner"]["ptr"])
|
||||
ptr_ty = gdb.Type.pointer(valobj.type.template_argument(0))
|
||||
self._data_ptr = self._data_ptr.reinterpret_cast(ptr_ty)
|
||||
|
||||
def to_string(self):
|
||||
return "Vec(size={})".format(self._length)
|
||||
|
|
@ -155,11 +160,13 @@ class StdVecDequeProvider(printer_base):
|
|||
self._head = int(valobj["head"])
|
||||
self._size = int(valobj["len"])
|
||||
# BACKCOMPAT: rust 1.75
|
||||
cap = valobj["buf"]["cap"]
|
||||
cap = valobj["buf"]["inner"]["cap"]
|
||||
if cap.type.code != gdb.TYPE_CODE_INT:
|
||||
cap = cap[ZERO_FIELD]
|
||||
self._cap = int(cap)
|
||||
self._data_ptr = unwrap_unique_or_non_null(valobj["buf"]["ptr"])
|
||||
self._data_ptr = unwrap_unique_or_non_null(valobj["buf"]["inner"]["ptr"])
|
||||
ptr_ty = gdb.Type.pointer(valobj.type.template_argument(0))
|
||||
self._data_ptr = self._data_ptr.reinterpret_cast(ptr_ty)
|
||||
|
||||
def to_string(self):
|
||||
return "VecDeque(size={})".format(self._size)
|
||||
|
|
|
|||
|
|
@ -389,11 +389,11 @@ class StdVecSyntheticProvider:
|
|||
def update(self):
|
||||
# type: () -> None
|
||||
self.length = self.valobj.GetChildMemberWithName("len").GetValueAsUnsigned()
|
||||
self.buf = self.valobj.GetChildMemberWithName("buf")
|
||||
self.buf = self.valobj.GetChildMemberWithName("buf").GetChildMemberWithName("inner")
|
||||
|
||||
self.data_ptr = unwrap_unique_or_non_null(self.buf.GetChildMemberWithName("ptr"))
|
||||
|
||||
self.element_type = self.data_ptr.GetType().GetPointeeType()
|
||||
self.element_type = self.valobj.GetType().GetTemplateArgumentType(0)
|
||||
self.element_type_size = self.element_type.GetByteSize()
|
||||
|
||||
def has_children(self):
|
||||
|
|
@ -474,7 +474,7 @@ class StdVecDequeSyntheticProvider:
|
|||
# type: () -> None
|
||||
self.head = self.valobj.GetChildMemberWithName("head").GetValueAsUnsigned()
|
||||
self.size = self.valobj.GetChildMemberWithName("len").GetValueAsUnsigned()
|
||||
self.buf = self.valobj.GetChildMemberWithName("buf")
|
||||
self.buf = self.valobj.GetChildMemberWithName("buf").GetChildMemberWithName("inner")
|
||||
cap = self.buf.GetChildMemberWithName("cap")
|
||||
if cap.GetType().num_fields == 1:
|
||||
cap = cap.GetChildAtIndex(0)
|
||||
|
|
@ -482,7 +482,7 @@ class StdVecDequeSyntheticProvider:
|
|||
|
||||
self.data_ptr = unwrap_unique_or_non_null(self.buf.GetChildMemberWithName("ptr"))
|
||||
|
||||
self.element_type = self.data_ptr.GetType().GetPointeeType()
|
||||
self.element_type = self.valobj.GetType().GetTemplateArgumentType(0)
|
||||
self.element_type_size = self.element_type.GetByteSize()
|
||||
|
||||
def has_children(self):
|
||||
|
|
|
|||
|
|
@ -4,10 +4,10 @@
|
|||
<DisplayString>{{ len={len} }}</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[len]" ExcludeView="simple">len</Item>
|
||||
<Item Name="[capacity]" ExcludeView="simple">buf.cap.__0</Item>
|
||||
<Item Name="[capacity]" ExcludeView="simple">buf.inner.cap.__0</Item>
|
||||
<ArrayItems>
|
||||
<Size>len</Size>
|
||||
<ValuePointer>buf.ptr.pointer.pointer</ValuePointer>
|
||||
<ValuePointer>($T1*)buf.inner.ptr.pointer.pointer</ValuePointer>
|
||||
</ArrayItems>
|
||||
</Expand>
|
||||
</Type>
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
<DisplayString>{{ len={len} }}</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[len]" ExcludeView="simple">len</Item>
|
||||
<Item Name="[capacity]" ExcludeView="simple">buf.cap.__0</Item>
|
||||
<Item Name="[capacity]" ExcludeView="simple">buf.inner.cap.__0</Item>
|
||||
<CustomListItems>
|
||||
<Variable Name="i" InitialValue="0" />
|
||||
<Size>len</Size>
|
||||
|
|
@ -23,7 +23,7 @@
|
|||
<If Condition="i == len">
|
||||
<Break/>
|
||||
</If>
|
||||
<Item>buf.ptr.pointer.pointer[(i + head) % buf.cap.__0]</Item>
|
||||
<Item>(($T1*)buf.inner.ptr.pointer.pointer)[(i + head) % buf.inner.cap.__0]</Item>
|
||||
<Exec>i = i + 1</Exec>
|
||||
</Loop>
|
||||
</CustomListItems>
|
||||
|
|
@ -41,17 +41,17 @@
|
|||
</Expand>
|
||||
</Type>
|
||||
<Type Name="alloc::string::String">
|
||||
<DisplayString>{(char*)vec.buf.ptr.pointer.pointer,[vec.len]s8}</DisplayString>
|
||||
<StringView>(char*)vec.buf.ptr.pointer.pointer,[vec.len]s8</StringView>
|
||||
<DisplayString>{(char*)vec.buf.inner.ptr.pointer.pointer,[vec.len]s8}</DisplayString>
|
||||
<StringView>(char*)vec.buf.inner.ptr.pointer.pointer,[vec.len]s8</StringView>
|
||||
<Expand>
|
||||
<Item Name="[len]" ExcludeView="simple">vec.len</Item>
|
||||
<Item Name="[capacity]" ExcludeView="simple">vec.buf.cap.__0</Item>
|
||||
<Item Name="[capacity]" ExcludeView="simple">vec.buf.inner.cap.__0</Item>
|
||||
<Synthetic Name="[chars]">
|
||||
<DisplayString>{(char*)vec.buf.ptr.pointer.pointer,[vec.len]s8}</DisplayString>
|
||||
<DisplayString>{(char*)vec.buf.inner.ptr.pointer.pointer,[vec.len]s8}</DisplayString>
|
||||
<Expand>
|
||||
<ArrayItems>
|
||||
<Size>vec.len</Size>
|
||||
<ValuePointer>(char*)vec.buf.ptr.pointer.pointer</ValuePointer>
|
||||
<ValuePointer>(char*)vec.buf.inner.ptr.pointer.pointer</ValuePointer>
|
||||
</ArrayItems>
|
||||
</Expand>
|
||||
</Synthetic>
|
||||
|
|
|
|||
|
|
@ -104,14 +104,14 @@
|
|||
</Type>
|
||||
|
||||
<Type Name="std::ffi::os_str::OsString">
|
||||
<DisplayString>{(char*)inner.inner.bytes.buf.ptr.pointer.pointer,[inner.inner.bytes.len]}</DisplayString>
|
||||
<DisplayString>{(char*)inner.inner.bytes.buf.inner.ptr.pointer.pointer,[inner.inner.bytes.len]}</DisplayString>
|
||||
<Expand>
|
||||
<Synthetic Name="[chars]">
|
||||
<DisplayString>{(char*)inner.inner.bytes.buf.ptr.pointer.pointer,[inner.inner.bytes.len]}</DisplayString>
|
||||
<DisplayString>{(char*)inner.inner.bytes.buf.inner.ptr.pointer.pointer,[inner.inner.bytes.len]}</DisplayString>
|
||||
<Expand>
|
||||
<ArrayItems>
|
||||
<Size>inner.inner.bytes.len</Size>
|
||||
<ValuePointer>(char*)inner.inner.bytes.buf.ptr.pointer.pointer</ValuePointer>
|
||||
<ValuePointer>(char*)inner.inner.bytes.buf.inner.ptr.pointer.pointer</ValuePointer>
|
||||
</ArrayItems>
|
||||
</Expand>
|
||||
</Synthetic>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ path = "lib.rs"
|
|||
|
||||
[dependencies]
|
||||
arrayvec = { version = "0.7", default-features = false }
|
||||
rinja = { version = "0.2", default-features = false, features = ["config"] }
|
||||
rinja = { version = "0.3", default-features = false, features = ["config"] }
|
||||
base64 = "0.21.7"
|
||||
itertools = "0.12"
|
||||
indexmap = "2"
|
||||
|
|
@ -23,6 +23,7 @@ tempfile = "3"
|
|||
tracing = "0.1"
|
||||
tracing-tree = "0.3.0"
|
||||
threadpool = "1.8.1"
|
||||
unicode-segmentation = "1.9"
|
||||
|
||||
[dependencies.tracing-subscriber]
|
||||
version = "0.3.3"
|
||||
|
|
|
|||
|
|
@ -6,13 +6,11 @@ use rustc_middle::ty::{self, Region, Ty};
|
|||
use rustc_span::def_id::DefId;
|
||||
use rustc_span::symbol::{kw, Symbol};
|
||||
use rustc_trait_selection::traits::auto_trait::{self, RegionTarget};
|
||||
|
||||
use thin_vec::ThinVec;
|
||||
|
||||
use crate::clean::{self, simplify, Lifetime};
|
||||
use crate::clean::{
|
||||
clean_generic_param_def, clean_middle_ty, clean_predicate, clean_trait_ref_with_constraints,
|
||||
clean_ty_generics,
|
||||
self, clean_generic_param_def, clean_middle_ty, clean_predicate,
|
||||
clean_trait_ref_with_constraints, clean_ty_generics, simplify, Lifetime,
|
||||
};
|
||||
use crate::core::DocContext;
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ use rustc_middle::ty::{self, Upcast};
|
|||
use rustc_span::def_id::DefId;
|
||||
use rustc_span::DUMMY_SP;
|
||||
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
|
||||
|
||||
use thin_vec::ThinVec;
|
||||
|
||||
use crate::clean;
|
||||
|
|
|
|||
|
|
@ -4,15 +4,13 @@
|
|||
// switch to use those structures instead.
|
||||
|
||||
use std::fmt::{self, Write};
|
||||
use std::mem;
|
||||
use std::ops;
|
||||
use std::{mem, ops};
|
||||
|
||||
use rustc_ast::{LitKind, MetaItem, MetaItemKind, NestedMetaItem};
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_feature::Features;
|
||||
use rustc_session::parse::ParseSess;
|
||||
use rustc_span::symbol::{sym, Symbol};
|
||||
|
||||
use rustc_span::Span;
|
||||
|
||||
use crate::html::escape::Escape;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
use super::*;
|
||||
|
||||
use rustc_ast::{MetaItemLit, Path, Safety, StrStyle};
|
||||
use rustc_span::create_default_session_globals_then;
|
||||
use rustc_span::symbol::{kw, Ident};
|
||||
use rustc_span::DUMMY_SP;
|
||||
use rustc_span::{create_default_session_globals_then, DUMMY_SP};
|
||||
use thin_vec::thin_vec;
|
||||
|
||||
use super::*;
|
||||
|
||||
fn word_cfg(s: &str) -> Cfg {
|
||||
Cfg::Cfg(Symbol::intern(s), None)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,11 +3,7 @@
|
|||
use std::iter::once;
|
||||
use std::sync::Arc;
|
||||
|
||||
use thin_vec::{thin_vec, ThinVec};
|
||||
|
||||
use rustc_ast as ast;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::def_id::{DefId, DefIdSet, LocalModDefId};
|
||||
use rustc_hir::Mutability;
|
||||
|
|
@ -16,8 +12,11 @@ use rustc_middle::ty::fast_reject::SimplifiedType;
|
|||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_span::def_id::LOCAL_CRATE;
|
||||
use rustc_span::hygiene::MacroKind;
|
||||
use rustc_span::symbol::{kw, sym, Symbol};
|
||||
use rustc_span::symbol::{sym, Symbol};
|
||||
use thin_vec::{thin_vec, ThinVec};
|
||||
use {rustc_ast as ast, rustc_hir as hir};
|
||||
|
||||
use super::Item;
|
||||
use crate::clean::{
|
||||
self, clean_bound_vars, clean_generics, clean_impl_item, clean_middle_assoc_item,
|
||||
clean_middle_field, clean_middle_ty, clean_poly_fn_sig, clean_trait_ref_with_constraints,
|
||||
|
|
@ -27,8 +26,6 @@ use crate::clean::{
|
|||
use crate::core::DocContext;
|
||||
use crate::formats::item_type::ItemType;
|
||||
|
||||
use super::Item;
|
||||
|
||||
/// Attempt to inline a definition into this AST.
|
||||
///
|
||||
/// This function will fetch the definition specified, and if it is
|
||||
|
|
@ -131,8 +128,8 @@ pub(crate) fn try_inline(
|
|||
Res::Def(DefKind::Const, did) => {
|
||||
record_extern_fqn(cx, did, ItemType::Constant);
|
||||
cx.with_param_env(did, |cx| {
|
||||
let (generics, ty, ct) = build_const_item(cx, did);
|
||||
clean::ConstantItem(generics, Box::new(ty), ct)
|
||||
let ct = build_const_item(cx, did);
|
||||
clean::ConstantItem(Box::new(ct))
|
||||
})
|
||||
}
|
||||
Res::Def(DefKind::Macro(kind), did) => {
|
||||
|
|
@ -720,10 +717,7 @@ pub(crate) fn print_inlined_const(tcx: TyCtxt<'_>, did: DefId) -> String {
|
|||
}
|
||||
}
|
||||
|
||||
fn build_const_item(
|
||||
cx: &mut DocContext<'_>,
|
||||
def_id: DefId,
|
||||
) -> (clean::Generics, clean::Type, clean::Constant) {
|
||||
fn build_const_item(cx: &mut DocContext<'_>, def_id: DefId) -> 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);
|
||||
|
|
@ -733,17 +727,17 @@ fn build_const_item(
|
|||
None,
|
||||
None,
|
||||
);
|
||||
(generics, ty, clean::Constant { kind: clean::ConstantKind::Extern { def_id } })
|
||||
clean::Constant { generics, type_: ty, kind: clean::ConstantKind::Extern { def_id } }
|
||||
}
|
||||
|
||||
fn build_static(cx: &mut DocContext<'_>, did: DefId, mutable: bool) -> clean::Static {
|
||||
clean::Static {
|
||||
type_: clean_middle_ty(
|
||||
type_: Box::new(clean_middle_ty(
|
||||
ty::Binder::dummy(cx.tcx.type_of(did).instantiate_identity()),
|
||||
cx,
|
||||
Some(did),
|
||||
None,
|
||||
),
|
||||
)),
|
||||
mutability: if mutable { Mutability::Mut } else { Mutability::Not },
|
||||
expr: None,
|
||||
}
|
||||
|
|
@ -798,11 +792,7 @@ fn build_macro(
|
|||
fn filter_non_trait_generics(trait_did: DefId, mut g: clean::Generics) -> clean::Generics {
|
||||
for pred in &mut g.where_predicates {
|
||||
match *pred {
|
||||
clean::WherePredicate::BoundPredicate {
|
||||
ty: clean::Generic(ref s),
|
||||
ref mut bounds,
|
||||
..
|
||||
} if *s == kw::SelfUpper => {
|
||||
clean::WherePredicate::BoundPredicate { ty: clean::SelfTy, ref mut bounds, .. } => {
|
||||
bounds.retain(|bound| match bound {
|
||||
clean::GenericBound::TraitBound(clean::PolyTrait { trait_, .. }, _) => {
|
||||
trait_.def_id() != trait_did
|
||||
|
|
@ -818,13 +808,13 @@ fn filter_non_trait_generics(trait_did: DefId, mut g: clean::Generics) -> clean:
|
|||
clean::WherePredicate::BoundPredicate {
|
||||
ty:
|
||||
clean::QPath(box clean::QPathData {
|
||||
self_type: clean::Generic(ref s),
|
||||
self_type: clean::Generic(_),
|
||||
trait_: Some(trait_),
|
||||
..
|
||||
}),
|
||||
bounds,
|
||||
..
|
||||
} => !(bounds.is_empty() || *s == kw::SelfUpper && trait_.def_id() == trait_did),
|
||||
} => !bounds.is_empty() && trait_.def_id() != trait_did,
|
||||
_ => true,
|
||||
});
|
||||
g
|
||||
|
|
@ -838,9 +828,7 @@ fn separate_supertrait_bounds(
|
|||
) -> (clean::Generics, Vec<clean::GenericBound>) {
|
||||
let mut ty_bounds = Vec::new();
|
||||
g.where_predicates.retain(|pred| match *pred {
|
||||
clean::WherePredicate::BoundPredicate { ty: clean::Generic(ref s), ref bounds, .. }
|
||||
if *s == kw::SelfUpper =>
|
||||
{
|
||||
clean::WherePredicate::BoundPredicate { ty: clean::SelfTy, ref bounds, .. } => {
|
||||
ty_bounds.extend(bounds.iter().cloned());
|
||||
false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,41 +30,36 @@ mod simplify;
|
|||
pub(crate) mod types;
|
||||
pub(crate) mod utils;
|
||||
|
||||
use rustc_ast as ast;
|
||||
use std::borrow::Cow;
|
||||
use std::collections::BTreeMap;
|
||||
use std::mem;
|
||||
|
||||
use rustc_ast::token::{Token, TokenKind};
|
||||
use rustc_ast::tokenstream::{TokenStream, TokenTree};
|
||||
use rustc_attr as attr;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet, IndexEntry};
|
||||
use rustc_errors::{codes::*, struct_span_code_err, FatalError};
|
||||
use rustc_hir as hir;
|
||||
use rustc_errors::codes::*;
|
||||
use rustc_errors::{struct_span_code_err, FatalError};
|
||||
use rustc_hir::def::{CtorKind, DefKind, Res};
|
||||
use rustc_hir::def_id::{DefId, DefIdMap, DefIdSet, LocalDefId, LOCAL_CRATE};
|
||||
use rustc_hir::PredicateOrigin;
|
||||
use rustc_hir_analysis::lower_ty;
|
||||
use rustc_middle::metadata::Reexport;
|
||||
use rustc_middle::middle::resolve_bound_vars as rbv;
|
||||
use rustc_middle::ty::GenericArgsRef;
|
||||
use rustc_middle::ty::TypeVisitableExt;
|
||||
use rustc_middle::ty::{self, AdtKind, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{self, AdtKind, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_span::hygiene::{AstPass, MacroKind};
|
||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||
use rustc_span::ExpnKind;
|
||||
use rustc_trait_selection::traits::wf::object_region_bounds;
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::collections::BTreeMap;
|
||||
use std::mem;
|
||||
use thin_vec::ThinVec;
|
||||
|
||||
use crate::core::DocContext;
|
||||
use crate::formats::item_type::ItemType;
|
||||
use crate::visit_ast::Module as DocModule;
|
||||
|
||||
use utils::*;
|
||||
use {rustc_ast as ast, rustc_attr as attr, rustc_hir as hir};
|
||||
|
||||
pub(crate) use self::types::*;
|
||||
pub(crate) use self::utils::{krate, register_res, synthesize_auto_trait_and_blanket_impls};
|
||||
use crate::core::DocContext;
|
||||
use crate::formats::item_type::ItemType;
|
||||
use crate::visit_ast::Module as DocModule;
|
||||
|
||||
pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext<'tcx>) -> Item {
|
||||
let mut items: Vec<Item> = vec![];
|
||||
|
|
@ -287,23 +282,21 @@ fn clean_lifetime<'tcx>(lifetime: &hir::Lifetime, cx: &mut DocContext<'tcx>) ->
|
|||
pub(crate) fn clean_const<'tcx>(
|
||||
constant: &hir::ConstArg<'tcx>,
|
||||
_cx: &mut DocContext<'tcx>,
|
||||
) -> Constant {
|
||||
) -> ConstantKind {
|
||||
match &constant.kind {
|
||||
hir::ConstArgKind::Path(qpath) => {
|
||||
Constant { kind: ConstantKind::Path { path: qpath_to_string(&qpath).into() } }
|
||||
}
|
||||
hir::ConstArgKind::Anon(anon) => {
|
||||
Constant { kind: ConstantKind::Anonymous { body: anon.body } }
|
||||
ConstantKind::Path { path: qpath_to_string(&qpath).into() }
|
||||
}
|
||||
hir::ConstArgKind::Anon(anon) => ConstantKind::Anonymous { body: anon.body },
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn clean_middle_const<'tcx>(
|
||||
constant: ty::Binder<'tcx, ty::Const<'tcx>>,
|
||||
_cx: &mut DocContext<'tcx>,
|
||||
) -> Constant {
|
||||
) -> ConstantKind {
|
||||
// FIXME: instead of storing the stringified expression, store `self` directly instead.
|
||||
Constant { kind: ConstantKind::TyConst { expr: constant.skip_binder().to_string().into() } }
|
||||
ConstantKind::TyConst { expr: constant.skip_binder().to_string().into() }
|
||||
}
|
||||
|
||||
pub(crate) fn clean_middle_region<'tcx>(region: ty::Region<'tcx>) -> Option<Lifetime> {
|
||||
|
|
@ -1230,14 +1223,11 @@ fn clean_trait_item<'tcx>(trait_item: &hir::TraitItem<'tcx>, cx: &mut DocContext
|
|||
let local_did = trait_item.owner_id.to_def_id();
|
||||
cx.with_param_env(local_did, |cx| {
|
||||
let inner = match trait_item.kind {
|
||||
hir::TraitItemKind::Const(ty, Some(default)) => {
|
||||
let generics = enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx));
|
||||
AssocConstItem(
|
||||
generics,
|
||||
Box::new(clean_ty(ty, cx)),
|
||||
ConstantKind::Local { def_id: local_did, body: default },
|
||||
)
|
||||
}
|
||||
hir::TraitItemKind::Const(ty, Some(default)) => AssocConstItem(Box::new(Constant {
|
||||
generics: enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx)),
|
||||
kind: ConstantKind::Local { def_id: local_did, body: default },
|
||||
type_: clean_ty(ty, cx),
|
||||
})),
|
||||
hir::TraitItemKind::Const(ty, None) => {
|
||||
let generics = enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx));
|
||||
TyAssocConstItem(generics, Box::new(clean_ty(ty, cx)))
|
||||
|
|
@ -1282,11 +1272,11 @@ pub(crate) fn clean_impl_item<'tcx>(
|
|||
let local_did = impl_.owner_id.to_def_id();
|
||||
cx.with_param_env(local_did, |cx| {
|
||||
let inner = match impl_.kind {
|
||||
hir::ImplItemKind::Const(ty, expr) => {
|
||||
let generics = clean_generics(impl_.generics, cx);
|
||||
let default = ConstantKind::Local { def_id: local_did, body: expr };
|
||||
AssocConstItem(generics, Box::new(clean_ty(ty, cx)), default)
|
||||
}
|
||||
hir::ImplItemKind::Const(ty, expr) => AssocConstItem(Box::new(Constant {
|
||||
generics: clean_generics(impl_.generics, cx),
|
||||
kind: ConstantKind::Local { def_id: local_did, body: expr },
|
||||
type_: clean_ty(ty, cx),
|
||||
})),
|
||||
hir::ImplItemKind::Fn(ref sig, body) => {
|
||||
let m = clean_function(cx, sig, impl_.generics, FunctionArgs::Body(body));
|
||||
let defaultness = cx.tcx.defaultness(impl_.owner_id);
|
||||
|
|
@ -1320,12 +1310,12 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
|
|||
let tcx = cx.tcx;
|
||||
let kind = match assoc_item.kind {
|
||||
ty::AssocKind::Const => {
|
||||
let ty = Box::new(clean_middle_ty(
|
||||
let ty = clean_middle_ty(
|
||||
ty::Binder::dummy(tcx.type_of(assoc_item.def_id).instantiate_identity()),
|
||||
cx,
|
||||
Some(assoc_item.def_id),
|
||||
None,
|
||||
));
|
||||
);
|
||||
|
||||
let mut generics = clean_ty_generics(
|
||||
cx,
|
||||
|
|
@ -1339,9 +1329,13 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
|
|||
ty::TraitContainer => tcx.defaultness(assoc_item.def_id).has_value(),
|
||||
};
|
||||
if provided {
|
||||
AssocConstItem(generics, ty, ConstantKind::Extern { def_id: assoc_item.def_id })
|
||||
AssocConstItem(Box::new(Constant {
|
||||
generics,
|
||||
kind: ConstantKind::Extern { def_id: assoc_item.def_id },
|
||||
type_: ty,
|
||||
}))
|
||||
} else {
|
||||
TyAssocConstItem(generics, ty)
|
||||
TyAssocConstItem(generics, Box::new(ty))
|
||||
}
|
||||
}
|
||||
ty::AssocKind::Fn => {
|
||||
|
|
@ -1357,11 +1351,11 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
|
|||
let self_arg_ty =
|
||||
tcx.fn_sig(assoc_item.def_id).instantiate_identity().input(0).skip_binder();
|
||||
if self_arg_ty == self_ty {
|
||||
item.decl.inputs.values[0].type_ = Generic(kw::SelfUpper);
|
||||
item.decl.inputs.values[0].type_ = SelfTy;
|
||||
} else if let ty::Ref(_, ty, _) = *self_arg_ty.kind() {
|
||||
if ty == self_ty {
|
||||
match item.decl.inputs.values[0].type_ {
|
||||
BorrowedRef { ref mut type_, .. } => **type_ = Generic(kw::SelfUpper),
|
||||
BorrowedRef { ref mut type_, .. } => **type_ = SelfTy,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
|
@ -1397,7 +1391,7 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
|
|||
{
|
||||
true
|
||||
}
|
||||
(GenericParamDefKind::Const { .. }, GenericArg::Const(c)) => match &c.kind {
|
||||
(GenericParamDefKind::Const { .. }, GenericArg::Const(c)) => match &**c {
|
||||
ConstantKind::TyConst { expr } => **expr == *param.name.as_str(),
|
||||
_ => false,
|
||||
},
|
||||
|
|
@ -1445,9 +1439,8 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
|
|||
if trait_.def_id() != assoc_item.container_id(tcx) {
|
||||
return true;
|
||||
}
|
||||
match *self_type {
|
||||
Generic(ref s) if *s == kw::SelfUpper => {}
|
||||
_ => return true,
|
||||
if *self_type != SelfTy {
|
||||
return true;
|
||||
}
|
||||
match &assoc.args {
|
||||
GenericArgs::AngleBracketed { args, constraints } => {
|
||||
|
|
@ -2234,6 +2227,8 @@ pub(crate) fn clean_middle_ty<'tcx>(
|
|||
ty::Param(ref p) => {
|
||||
if let Some(bounds) = cx.impl_trait_bounds.remove(&p.index.into()) {
|
||||
ImplTrait(bounds)
|
||||
} else if p.name == kw::SelfUpper {
|
||||
SelfTy
|
||||
} else {
|
||||
Generic(p.name)
|
||||
}
|
||||
|
|
@ -2744,18 +2739,19 @@ fn clean_maybe_renamed_item<'tcx>(
|
|||
let mut name = renamed.unwrap_or_else(|| cx.tcx.hir().name(item.hir_id()));
|
||||
cx.with_param_env(def_id, |cx| {
|
||||
let kind = match item.kind {
|
||||
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(
|
||||
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),
|
||||
ItemKind::Static(ty, mutability, body_id) => StaticItem(Static {
|
||||
type_: Box::new(clean_ty(ty, cx)),
|
||||
mutability,
|
||||
expr: Some(body_id),
|
||||
}),
|
||||
ItemKind::Const(ty, generics, body_id) => ConstantItem(Box::new(Constant {
|
||||
generics: clean_generics(generics, cx),
|
||||
type_: clean_ty(ty, cx),
|
||||
kind: ConstantKind::Local { body: body_id, def_id },
|
||||
})),
|
||||
// clean_ty changes types which reference an OpaqueTy item to instead be
|
||||
// an ImplTrait, so it's ok to return nothing here.
|
||||
ItemKind::OpaqueTy(_) => return vec![],
|
||||
ItemKind::TyAlias(hir_ty, generics) => {
|
||||
*cx.current_type_aliases.entry(def_id).or_insert(0) += 1;
|
||||
let rustdoc_ty = clean_ty(hir_ty, cx);
|
||||
|
|
@ -2838,7 +2834,7 @@ fn clean_maybe_renamed_item<'tcx>(
|
|||
ItemKind::Use(path, kind) => {
|
||||
return clean_use_statement(item, name, path, kind, cx, &mut FxHashSet::default());
|
||||
}
|
||||
_ => unreachable!("not yet converted"),
|
||||
_ => span_bug!(item.span, "not yet converted"),
|
||||
};
|
||||
|
||||
vec![generate_item_with_correct_attrs(
|
||||
|
|
@ -3109,7 +3105,7 @@ fn clean_maybe_renamed_foreign_item<'tcx>(
|
|||
ForeignFunctionItem(Box::new(Function { decl, generics }), safety)
|
||||
}
|
||||
hir::ForeignItemKind::Static(ty, mutability, safety) => ForeignStaticItem(
|
||||
Static { type_: clean_ty(ty, cx), mutability, expr: None },
|
||||
Static { type_: Box::new(clean_ty(ty, cx)), mutability, expr: None },
|
||||
safety,
|
||||
),
|
||||
hir::ForeignItemKind::Type => ForeignTypeItem,
|
||||
|
|
|
|||
|
|
@ -18,8 +18,7 @@ use rustc_middle::ty;
|
|||
use thin_vec::ThinVec;
|
||||
|
||||
use crate::clean;
|
||||
use crate::clean::GenericArgs as PP;
|
||||
use crate::clean::WherePredicate as WP;
|
||||
use crate::clean::{GenericArgs as PP, WherePredicate as WP};
|
||||
use crate::core::DocContext;
|
||||
|
||||
pub(crate) fn where_clauses(cx: &DocContext<'_>, clauses: ThinVec<WP>) -> ThinVec<WP> {
|
||||
|
|
@ -146,7 +145,6 @@ pub(crate) fn sized_bounds(cx: &mut DocContext<'_>, generics: &mut clean::Generi
|
|||
// should be handled when cleaning associated types.
|
||||
generics.where_predicates.retain(|pred| {
|
||||
if let WP::BoundPredicate { ty: clean::Generic(param), bounds, .. } = pred
|
||||
&& *param != rustc_span::symbol::kw::SelfUpper
|
||||
&& bounds.iter().any(|b| b.is_sized_bound(cx))
|
||||
{
|
||||
sized_params.insert(*param);
|
||||
|
|
|
|||
|
|
@ -3,19 +3,14 @@ use std::cell::RefCell;
|
|||
use std::hash::Hash;
|
||||
use std::path::PathBuf;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
use std::sync::OnceLock as OnceCell;
|
||||
use std::sync::{Arc, OnceLock as OnceCell};
|
||||
use std::{fmt, iter};
|
||||
|
||||
use arrayvec::ArrayVec;
|
||||
use thin_vec::ThinVec;
|
||||
|
||||
use rustc_ast as ast;
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_attr::{ConstStability, Deprecation, Stability, StabilityLevel, StableSince};
|
||||
use rustc_const_eval::const_eval::is_unstable_const_fn;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{CtorKind, DefKind, Res};
|
||||
use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
|
|
@ -35,7 +30,14 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
|||
use rustc_span::{FileName, Loc, DUMMY_SP};
|
||||
use rustc_target::abi::VariantIdx;
|
||||
use rustc_target::spec::abi::Abi;
|
||||
use thin_vec::ThinVec;
|
||||
use {rustc_ast as ast, rustc_hir as hir};
|
||||
|
||||
pub(crate) use self::ItemKind::*;
|
||||
pub(crate) use self::Type::{
|
||||
Array, BareFunction, BorrowedRef, DynTrait, Generic, ImplTrait, Infer, Primitive, QPath,
|
||||
RawPointer, SelfTy, Slice, Tuple,
|
||||
};
|
||||
use crate::clean::cfg::Cfg;
|
||||
use crate::clean::clean_middle_path;
|
||||
use crate::clean::inline::{self, print_inlined_const};
|
||||
|
|
@ -46,13 +48,6 @@ use crate::formats::item_type::ItemType;
|
|||
use crate::html::render::Context;
|
||||
use crate::passes::collect_intra_doc_links::UrlFragment;
|
||||
|
||||
pub(crate) use self::ItemKind::*;
|
||||
pub(crate) use self::SelfTy::*;
|
||||
pub(crate) use self::Type::{
|
||||
Array, BareFunction, BorrowedRef, DynTrait, Generic, ImplTrait, Infer, Primitive, QPath,
|
||||
RawPointer, Slice, Tuple,
|
||||
};
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
|
|
@ -828,7 +823,6 @@ pub(crate) enum ItemKind {
|
|||
FunctionItem(Box<Function>),
|
||||
ModuleItem(Module),
|
||||
TypeAliasItem(Box<TypeAlias>),
|
||||
OpaqueTyItem(OpaqueTy),
|
||||
StaticItem(Static),
|
||||
TraitItem(Box<Trait>),
|
||||
TraitAliasItem(TraitAlias),
|
||||
|
|
@ -852,9 +846,9 @@ pub(crate) enum ItemKind {
|
|||
PrimitiveItem(PrimitiveType),
|
||||
/// A required associated constant in a trait declaration.
|
||||
TyAssocConstItem(Generics, Box<Type>),
|
||||
ConstantItem(Generics, Box<Type>, Constant),
|
||||
ConstantItem(Box<Constant>),
|
||||
/// An associated constant in a trait impl or a provided one in a trait declaration.
|
||||
AssocConstItem(Generics, Box<Type>, ConstantKind),
|
||||
AssocConstItem(Box<Constant>),
|
||||
/// A required associated type in a trait declaration.
|
||||
///
|
||||
/// The bounds may be non-empty if there is a `where` clause.
|
||||
|
|
@ -886,9 +880,8 @@ impl ItemKind {
|
|||
| ImportItem(_)
|
||||
| FunctionItem(_)
|
||||
| TypeAliasItem(_)
|
||||
| OpaqueTyItem(_)
|
||||
| StaticItem(_)
|
||||
| ConstantItem(_, _, _)
|
||||
| ConstantItem(_)
|
||||
| TraitAliasItem(_)
|
||||
| TyMethodItem(_)
|
||||
| MethodItem(_, _)
|
||||
|
|
@ -920,9 +913,8 @@ impl ItemKind {
|
|||
| ExternCrateItem { .. }
|
||||
| FunctionItem(_)
|
||||
| TypeAliasItem(_)
|
||||
| OpaqueTyItem(_)
|
||||
| StaticItem(_)
|
||||
| ConstantItem(_, _, _)
|
||||
| ConstantItem(_)
|
||||
| TraitAliasItem(_)
|
||||
| ForeignFunctionItem(_, _)
|
||||
| ForeignStaticItem(_, _)
|
||||
|
|
@ -1391,8 +1383,8 @@ pub(crate) struct FnDecl {
|
|||
}
|
||||
|
||||
impl FnDecl {
|
||||
pub(crate) fn self_type(&self) -> Option<SelfTy> {
|
||||
self.inputs.values.get(0).and_then(|v| v.to_self())
|
||||
pub(crate) fn receiver_type(&self) -> Option<&Type> {
|
||||
self.inputs.values.get(0).and_then(|v| v.to_receiver())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1410,27 +1402,9 @@ pub(crate) struct Argument {
|
|||
pub(crate) is_const: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
pub(crate) enum SelfTy {
|
||||
SelfValue,
|
||||
SelfBorrowed(Option<Lifetime>, Mutability),
|
||||
SelfExplicit(Type),
|
||||
}
|
||||
|
||||
impl Argument {
|
||||
pub(crate) fn to_self(&self) -> Option<SelfTy> {
|
||||
if self.name != kw::SelfLower {
|
||||
return None;
|
||||
}
|
||||
if self.type_.is_self_type() {
|
||||
return Some(SelfValue);
|
||||
}
|
||||
match self.type_ {
|
||||
BorrowedRef { ref lifetime, mutability, ref type_ } if type_.is_self_type() => {
|
||||
Some(SelfBorrowed(lifetime.clone(), mutability))
|
||||
}
|
||||
_ => Some(SelfExplicit(self.type_.clone())),
|
||||
}
|
||||
pub(crate) fn to_receiver(&self) -> Option<&Type> {
|
||||
if self.name == kw::SelfLower { Some(&self.type_) } else { None }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1484,6 +1458,8 @@ pub(crate) enum Type {
|
|||
DynTrait(Vec<PolyTrait>, Option<Lifetime>),
|
||||
/// A type parameter.
|
||||
Generic(Symbol),
|
||||
/// The `Self` type.
|
||||
SelfTy,
|
||||
/// A primitive (aka, builtin) type.
|
||||
Primitive(PrimitiveType),
|
||||
/// A function pointer: `extern "ABI" fn(...) -> ...`
|
||||
|
|
@ -1578,6 +1554,8 @@ impl Type {
|
|||
// If both sides are generic, this returns true.
|
||||
(_, Type::Generic(_)) => true,
|
||||
(Type::Generic(_), _) => false,
|
||||
// `Self` only matches itself.
|
||||
(Type::SelfTy, Type::SelfTy) => true,
|
||||
// Paths account for both the path itself and its generics.
|
||||
(Type::Path { path: a }, Type::Path { path: b }) => {
|
||||
a.def_id() == b.def_id()
|
||||
|
|
@ -1649,7 +1627,7 @@ impl Type {
|
|||
|
||||
pub(crate) fn is_self_type(&self) -> bool {
|
||||
match *self {
|
||||
Generic(name) => name == kw::SelfUpper,
|
||||
SelfTy => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
@ -1684,13 +1662,16 @@ impl Type {
|
|||
}
|
||||
}
|
||||
|
||||
fn inner_def_id(&self, cache: Option<&Cache>) -> Option<DefId> {
|
||||
/// Use this method to get the [DefId] of a [clean] AST node, including [PrimitiveType]s.
|
||||
///
|
||||
/// [clean]: crate::clean
|
||||
pub(crate) fn def_id(&self, cache: &Cache) -> Option<DefId> {
|
||||
let t: PrimitiveType = match *self {
|
||||
Type::Path { ref path } => return Some(path.def_id()),
|
||||
DynTrait(ref bounds, _) => return bounds.get(0).map(|b| b.trait_.def_id()),
|
||||
Primitive(p) => return cache.and_then(|c| c.primitive_locations.get(&p).cloned()),
|
||||
Primitive(p) => return cache.primitive_locations.get(&p).cloned(),
|
||||
BorrowedRef { type_: box Generic(..), .. } => PrimitiveType::Reference,
|
||||
BorrowedRef { ref type_, .. } => return type_.inner_def_id(cache),
|
||||
BorrowedRef { ref type_, .. } => return type_.def_id(cache),
|
||||
Tuple(ref tys) => {
|
||||
if tys.is_empty() {
|
||||
PrimitiveType::Unit
|
||||
|
|
@ -1703,17 +1684,10 @@ impl Type {
|
|||
Array(..) => PrimitiveType::Array,
|
||||
Type::Pat(..) => PrimitiveType::Pat,
|
||||
RawPointer(..) => PrimitiveType::RawPointer,
|
||||
QPath(box QPathData { ref self_type, .. }) => return self_type.inner_def_id(cache),
|
||||
Generic(_) | Infer | ImplTrait(_) => return None,
|
||||
QPath(box QPathData { ref self_type, .. }) => return self_type.def_id(cache),
|
||||
Generic(_) | SelfTy | Infer | ImplTrait(_) => return None,
|
||||
};
|
||||
cache.and_then(|c| Primitive(t).def_id(c))
|
||||
}
|
||||
|
||||
/// Use this method to get the [DefId] of a [clean] AST node, including [PrimitiveType]s.
|
||||
///
|
||||
/// [clean]: crate::clean
|
||||
pub(crate) fn def_id(&self, cache: &Cache) -> Option<DefId> {
|
||||
self.inner_def_id(Some(cache))
|
||||
Primitive(t).def_id(cache)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2050,7 +2024,7 @@ impl From<hir::PrimTy> for PrimitiveType {
|
|||
pub(crate) struct Struct {
|
||||
pub(crate) ctor_kind: Option<CtorKind>,
|
||||
pub(crate) generics: Generics,
|
||||
pub(crate) fields: Vec<Item>,
|
||||
pub(crate) fields: ThinVec<Item>,
|
||||
}
|
||||
|
||||
impl Struct {
|
||||
|
|
@ -2076,7 +2050,7 @@ impl Union {
|
|||
/// only as a variant in an enum.
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) struct VariantStruct {
|
||||
pub(crate) fields: Vec<Item>,
|
||||
pub(crate) fields: ThinVec<Item>,
|
||||
}
|
||||
|
||||
impl VariantStruct {
|
||||
|
|
@ -2110,7 +2084,7 @@ pub(crate) struct Variant {
|
|||
#[derive(Clone, Debug)]
|
||||
pub(crate) enum VariantKind {
|
||||
CLike,
|
||||
Tuple(Vec<Item>),
|
||||
Tuple(ThinVec<Item>),
|
||||
Struct(VariantStruct),
|
||||
}
|
||||
|
||||
|
|
@ -2246,7 +2220,7 @@ impl Path {
|
|||
pub(crate) enum GenericArg {
|
||||
Lifetime(Lifetime),
|
||||
Type(Type),
|
||||
Const(Box<Constant>),
|
||||
Const(Box<ConstantKind>),
|
||||
Infer,
|
||||
}
|
||||
|
||||
|
|
@ -2343,12 +2317,6 @@ pub(crate) struct TypeAlias {
|
|||
pub(crate) item_type: Option<Type>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) struct OpaqueTy {
|
||||
pub(crate) bounds: Vec<GenericBound>,
|
||||
pub(crate) generics: Generics,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||
pub(crate) struct BareFunctionDecl {
|
||||
pub(crate) safety: hir::Safety,
|
||||
|
|
@ -2359,20 +2327,22 @@ pub(crate) struct BareFunctionDecl {
|
|||
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) struct Static {
|
||||
pub(crate) type_: Type,
|
||||
pub(crate) type_: Box<Type>,
|
||||
pub(crate) mutability: Mutability,
|
||||
pub(crate) expr: Option<BodyId>,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
|
||||
pub(crate) struct Constant {
|
||||
pub(crate) generics: Generics,
|
||||
pub(crate) kind: ConstantKind,
|
||||
pub(crate) type_: Type,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
|
||||
pub(crate) enum Term {
|
||||
Type(Type),
|
||||
Constant(Constant),
|
||||
Constant(ConstantKind),
|
||||
}
|
||||
|
||||
impl Term {
|
||||
|
|
@ -2476,6 +2446,10 @@ impl Impl {
|
|||
.map(|did| tcx.provided_trait_methods(did).map(|meth| meth.name).collect())
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
pub(crate) fn is_negative_trait_impl(&self) -> bool {
|
||||
matches!(self.polarity, ty::ImplPolarity::Negative)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
|
@ -2584,8 +2558,9 @@ pub(crate) enum AssocItemConstraintKind {
|
|||
// Some nodes are used a lot. Make sure they don't unintentionally get bigger.
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
mod size_asserts {
|
||||
use super::*;
|
||||
use rustc_data_structures::static_assert_size;
|
||||
|
||||
use super::*;
|
||||
// tidy-alphabetical-start
|
||||
static_assert_size!(Crate, 64); // frequently moved by-value
|
||||
static_assert_size!(DocFragment, 32);
|
||||
|
|
@ -2594,7 +2569,7 @@ mod size_asserts {
|
|||
static_assert_size!(GenericParamDef, 40);
|
||||
static_assert_size!(Generics, 16);
|
||||
static_assert_size!(Item, 56);
|
||||
static_assert_size!(ItemKind, 56);
|
||||
static_assert_size!(ItemKind, 48);
|
||||
static_assert_size!(PathSegment, 40);
|
||||
static_assert_size!(Type, 32);
|
||||
// tidy-alphabetical-end
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
use super::*;
|
||||
|
||||
use rustc_resolve::rustdoc::{unindent_doc_fragments, DocFragmentKind};
|
||||
use rustc_span::create_default_session_globals_then;
|
||||
|
||||
use super::*;
|
||||
|
||||
fn create_doc_fragment(s: &str) -> Vec<DocFragment> {
|
||||
vec![DocFragment {
|
||||
span: DUMMY_SP,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,18 @@
|
|||
use std::assert_matches::debug_assert_matches;
|
||||
use std::fmt::Write as _;
|
||||
use std::mem;
|
||||
use std::sync::LazyLock as Lazy;
|
||||
|
||||
use rustc_ast::tokenstream::TokenTree;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE};
|
||||
use rustc_metadata::rendered_const;
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::ty::{self, GenericArgKind, GenericArgsRef, TyCtxt, TypeVisitableExt};
|
||||
use rustc_span::symbol::{kw, sym, Symbol};
|
||||
use thin_vec::{thin_vec, ThinVec};
|
||||
use {rustc_ast as ast, rustc_hir as hir};
|
||||
|
||||
use crate::clean::auto_trait::synthesize_auto_trait_impls;
|
||||
use crate::clean::blanket_impl::synthesize_blanket_impls;
|
||||
use crate::clean::render_macro_matchers::render_macro_matcher;
|
||||
|
|
@ -10,22 +25,6 @@ use crate::clean::{
|
|||
use crate::core::DocContext;
|
||||
use crate::html::format::visibility_to_src_with_space;
|
||||
|
||||
use rustc_ast as ast;
|
||||
use rustc_ast::tokenstream::TokenTree;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE};
|
||||
use rustc_metadata::rendered_const;
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::ty::TypeVisitableExt;
|
||||
use rustc_middle::ty::{self, GenericArgKind, GenericArgsRef, TyCtxt};
|
||||
use rustc_span::symbol::{kw, sym, Symbol};
|
||||
use std::assert_matches::debug_assert_matches;
|
||||
use std::fmt::Write as _;
|
||||
use std::mem;
|
||||
use std::sync::LazyLock as Lazy;
|
||||
use thin_vec::{thin_vec, ThinVec};
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
|
|
@ -469,7 +468,7 @@ pub(crate) fn resolve_type(cx: &mut DocContext<'_>, path: Path) -> Type {
|
|||
match path.res {
|
||||
Res::PrimTy(p) => Primitive(PrimitiveType::from(p)),
|
||||
Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } if path.segments.len() == 1 => {
|
||||
Generic(kw::SelfUpper)
|
||||
Type::SelfTy
|
||||
}
|
||||
Res::Def(DefKind::TyParam, _) if path.segments.len() == 1 => Generic(path.segments[0].name),
|
||||
_ => {
|
||||
|
|
|
|||
|
|
@ -1,38 +1,32 @@
|
|||
use std::collections::BTreeMap;
|
||||
use std::ffi::OsStr;
|
||||
use std::fmt;
|
||||
use std::io;
|
||||
use std::io::Read;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::str::FromStr;
|
||||
use std::{fmt, io};
|
||||
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_errors::DiagCtxtHandle;
|
||||
use rustc_session::config::{
|
||||
self, parse_crate_types_from_list, parse_externs, parse_target_triple, CrateType,
|
||||
self, get_cmd_lint_options, nightly_options, parse_crate_types_from_list, parse_externs,
|
||||
parse_target_triple, CodegenOptions, CrateType, ErrorOutputType, Externs, Input,
|
||||
JsonUnusedExterns, UnstableOptions,
|
||||
};
|
||||
use rustc_session::config::{get_cmd_lint_options, nightly_options};
|
||||
use rustc_session::config::{CodegenOptions, ErrorOutputType, Externs, Input};
|
||||
use rustc_session::config::{JsonUnusedExterns, UnstableOptions};
|
||||
use rustc_session::getopts;
|
||||
use rustc_session::lint::Level;
|
||||
use rustc_session::search_paths::SearchPath;
|
||||
use rustc_session::EarlyDiagCtxt;
|
||||
use rustc_session::{getopts, EarlyDiagCtxt};
|
||||
use rustc_span::edition::Edition;
|
||||
use rustc_span::FileName;
|
||||
use rustc_target::spec::TargetTriple;
|
||||
|
||||
use crate::core::new_dcx;
|
||||
use crate::externalfiles::ExternalHtml;
|
||||
use crate::html;
|
||||
use crate::html::markdown::IdMap;
|
||||
use crate::html::render::StylePath;
|
||||
use crate::html::static_files;
|
||||
use crate::opts;
|
||||
use crate::passes::{self, Condition};
|
||||
use crate::scrape_examples::{AllCallLocations, ScrapeExamplesOptions};
|
||||
use crate::theme;
|
||||
use crate::{html, opts, theme};
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)]
|
||||
pub(crate) enum OutputFormat {
|
||||
|
|
@ -368,9 +362,10 @@ impl Options {
|
|||
}
|
||||
|
||||
let color = config::parse_color(early_dcx, matches);
|
||||
let config::JsonConfig { json_rendered, json_unused_externs, .. } =
|
||||
let config::JsonConfig { json_rendered, json_unused_externs, json_color, .. } =
|
||||
config::parse_json(early_dcx, matches);
|
||||
let error_format = config::parse_error_format(early_dcx, matches, color, json_rendered);
|
||||
let error_format =
|
||||
config::parse_error_format(early_dcx, matches, color, json_color, json_rendered);
|
||||
let diagnostic_width = matches.opt_get("diagnostic-width").unwrap_or_default();
|
||||
|
||||
let codegen_options = CodegenOptions::build(early_dcx, matches);
|
||||
|
|
|
|||
|
|
@ -1,9 +1,16 @@
|
|||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
use std::sync::atomic::AtomicBool;
|
||||
use std::sync::{Arc, LazyLock};
|
||||
use std::{io, mem};
|
||||
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_data_structures::unord::UnordSet;
|
||||
use rustc_errors::codes::*;
|
||||
use rustc_errors::emitter::{stderr_destination, DynEmitter, HumanEmitter};
|
||||
use rustc_errors::json::JsonEmitter;
|
||||
use rustc_errors::{codes::*, DiagCtxtHandle, ErrorGuaranteed, TerminalUrl};
|
||||
use rustc_errors::{DiagCtxtHandle, ErrorGuaranteed, TerminalUrl};
|
||||
use rustc_feature::UnstableFeatures;
|
||||
use rustc_hir::def::Res;
|
||||
use rustc_hir::def_id::{DefId, DefIdMap, DefIdSet, LocalDefId};
|
||||
|
|
@ -14,25 +21,17 @@ use rustc_lint::{late_lint_mod, MissingDoc};
|
|||
use rustc_middle::hir::nested_filter;
|
||||
use rustc_middle::ty::{ParamEnv, Ty, TyCtxt};
|
||||
use rustc_session::config::{self, CrateType, ErrorOutputType, ResolveDocLinks};
|
||||
use rustc_session::lint;
|
||||
use rustc_session::Session;
|
||||
pub(crate) use rustc_session::config::{Options, UnstableOptions};
|
||||
use rustc_session::{lint, Session};
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::{source_map, Span};
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::io;
|
||||
use std::mem;
|
||||
use std::rc::Rc;
|
||||
use std::sync::LazyLock;
|
||||
use std::sync::{atomic::AtomicBool, Arc};
|
||||
|
||||
use crate::clean::inline::build_external_trait;
|
||||
use crate::clean::{self, ItemId};
|
||||
use crate::config::{Options as RustdocOptions, OutputFormat, RenderOptions};
|
||||
use crate::formats::cache::Cache;
|
||||
use crate::passes::{self, Condition::*};
|
||||
|
||||
pub(crate) use rustc_session::config::{Options, UnstableOptions};
|
||||
use crate::passes::Condition::*;
|
||||
use crate::passes::{self};
|
||||
|
||||
pub(crate) struct DocContext<'tcx> {
|
||||
pub(crate) tcx: TyCtxt<'tcx>,
|
||||
|
|
@ -139,8 +138,8 @@ pub(crate) fn new_dcx(
|
|||
false,
|
||||
);
|
||||
let emitter: Box<DynEmitter> = match error_format {
|
||||
ErrorOutputType::HumanReadable(kind) => {
|
||||
let (short, color_config) = kind.unzip();
|
||||
ErrorOutputType::HumanReadable(kind, color_config) => {
|
||||
let short = kind.short();
|
||||
Box::new(
|
||||
HumanEmitter::new(stderr_destination(color_config), fallback_bundle)
|
||||
.sm(source_map.map(|sm| sm as _))
|
||||
|
|
@ -151,7 +150,7 @@ pub(crate) fn new_dcx(
|
|||
.ui_testing(unstable_opts.ui_testing),
|
||||
)
|
||||
}
|
||||
ErrorOutputType::Json { pretty, json_rendered } => {
|
||||
ErrorOutputType::Json { pretty, json_rendered, color_config } => {
|
||||
let source_map = source_map.unwrap_or_else(|| {
|
||||
Lrc::new(source_map::SourceMap::new(source_map::FilePathMapping::empty()))
|
||||
});
|
||||
|
|
@ -162,6 +161,7 @@ pub(crate) fn new_dcx(
|
|||
fallback_bundle,
|
||||
pretty,
|
||||
json_rendered,
|
||||
color_config,
|
||||
)
|
||||
.ui_testing(unstable_opts.ui_testing)
|
||||
.diagnostic_width(diagnostic_width)
|
||||
|
|
@ -196,6 +196,7 @@ pub(crate) fn create_config(
|
|||
lint_cap,
|
||||
scrape_examples_options,
|
||||
expanded_args,
|
||||
remap_path_prefix,
|
||||
..
|
||||
}: RustdocOptions,
|
||||
RenderOptions { document_private, .. }: &RenderOptions,
|
||||
|
|
@ -248,6 +249,7 @@ pub(crate) fn create_config(
|
|||
describe_lints,
|
||||
crate_name,
|
||||
test,
|
||||
remap_path_prefix,
|
||||
..Options::default()
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -9,11 +9,11 @@
|
|||
//! abstraction.
|
||||
|
||||
use std::cmp::max;
|
||||
use std::fs;
|
||||
use std::io;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::mpsc::Sender;
|
||||
use std::thread::available_parallelism;
|
||||
use std::{fs, io};
|
||||
|
||||
use threadpool::ThreadPool;
|
||||
|
||||
pub(crate) trait PathError {
|
||||
|
|
|
|||
|
|
@ -2,9 +2,16 @@ mod make;
|
|||
mod markdown;
|
||||
mod rust;
|
||||
|
||||
use std::fs::File;
|
||||
use std::io::{self, Write};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::{self, Command, Stdio};
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::{panic, str};
|
||||
|
||||
pub(crate) use make::make_test;
|
||||
pub(crate) use markdown::test as test_markdown;
|
||||
|
||||
use rustc_ast as ast;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_errors::{ColorConfig, DiagCtxtHandle, ErrorGuaranteed, FatalError};
|
||||
|
|
@ -17,24 +24,13 @@ use rustc_span::edition::Edition;
|
|||
use rustc_span::symbol::sym;
|
||||
use rustc_span::FileName;
|
||||
use rustc_target::spec::{Target, TargetTriple};
|
||||
|
||||
use std::fs::File;
|
||||
use std::io::{self, Write};
|
||||
use std::panic;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::{self, Command, Stdio};
|
||||
use std::str;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use tempfile::{Builder as TempFileBuilder, TempDir};
|
||||
|
||||
use self::rust::HirCollector;
|
||||
use crate::config::Options as RustdocOptions;
|
||||
use crate::html::markdown::{ErrorCodes, Ignore, LangString, MdRelLine};
|
||||
use crate::lint::init_lints;
|
||||
|
||||
use self::rust::HirCollector;
|
||||
|
||||
/// Options that apply to all doctests in a crate or Markdown file (for `rustdoc foo.md`).
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct GlobalTestOptions {
|
||||
|
|
@ -426,8 +422,8 @@ fn run_test(
|
|||
path_for_rustdoc.to_str().expect("target path must be valid unicode")
|
||||
}
|
||||
});
|
||||
if let ErrorOutputType::HumanReadable(kind) = rustdoc_options.error_format {
|
||||
let (short, color_config) = kind.unzip();
|
||||
if let ErrorOutputType::HumanReadable(kind, color_config) = rustdoc_options.error_format {
|
||||
let short = kind.short();
|
||||
|
||||
if short {
|
||||
compiler.arg("--error-format").arg("short");
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
use std::env;
|
||||
|
||||
use rustc_data_structures::{fx::FxHashSet, sync::Lrc};
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
|
||||
use rustc_hir::{self as hir, intravisit, CRATE_HIR_ID};
|
||||
use rustc_middle::hir::map::Map;
|
||||
|
|
@ -14,7 +15,8 @@ use rustc_span::source_map::SourceMap;
|
|||
use rustc_span::{BytePos, FileName, Pos, Span, DUMMY_SP};
|
||||
|
||||
use super::{DoctestVisitor, ScrapedDoctest};
|
||||
use crate::clean::{types::AttributesExt, Attributes};
|
||||
use crate::clean::types::AttributesExt;
|
||||
use crate::clean::Attributes;
|
||||
use crate::html::markdown::{self, ErrorCodes, LangString, MdRelLine};
|
||||
|
||||
struct RustCollector {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
use std::path::PathBuf;
|
||||
|
||||
use super::{make_test, GlobalTestOptions};
|
||||
use rustc_span::edition::DEFAULT_EDITION;
|
||||
|
||||
use super::{make_test, GlobalTestOptions};
|
||||
|
||||
/// Default [`GlobalTestOptions`] for these unit tests.
|
||||
fn default_global_opts(crate_name: impl Into<String>) -> GlobalTestOptions {
|
||||
GlobalTestOptions {
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
use crate::html::markdown::{ErrorCodes, HeadingOffset, IdMap, Markdown, Playground};
|
||||
use std::path::Path;
|
||||
use std::{fs, str};
|
||||
|
||||
use rustc_errors::DiagCtxtHandle;
|
||||
use rustc_span::edition::Edition;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
use std::str;
|
||||
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::html::markdown::{ErrorCodes, HeadingOffset, IdMap, Markdown, Playground};
|
||||
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
pub(crate) struct ExternalHtml {
|
||||
/// Content that will be included inline in the `<head>` section of a
|
||||
|
|
|
|||
|
|
@ -77,9 +77,8 @@ pub(crate) trait DocFolder: Sized {
|
|||
ExternCrateItem { src: _ }
|
||||
| ImportItem(_)
|
||||
| FunctionItem(_)
|
||||
| OpaqueTyItem(_)
|
||||
| StaticItem(_)
|
||||
| ConstantItem(_, _, _)
|
||||
| ConstantItem(..)
|
||||
| TraitAliasItem(_)
|
||||
| TyMethodItem(_)
|
||||
| MethodItem(_, _)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@ use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet};
|
|||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_span::Symbol;
|
||||
|
||||
use crate::clean::{self, types::ExternalLocation, ExternalCrate, ItemId, PrimitiveType};
|
||||
use crate::clean::types::ExternalLocation;
|
||||
use crate::clean::{self, ExternalCrate, ItemId, PrimitiveType};
|
||||
use crate::core::DocContext;
|
||||
use crate::fold::DocFolder;
|
||||
use crate::formats::item_type::ItemType;
|
||||
|
|
@ -259,153 +260,21 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
|
|||
}
|
||||
|
||||
// Index this method for searching later on.
|
||||
if let Some(s) = item.name.or_else(|| {
|
||||
if item.is_stripped() {
|
||||
None
|
||||
} else if let clean::ImportItem(ref i) = *item.kind
|
||||
&& let clean::ImportKind::Simple(s) = i.kind
|
||||
{
|
||||
Some(s)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}) {
|
||||
let (parent, is_inherent_impl_item) = match *item.kind {
|
||||
clean::StrippedItem(..) => ((None, None), false),
|
||||
clean::AssocConstItem(..) | clean::AssocTypeItem(..)
|
||||
if self
|
||||
.cache
|
||||
.parent_stack
|
||||
.last()
|
||||
.is_some_and(|parent| parent.is_trait_impl()) =>
|
||||
let search_name = if !item.is_stripped() {
|
||||
item.name.or_else(|| {
|
||||
if let clean::ImportItem(ref i) = *item.kind
|
||||
&& let clean::ImportKind::Simple(s) = i.kind
|
||||
{
|
||||
// skip associated items in trait impls
|
||||
((None, None), false)
|
||||
Some(s)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
clean::TyMethodItem(..)
|
||||
| clean::TyAssocConstItem(..)
|
||||
| clean::TyAssocTypeItem(..)
|
||||
| clean::StructFieldItem(..)
|
||||
| clean::VariantItem(..) => (
|
||||
(
|
||||
Some(
|
||||
self.cache
|
||||
.parent_stack
|
||||
.last()
|
||||
.expect("parent_stack is empty")
|
||||
.item_id()
|
||||
.expect_def_id(),
|
||||
),
|
||||
Some(&self.cache.stack[..self.cache.stack.len() - 1]),
|
||||
),
|
||||
false,
|
||||
),
|
||||
clean::MethodItem(..) | clean::AssocConstItem(..) | clean::AssocTypeItem(..) => {
|
||||
if self.cache.parent_stack.is_empty() {
|
||||
((None, None), false)
|
||||
} else {
|
||||
let last = self.cache.parent_stack.last().expect("parent_stack is empty 2");
|
||||
let did = match &*last {
|
||||
ParentStackItem::Impl {
|
||||
// impl Trait for &T { fn method(self); }
|
||||
//
|
||||
// When generating a function index with the above shape, we want it
|
||||
// associated with `T`, not with the primitive reference type. It should
|
||||
// show up as `T::method`, rather than `reference::method`, in the search
|
||||
// results page.
|
||||
for_: clean::Type::BorrowedRef { type_, .. },
|
||||
..
|
||||
} => type_.def_id(&self.cache),
|
||||
ParentStackItem::Impl { for_, .. } => for_.def_id(&self.cache),
|
||||
ParentStackItem::Type(item_id) => item_id.as_def_id(),
|
||||
};
|
||||
let path = did
|
||||
.and_then(|did| self.cache.paths.get(&did))
|
||||
// The current stack not necessarily has correlation
|
||||
// for where the type was defined. On the other
|
||||
// hand, `paths` always has the right
|
||||
// information if present.
|
||||
.map(|(fqp, _)| &fqp[..fqp.len() - 1]);
|
||||
((did, path), true)
|
||||
}
|
||||
}
|
||||
_ => ((None, Some(&*self.cache.stack)), false),
|
||||
};
|
||||
|
||||
match parent {
|
||||
(parent, Some(path)) if is_inherent_impl_item || !self.cache.stripped_mod => {
|
||||
debug_assert!(!item.is_stripped());
|
||||
|
||||
// A crate has a module at its root, containing all items,
|
||||
// which should not be indexed. The crate-item itself is
|
||||
// inserted later on when serializing the search-index.
|
||||
if item.item_id.as_def_id().is_some_and(|idx| !idx.is_crate_root())
|
||||
&& let ty = item.type_()
|
||||
&& (ty != ItemType::StructField
|
||||
|| u16::from_str_radix(s.as_str(), 10).is_err())
|
||||
{
|
||||
let desc =
|
||||
short_markdown_summary(&item.doc_value(), &item.link_names(self.cache));
|
||||
// For searching purposes, a re-export is a duplicate if:
|
||||
//
|
||||
// - It's either an inline, or a true re-export
|
||||
// - It's got the same name
|
||||
// - Both of them have the same exact path
|
||||
let defid = (match &*item.kind {
|
||||
&clean::ItemKind::ImportItem(ref import) => import.source.did,
|
||||
_ => None,
|
||||
})
|
||||
.or_else(|| item.item_id.as_def_id());
|
||||
// In case this is a field from a tuple struct, we don't add it into
|
||||
// the search index because its name is something like "0", which is
|
||||
// not useful for rustdoc search.
|
||||
self.cache.search_index.push(IndexItem {
|
||||
ty,
|
||||
defid,
|
||||
name: s,
|
||||
path: join_with_double_colon(path),
|
||||
desc,
|
||||
parent,
|
||||
parent_idx: None,
|
||||
exact_path: None,
|
||||
impl_id: if let Some(ParentStackItem::Impl { item_id, .. }) =
|
||||
self.cache.parent_stack.last()
|
||||
{
|
||||
item_id.as_def_id()
|
||||
} else {
|
||||
None
|
||||
},
|
||||
search_type: get_function_type_for_search(
|
||||
&item,
|
||||
self.tcx,
|
||||
clean_impl_generics(self.cache.parent_stack.last()).as_ref(),
|
||||
parent,
|
||||
self.cache,
|
||||
),
|
||||
aliases: item.attrs.get_doc_aliases(),
|
||||
deprecation: item.deprecation(self.tcx),
|
||||
});
|
||||
}
|
||||
}
|
||||
(Some(parent), None) if is_inherent_impl_item => {
|
||||
// We have a parent, but we don't know where they're
|
||||
// defined yet. Wait for later to index this item.
|
||||
let impl_generics = clean_impl_generics(self.cache.parent_stack.last());
|
||||
self.cache.orphan_impl_items.push(OrphanImplItem {
|
||||
parent,
|
||||
item: item.clone(),
|
||||
impl_generics,
|
||||
impl_id: if let Some(ParentStackItem::Impl { item_id, .. }) =
|
||||
self.cache.parent_stack.last()
|
||||
{
|
||||
item_id.as_def_id()
|
||||
} else {
|
||||
None
|
||||
},
|
||||
});
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
if let Some(name) = search_name {
|
||||
add_item_to_search_index(self.tcx, &mut self.cache, &item, name)
|
||||
}
|
||||
|
||||
// Keep track of the fully qualified path for this item.
|
||||
|
|
@ -441,16 +310,16 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
|
|||
// `public_items` map, so we can skip inserting into the
|
||||
// paths map if there was already an entry present and we're
|
||||
// not a public item.
|
||||
if !self.cache.paths.contains_key(&item.item_id.expect_def_id())
|
||||
let item_def_id = item.item_id.expect_def_id();
|
||||
if !self.cache.paths.contains_key(&item_def_id)
|
||||
|| self
|
||||
.cache
|
||||
.effective_visibilities
|
||||
.is_directly_public(self.tcx, item.item_id.expect_def_id())
|
||||
.is_directly_public(self.tcx, item_def_id)
|
||||
{
|
||||
self.cache.paths.insert(
|
||||
item.item_id.expect_def_id(),
|
||||
(self.cache.stack.clone(), item.type_()),
|
||||
);
|
||||
self.cache
|
||||
.paths
|
||||
.insert(item_def_id, (self.cache.stack.clone(), item.type_()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -462,7 +331,6 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
|
|||
|
||||
clean::ExternCrateItem { .. }
|
||||
| clean::ImportItem(..)
|
||||
| clean::OpaqueTyItem(..)
|
||||
| clean::ImplItem(..)
|
||||
| clean::TyMethodItem(..)
|
||||
| clean::MethodItem(..)
|
||||
|
|
@ -513,9 +381,7 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
|
|||
&& adt.is_fundamental()
|
||||
{
|
||||
for ty in generics {
|
||||
if let Some(did) = ty.def_id(self.cache) {
|
||||
dids.insert(did);
|
||||
}
|
||||
dids.extend(ty.def_id(self.cache));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -528,32 +394,26 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
|
|||
.primitive_type()
|
||||
.and_then(|t| self.cache.primitive_locations.get(&t).cloned());
|
||||
|
||||
if let Some(did) = did {
|
||||
dids.insert(did);
|
||||
}
|
||||
dids.extend(did);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(generics) = i.trait_.as_ref().and_then(|t| t.generics()) {
|
||||
for bound in generics {
|
||||
if let Some(did) = bound.def_id(self.cache) {
|
||||
dids.insert(did);
|
||||
}
|
||||
dids.extend(bound.def_id(self.cache));
|
||||
}
|
||||
}
|
||||
let impl_item = Impl { impl_item: item };
|
||||
if impl_item.trait_did().map_or(true, |d| self.cache.traits.contains_key(&d)) {
|
||||
let impl_did = impl_item.def_id();
|
||||
let trait_did = impl_item.trait_did();
|
||||
if trait_did.map_or(true, |d| self.cache.traits.contains_key(&d)) {
|
||||
for did in dids {
|
||||
if self.impl_ids.entry(did).or_default().insert(impl_item.def_id()) {
|
||||
self.cache
|
||||
.impls
|
||||
.entry(did)
|
||||
.or_insert_with(Vec::new)
|
||||
.push(impl_item.clone());
|
||||
if self.impl_ids.entry(did).or_default().insert(impl_did) {
|
||||
self.cache.impls.entry(did).or_default().push(impl_item.clone());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let trait_did = impl_item.trait_did().expect("no trait did");
|
||||
let trait_did = trait_did.expect("no trait did");
|
||||
self.cache.orphan_trait_impls.push((trait_did, dids, impl_item));
|
||||
}
|
||||
None
|
||||
|
|
@ -572,6 +432,152 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn add_item_to_search_index(tcx: TyCtxt<'_>, cache: &mut Cache, item: &clean::Item, name: Symbol) {
|
||||
// Item has a name, so it must also have a DefId (can't be an impl, let alone a blanket or auto impl).
|
||||
let item_def_id = item.item_id.as_def_id().unwrap();
|
||||
let (parent_did, parent_path) = match *item.kind {
|
||||
clean::StrippedItem(..) => return,
|
||||
clean::AssocConstItem(..) | clean::AssocTypeItem(..)
|
||||
if cache.parent_stack.last().is_some_and(|parent| parent.is_trait_impl()) =>
|
||||
{
|
||||
// skip associated items in trait impls
|
||||
return;
|
||||
}
|
||||
clean::TyMethodItem(..)
|
||||
| clean::TyAssocConstItem(..)
|
||||
| clean::TyAssocTypeItem(..)
|
||||
| clean::StructFieldItem(..)
|
||||
| clean::VariantItem(..) => {
|
||||
// Don't index if containing module is stripped (i.e., private),
|
||||
// or if item is tuple struct/variant field (name is a number -> not useful for search).
|
||||
if cache.stripped_mod
|
||||
|| item.type_() == ItemType::StructField
|
||||
&& name.as_str().chars().all(|c| c.is_digit(10))
|
||||
{
|
||||
return;
|
||||
}
|
||||
let parent_did =
|
||||
cache.parent_stack.last().expect("parent_stack is empty").item_id().expect_def_id();
|
||||
let parent_path = &cache.stack[..cache.stack.len() - 1];
|
||||
(Some(parent_did), parent_path)
|
||||
}
|
||||
clean::MethodItem(..) | clean::AssocConstItem(..) | clean::AssocTypeItem(..) => {
|
||||
let last = cache.parent_stack.last().expect("parent_stack is empty 2");
|
||||
let parent_did = match &*last {
|
||||
// impl Trait for &T { fn method(self); }
|
||||
//
|
||||
// When generating a function index with the above shape, we want it
|
||||
// associated with `T`, not with the primitive reference type. It should
|
||||
// show up as `T::method`, rather than `reference::method`, in the search
|
||||
// results page.
|
||||
ParentStackItem::Impl { for_: clean::Type::BorrowedRef { type_, .. }, .. } => {
|
||||
type_.def_id(&cache)
|
||||
}
|
||||
ParentStackItem::Impl { for_, .. } => for_.def_id(&cache),
|
||||
ParentStackItem::Type(item_id) => item_id.as_def_id(),
|
||||
};
|
||||
let Some(parent_did) = parent_did else { return };
|
||||
// The current stack reflects the CacheBuilder's recursive
|
||||
// walk over HIR. For associated items, this is the module
|
||||
// where the `impl` block is defined. That's an implementation
|
||||
// detail that we don't want to affect the search engine.
|
||||
//
|
||||
// In particular, you can arrange things like this:
|
||||
//
|
||||
// #![crate_name="me"]
|
||||
// mod private_mod {
|
||||
// impl Clone for MyThing { fn clone(&self) -> MyThing { MyThing } }
|
||||
// }
|
||||
// pub struct MyThing;
|
||||
//
|
||||
// When that happens, we need to:
|
||||
// - ignore the `cache.stripped_mod` flag, since the Clone impl is actually
|
||||
// part of the public API even though it's defined in a private module
|
||||
// - present the method as `me::MyThing::clone`, its publicly-visible path
|
||||
// - deal with the fact that the recursive walk hasn't actually reached `MyThing`
|
||||
// until it's already past `private_mod`, since that's first, and doesn't know
|
||||
// yet if `MyThing` will actually be public or not (it could be re-exported)
|
||||
//
|
||||
// We accomplish the last two points by recording children of "orphan impls"
|
||||
// in a field of the cache whose elements are added to the search index later,
|
||||
// after cache building is complete (see `handle_orphan_impl_child`).
|
||||
match cache.paths.get(&parent_did) {
|
||||
Some((fqp, _)) => (Some(parent_did), &fqp[..fqp.len() - 1]),
|
||||
None => {
|
||||
handle_orphan_impl_child(cache, item, parent_did);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
// Don't index if item is crate root, which is inserted later on when serializing the index.
|
||||
// Don't index if containing module is stripped (i.e., private),
|
||||
if item_def_id.is_crate_root() || cache.stripped_mod {
|
||||
return;
|
||||
}
|
||||
(None, &*cache.stack)
|
||||
}
|
||||
};
|
||||
|
||||
debug_assert!(!item.is_stripped());
|
||||
|
||||
let desc = short_markdown_summary(&item.doc_value(), &item.link_names(cache));
|
||||
// For searching purposes, a re-export is a duplicate if:
|
||||
//
|
||||
// - It's either an inline, or a true re-export
|
||||
// - It's got the same name
|
||||
// - Both of them have the same exact path
|
||||
let defid = match &*item.kind {
|
||||
clean::ItemKind::ImportItem(import) => import.source.did.unwrap_or(item_def_id),
|
||||
_ => item_def_id,
|
||||
};
|
||||
let path = join_with_double_colon(parent_path);
|
||||
let impl_id = if let Some(ParentStackItem::Impl { item_id, .. }) = cache.parent_stack.last() {
|
||||
item_id.as_def_id()
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let search_type = get_function_type_for_search(
|
||||
&item,
|
||||
tcx,
|
||||
clean_impl_generics(cache.parent_stack.last()).as_ref(),
|
||||
parent_did,
|
||||
cache,
|
||||
);
|
||||
let aliases = item.attrs.get_doc_aliases();
|
||||
let deprecation = item.deprecation(tcx);
|
||||
let index_item = IndexItem {
|
||||
ty: item.type_(),
|
||||
defid: Some(defid),
|
||||
name,
|
||||
path,
|
||||
desc,
|
||||
parent: parent_did,
|
||||
parent_idx: None,
|
||||
exact_path: None,
|
||||
impl_id,
|
||||
search_type,
|
||||
aliases,
|
||||
deprecation,
|
||||
};
|
||||
cache.search_index.push(index_item);
|
||||
}
|
||||
|
||||
/// We have a parent, but we don't know where they're
|
||||
/// defined yet. Wait for later to index this item.
|
||||
/// See [`Cache::orphan_impl_items`].
|
||||
fn handle_orphan_impl_child(cache: &mut Cache, item: &clean::Item, parent_did: DefId) {
|
||||
let impl_generics = clean_impl_generics(cache.parent_stack.last());
|
||||
let impl_id = if let Some(ParentStackItem::Impl { item_id, .. }) = cache.parent_stack.last() {
|
||||
item_id.as_def_id()
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let orphan_item =
|
||||
OrphanImplItem { parent: parent_did, item: item.clone(), impl_generics, impl_id };
|
||||
cache.orphan_impl_items.push(orphan_item);
|
||||
}
|
||||
|
||||
pub(crate) struct OrphanImplItem {
|
||||
pub(crate) parent: DefId,
|
||||
pub(crate) impl_id: Option<DefId>,
|
||||
|
|
|
|||
|
|
@ -2,10 +2,9 @@
|
|||
|
||||
use std::fmt;
|
||||
|
||||
use serde::{Serialize, Serializer};
|
||||
|
||||
use rustc_hir::def::{CtorOf, DefKind};
|
||||
use rustc_span::hygiene::MacroKind;
|
||||
use serde::{Serialize, Serializer};
|
||||
|
||||
use crate::clean;
|
||||
|
||||
|
|
@ -52,7 +51,7 @@ pub(crate) enum ItemType {
|
|||
AssocConst = 19,
|
||||
Union = 20,
|
||||
ForeignType = 21,
|
||||
OpaqueTy = 22,
|
||||
// OpaqueTy used to be here, but it was removed in #127276
|
||||
ProcAttribute = 23,
|
||||
ProcDerive = 24,
|
||||
TraitAlias = 25,
|
||||
|
|
@ -85,7 +84,6 @@ impl<'a> From<&'a clean::Item> for ItemType {
|
|||
clean::EnumItem(..) => ItemType::Enum,
|
||||
clean::FunctionItem(..) => ItemType::Function,
|
||||
clean::TypeAliasItem(..) => ItemType::TypeAlias,
|
||||
clean::OpaqueTyItem(..) => ItemType::OpaqueTy,
|
||||
clean::StaticItem(..) => ItemType::Static,
|
||||
clean::ConstantItem(..) => ItemType::Constant,
|
||||
clean::TraitItem(..) => ItemType::Trait,
|
||||
|
|
@ -192,7 +190,6 @@ impl ItemType {
|
|||
ItemType::AssocConst => "associatedconstant",
|
||||
ItemType::ForeignType => "foreigntype",
|
||||
ItemType::Keyword => "keyword",
|
||||
ItemType::OpaqueTy => "opaque",
|
||||
ItemType::ProcAttribute => "attr",
|
||||
ItemType::ProcDerive => "derive",
|
||||
ItemType::TraitAlias => "traitalias",
|
||||
|
|
|
|||
|
|
@ -2,9 +2,8 @@ pub(crate) mod cache;
|
|||
pub(crate) mod item_type;
|
||||
pub(crate) mod renderer;
|
||||
|
||||
use rustc_hir::def_id::DefId;
|
||||
|
||||
pub(crate) use renderer::{run_format, FormatRenderer};
|
||||
use rustc_hir::def_id::DefId;
|
||||
|
||||
use crate::clean::{self, ItemId};
|
||||
use crate::html::render::Context;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
use std::fmt;
|
||||
|
||||
use unicode_segmentation::UnicodeSegmentation;
|
||||
|
||||
/// Wrapper struct which will emit the HTML-escaped version of the contained
|
||||
/// string when passed to a format string.
|
||||
pub(crate) struct Escape<'a>(pub &'a str);
|
||||
|
|
@ -74,3 +76,56 @@ impl<'a> fmt::Display for EscapeBodyText<'a> {
|
|||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Wrapper struct which will emit the HTML-escaped version of the contained
|
||||
/// string when passed to a format string. This function also word-breaks
|
||||
/// CamelCase and snake_case word names.
|
||||
///
|
||||
/// This is only safe to use for text nodes. If you need your output to be
|
||||
/// safely contained in an attribute, use [`Escape`]. If you don't know the
|
||||
/// difference, use [`Escape`].
|
||||
pub(crate) struct EscapeBodyTextWithWbr<'a>(pub &'a str);
|
||||
|
||||
impl<'a> fmt::Display for EscapeBodyTextWithWbr<'a> {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let EscapeBodyTextWithWbr(text) = *self;
|
||||
if text.len() < 8 {
|
||||
return EscapeBodyText(text).fmt(fmt);
|
||||
}
|
||||
let mut last = 0;
|
||||
let mut it = text.grapheme_indices(true).peekable();
|
||||
let _ = it.next(); // don't insert wbr before first char
|
||||
while let Some((i, s)) = it.next() {
|
||||
let pk = it.peek();
|
||||
if s.chars().all(|c| c.is_whitespace()) {
|
||||
// don't need "First <wbr>Second"; the space is enough
|
||||
EscapeBodyText(&text[last..i]).fmt(fmt)?;
|
||||
last = i;
|
||||
continue;
|
||||
}
|
||||
let is_uppercase = || s.chars().any(|c| c.is_uppercase());
|
||||
let next_is_uppercase =
|
||||
|| pk.map_or(true, |(_, t)| t.chars().any(|c| c.is_uppercase()));
|
||||
let next_is_underscore = || pk.map_or(true, |(_, t)| t.contains('_'));
|
||||
let next_is_colon = || pk.map_or(true, |(_, t)| t.contains(':'));
|
||||
if i - last > 3 && is_uppercase() && !next_is_uppercase() {
|
||||
EscapeBodyText(&text[last..i]).fmt(fmt)?;
|
||||
fmt.write_str("<wbr>")?;
|
||||
last = i;
|
||||
} else if (s.contains(':') && !next_is_colon())
|
||||
|| (s.contains('_') && !next_is_underscore())
|
||||
{
|
||||
EscapeBodyText(&text[last..i + 1]).fmt(fmt)?;
|
||||
fmt.write_str("<wbr>")?;
|
||||
last = i + 1;
|
||||
}
|
||||
}
|
||||
if last < text.len() {
|
||||
EscapeBodyText(&text[last..]).fmt(fmt)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
|
|
|||
68
src/librustdoc/html/escape/tests.rs
Normal file
68
src/librustdoc/html/escape/tests.rs
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
// basic examples
|
||||
#[test]
|
||||
fn escape_body_text_with_wbr() {
|
||||
use super::EscapeBodyTextWithWbr as E;
|
||||
// extreme corner cases
|
||||
assert_eq!(&E("").to_string(), "");
|
||||
assert_eq!(&E("a").to_string(), "a");
|
||||
assert_eq!(&E("A").to_string(), "A");
|
||||
assert_eq!(&E("_").to_string(), "_");
|
||||
assert_eq!(&E(":").to_string(), ":");
|
||||
assert_eq!(&E(" ").to_string(), " ");
|
||||
assert_eq!(&E("___________").to_string(), "___________");
|
||||
assert_eq!(&E(":::::::::::").to_string(), ":::::::::::");
|
||||
assert_eq!(&E(" ").to_string(), " ");
|
||||
// real(istic) examples
|
||||
assert_eq!(&E("FirstSecond").to_string(), "First<wbr>Second");
|
||||
assert_eq!(&E("First_Second").to_string(), "First_<wbr>Second");
|
||||
assert_eq!(&E("First Second").to_string(), "First Second");
|
||||
assert_eq!(&E("First HSecond").to_string(), "First HSecond");
|
||||
assert_eq!(&E("First HTTPSecond").to_string(), "First HTTP<wbr>Second");
|
||||
assert_eq!(&E("First SecondThird").to_string(), "First Second<wbr>Third");
|
||||
assert_eq!(&E("First<T>_Second").to_string(), "First<<wbr>T>_<wbr>Second");
|
||||
assert_eq!(&E("first_second").to_string(), "first_<wbr>second");
|
||||
assert_eq!(&E("first:second").to_string(), "first:<wbr>second");
|
||||
assert_eq!(&E("first::second").to_string(), "first::<wbr>second");
|
||||
assert_eq!(&E("MY_CONSTANT").to_string(), "MY_<wbr>CONSTANT");
|
||||
// a string won't get wrapped if it's less than 8 bytes
|
||||
assert_eq!(&E("HashSet").to_string(), "HashSet");
|
||||
// an individual word won't get wrapped if it's less than 4 bytes
|
||||
assert_eq!(&E("VecDequeue").to_string(), "VecDequeue");
|
||||
assert_eq!(&E("VecDequeueSet").to_string(), "VecDequeue<wbr>Set");
|
||||
// how to handle acronyms
|
||||
assert_eq!(&E("BTreeMap").to_string(), "BTree<wbr>Map");
|
||||
assert_eq!(&E("HTTPSProxy").to_string(), "HTTPS<wbr>Proxy");
|
||||
// more corners
|
||||
assert_eq!(&E("ṼẽçÑñéå").to_string(), "Ṽẽç<wbr>Ññéå");
|
||||
assert_eq!(&E("V\u{0300}e\u{0300}c\u{0300}D\u{0300}e\u{0300}q\u{0300}u\u{0300}e\u{0300}u\u{0300}e\u{0300}").to_string(), "V\u{0300}e\u{0300}c\u{0300}<wbr>D\u{0300}e\u{0300}q\u{0300}u\u{0300}e\u{0300}u\u{0300}e\u{0300}");
|
||||
assert_eq!(&E("LPFNACCESSIBLEOBJECTFROMWINDOW").to_string(), "LPFNACCESSIBLEOBJECTFROMWINDOW");
|
||||
}
|
||||
// property test
|
||||
#[test]
|
||||
fn escape_body_text_with_wbr_makes_sense() {
|
||||
use itertools::Itertools as _;
|
||||
|
||||
use super::EscapeBodyTextWithWbr as E;
|
||||
const C: [u8; 3] = [b'a', b'A', b'_'];
|
||||
for chars in [
|
||||
C.into_iter(),
|
||||
C.into_iter(),
|
||||
C.into_iter(),
|
||||
C.into_iter(),
|
||||
C.into_iter(),
|
||||
C.into_iter(),
|
||||
C.into_iter(),
|
||||
C.into_iter(),
|
||||
]
|
||||
.into_iter()
|
||||
.multi_cartesian_product()
|
||||
{
|
||||
let s = String::from_utf8(chars).unwrap();
|
||||
assert_eq!(s.len(), 8);
|
||||
let esc = E(&s).to_string();
|
||||
assert!(!esc.contains("<wbr><wbr>"));
|
||||
assert!(!esc.ends_with("<wbr>"));
|
||||
assert!(!esc.starts_with("<wbr>"));
|
||||
assert_eq!(&esc.replace("<wbr>", ""), &s);
|
||||
}
|
||||
}
|
||||
|
|
@ -12,11 +12,10 @@ use std::cell::Cell;
|
|||
use std::fmt::{self, Display, Write};
|
||||
use std::iter::{self, once};
|
||||
|
||||
use rustc_ast as ast;
|
||||
use itertools::Itertools;
|
||||
use rustc_attr::{ConstStability, StabilityLevel, StableSince};
|
||||
use rustc_data_structures::captures::Captures;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
|
||||
use rustc_metadata::creader::{CStore, LoadedMacro};
|
||||
|
|
@ -25,21 +24,18 @@ use rustc_middle::ty::TyCtxt;
|
|||
use rustc_span::symbol::kw;
|
||||
use rustc_span::{sym, Symbol};
|
||||
use rustc_target::spec::abi::Abi;
|
||||
use {rustc_ast as ast, rustc_hir as hir};
|
||||
|
||||
use itertools::Itertools;
|
||||
|
||||
use crate::clean::{
|
||||
self, types::ExternalLocation, utils::find_nearest_parent_module, ExternalCrate, PrimitiveType,
|
||||
};
|
||||
use super::url_parts_builder::{estimate_item_path_byte_length, UrlPartsBuilder};
|
||||
use crate::clean::types::ExternalLocation;
|
||||
use crate::clean::utils::find_nearest_parent_module;
|
||||
use crate::clean::{self, ExternalCrate, PrimitiveType};
|
||||
use crate::formats::cache::Cache;
|
||||
use crate::formats::item_type::ItemType;
|
||||
use crate::html::escape::Escape;
|
||||
use crate::html::escape::{Escape, EscapeBodyText};
|
||||
use crate::html::render::Context;
|
||||
use crate::passes::collect_intra_doc_links::UrlFragment;
|
||||
|
||||
use super::url_parts_builder::estimate_item_path_byte_length;
|
||||
use super::url_parts_builder::UrlPartsBuilder;
|
||||
|
||||
pub(crate) trait Print {
|
||||
fn print(self, buffer: &mut Buffer);
|
||||
}
|
||||
|
|
@ -375,7 +371,7 @@ impl clean::Lifetime {
|
|||
}
|
||||
}
|
||||
|
||||
impl clean::Constant {
|
||||
impl clean::ConstantKind {
|
||||
pub(crate) fn print(&self, tcx: TyCtxt<'_>) -> impl Display + '_ {
|
||||
let expr = self.expr(tcx);
|
||||
display_fn(
|
||||
|
|
@ -992,6 +988,7 @@ pub(crate) fn anchor<'a, 'cx: 'a>(
|
|||
f,
|
||||
r#"<a class="{short_ty}" href="{url}" title="{short_ty} {path}">{text}</a>"#,
|
||||
path = join_with_double_colon(&fqp),
|
||||
text = EscapeBodyText(text.as_str()),
|
||||
)
|
||||
} else {
|
||||
f.write_str(text.as_str())
|
||||
|
|
@ -1009,6 +1006,7 @@ fn fmt_type<'cx>(
|
|||
|
||||
match *t {
|
||||
clean::Generic(name) => f.write_str(name.as_str()),
|
||||
clean::SelfTy => f.write_str("Self"),
|
||||
clean::Type::Path { ref path } => {
|
||||
// Paths like `T::Output` and `Self::Output` should be rendered with all segments.
|
||||
let did = path.def_id();
|
||||
|
|
@ -1287,9 +1285,8 @@ impl clean::Impl {
|
|||
f.write_str(" ")?;
|
||||
|
||||
if let Some(ref ty) = self.trait_ {
|
||||
match self.polarity {
|
||||
ty::ImplPolarity::Positive | ty::ImplPolarity::Reservation => {}
|
||||
ty::ImplPolarity::Negative => write!(f, "!")?,
|
||||
if self.is_negative_trait_impl() {
|
||||
write!(f, "!")?;
|
||||
}
|
||||
ty.print(cx).fmt(f)?;
|
||||
write!(f, " for ")?;
|
||||
|
|
@ -1455,29 +1452,22 @@ impl clean::FnDecl {
|
|||
|
||||
let last_input_index = self.inputs.values.len().checked_sub(1);
|
||||
for (i, input) in self.inputs.values.iter().enumerate() {
|
||||
if let Some(selfty) = input.to_self() {
|
||||
if let Some(selfty) = input.to_receiver() {
|
||||
match selfty {
|
||||
clean::SelfValue => {
|
||||
clean::SelfTy => {
|
||||
write!(f, "self")?;
|
||||
}
|
||||
clean::SelfBorrowed(Some(ref lt), mutability) => {
|
||||
write!(
|
||||
f,
|
||||
"{amp}{lifetime} {mutability}self",
|
||||
lifetime = lt.print(),
|
||||
mutability = mutability.print_with_space(),
|
||||
)?;
|
||||
clean::BorrowedRef { lifetime, mutability, type_: box clean::SelfTy } => {
|
||||
write!(f, "{amp}")?;
|
||||
match lifetime {
|
||||
Some(lt) => write!(f, "{lt} ", lt = lt.print())?,
|
||||
None => {}
|
||||
}
|
||||
write!(f, "{mutability}self", mutability = mutability.print_with_space())?;
|
||||
}
|
||||
clean::SelfBorrowed(None, mutability) => {
|
||||
write!(
|
||||
f,
|
||||
"{amp}{mutability}self",
|
||||
mutability = mutability.print_with_space(),
|
||||
)?;
|
||||
}
|
||||
clean::SelfExplicit(ref typ) => {
|
||||
_ => {
|
||||
write!(f, "self: ")?;
|
||||
typ.print(cx).fmt(f)?;
|
||||
selfty.print(cx).fmt(f)?;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -5,10 +5,6 @@
|
|||
//!
|
||||
//! Use the `render_with_highlighting` to highlight some rust code.
|
||||
|
||||
use crate::clean::PrimitiveType;
|
||||
use crate::html::escape::EscapeBodyText;
|
||||
use crate::html::render::{Context, LinkFromSrc};
|
||||
|
||||
use std::collections::VecDeque;
|
||||
use std::fmt::{Display, Write};
|
||||
|
||||
|
|
@ -19,6 +15,9 @@ use rustc_span::symbol::Symbol;
|
|||
use rustc_span::{BytePos, Span, DUMMY_SP};
|
||||
|
||||
use super::format::{self, Buffer};
|
||||
use crate::clean::PrimitiveType;
|
||||
use crate::html::escape::EscapeBodyText;
|
||||
use crate::html::render::{Context, LinkFromSrc};
|
||||
|
||||
/// This type is needed in case we want to render links on items to allow to go to their definition.
|
||||
pub(crate) struct HrefContext<'a, 'tcx> {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
use super::{write_code, DecorationInfo};
|
||||
use crate::html::format::Buffer;
|
||||
use expect_test::expect_file;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_span::create_default_session_globals_then;
|
||||
|
||||
use super::{write_code, DecorationInfo};
|
||||
use crate::html::format::Buffer;
|
||||
|
||||
const STYLE: &str = r#"
|
||||
<style>
|
||||
.kw { color: #8959A8; }
|
||||
|
|
|
|||
|
|
@ -1,15 +1,13 @@
|
|||
use std::path::PathBuf;
|
||||
|
||||
use rinja::Template;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
|
||||
use super::static_files::{StaticFiles, STATIC_FILES};
|
||||
use crate::externalfiles::ExternalHtml;
|
||||
use crate::html::format::{Buffer, Print};
|
||||
use crate::html::render::{ensure_trailing_slash, StylePath};
|
||||
|
||||
use rinja::Template;
|
||||
|
||||
use super::static_files::{StaticFiles, STATIC_FILES};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct Layout {
|
||||
pub(crate) logo: String,
|
||||
|
|
@ -71,6 +69,8 @@ struct PageLayout<'a> {
|
|||
display_krate_version_extra: &'a str,
|
||||
}
|
||||
|
||||
pub(crate) use crate::html::render::sidebar::filters;
|
||||
|
||||
pub(crate) fn render<T: Print, S: Print>(
|
||||
layout: &Layout,
|
||||
page: &Page<'_>,
|
||||
|
|
|
|||
|
|
@ -25,15 +25,6 @@
|
|||
//! // ... something using html
|
||||
//! ```
|
||||
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_errors::{Diag, DiagMessage};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
pub(crate) use rustc_resolve::rustdoc::main_body_opts;
|
||||
use rustc_resolve::rustdoc::may_be_doc_link;
|
||||
use rustc_span::edition::Edition;
|
||||
use rustc_span::{Span, Symbol};
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::collections::VecDeque;
|
||||
use std::fmt::Write;
|
||||
|
|
@ -43,6 +34,19 @@ use std::path::PathBuf;
|
|||
use std::str::{self, CharIndices};
|
||||
use std::sync::OnceLock;
|
||||
|
||||
use pulldown_cmark::{
|
||||
html, BrokenLink, BrokenLinkCallback, CodeBlockKind, CowStr, Event, LinkType, OffsetIter,
|
||||
Options, Parser, Tag, TagEnd,
|
||||
};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_errors::{Diag, DiagMessage};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
pub(crate) use rustc_resolve::rustdoc::main_body_opts;
|
||||
use rustc_resolve::rustdoc::may_be_doc_link;
|
||||
use rustc_span::edition::Edition;
|
||||
use rustc_span::{Span, Symbol};
|
||||
|
||||
use crate::clean::RenderedLink;
|
||||
use crate::doctest;
|
||||
use crate::doctest::GlobalTestOptions;
|
||||
|
|
@ -53,11 +57,6 @@ use crate::html::length_limit::HtmlWithLimit;
|
|||
use crate::html::render::small_url_encode;
|
||||
use crate::html::toc::TocBuilder;
|
||||
|
||||
use pulldown_cmark::{
|
||||
html, BrokenLink, BrokenLinkCallback, CodeBlockKind, CowStr, Event, LinkType, OffsetIter,
|
||||
Options, Parser, Tag, TagEnd,
|
||||
};
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
|
|
@ -305,7 +304,8 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
|
|||
Some(format!(
|
||||
"<a class=\"test-arrow\" \
|
||||
target=\"_blank\" \
|
||||
href=\"{url}?code={test_escaped}{channel}&edition={edition}\">Run</a>",
|
||||
title=\"Run code\" \
|
||||
href=\"{url}?code={test_escaped}{channel}&edition={edition}\"></a>",
|
||||
))
|
||||
});
|
||||
|
||||
|
|
@ -925,6 +925,7 @@ pub(crate) struct TagIterator<'a, 'tcx> {
|
|||
data: &'a str,
|
||||
is_in_attribute_block: bool,
|
||||
extra: Option<&'a ExtraInfo<'tcx>>,
|
||||
is_error: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
|
|
@ -951,13 +952,20 @@ struct Indices {
|
|||
|
||||
impl<'a, 'tcx> TagIterator<'a, 'tcx> {
|
||||
pub(crate) fn new(data: &'a str, extra: Option<&'a ExtraInfo<'tcx>>) -> Self {
|
||||
Self { inner: data.char_indices().peekable(), data, is_in_attribute_block: false, extra }
|
||||
Self {
|
||||
inner: data.char_indices().peekable(),
|
||||
data,
|
||||
is_in_attribute_block: false,
|
||||
extra,
|
||||
is_error: false,
|
||||
}
|
||||
}
|
||||
|
||||
fn emit_error(&self, err: impl Into<DiagMessage>) {
|
||||
fn emit_error(&mut self, err: impl Into<DiagMessage>) {
|
||||
if let Some(extra) = self.extra {
|
||||
extra.error_invalid_codeblock_attr(err);
|
||||
}
|
||||
self.is_error = true;
|
||||
}
|
||||
|
||||
fn skip_separators(&mut self) -> Option<usize> {
|
||||
|
|
@ -1155,6 +1163,9 @@ impl<'a, 'tcx> Iterator for TagIterator<'a, 'tcx> {
|
|||
type Item = LangStringToken<'a>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.is_error {
|
||||
return None;
|
||||
}
|
||||
let Some(start) = self.skip_separators() else {
|
||||
if self.is_in_attribute_block {
|
||||
self.emit_error("unclosed attribute block (`{}`): missing `}` at the end");
|
||||
|
|
@ -1343,14 +1354,15 @@ impl LangString {
|
|||
}
|
||||
};
|
||||
|
||||
call(&mut TagIterator::new(string, extra));
|
||||
let mut tag_iter = TagIterator::new(string, extra);
|
||||
call(&mut tag_iter);
|
||||
|
||||
// ignore-foo overrides ignore
|
||||
if !ignores.is_empty() {
|
||||
data.ignore = Ignore::Some(ignores);
|
||||
}
|
||||
|
||||
data.rust &= !seen_custom_tag && (!seen_other_tags || seen_rust_tags);
|
||||
data.rust &= !seen_custom_tag && (!seen_other_tags || seen_rust_tags) && !tag_iter.is_error;
|
||||
|
||||
data
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
use super::{find_testable_code, plain_text_summary, short_markdown_summary};
|
||||
use super::{
|
||||
ErrorCodes, HeadingOffset, IdMap, Ignore, LangString, LangStringToken, Markdown,
|
||||
MarkdownItemInfo, TagIterator,
|
||||
};
|
||||
use rustc_span::edition::{Edition, DEFAULT_EDITION};
|
||||
|
||||
use super::{
|
||||
find_testable_code, plain_text_summary, short_markdown_summary, ErrorCodes, HeadingOffset,
|
||||
IdMap, Ignore, LangString, LangStringToken, Markdown, MarkdownItemInfo, TagIterator,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn test_unique_id() {
|
||||
let input = [
|
||||
|
|
@ -61,7 +61,7 @@ fn test_lang_string_parse() {
|
|||
..Default::default()
|
||||
});
|
||||
// error
|
||||
t(LangString { original: "{rust}".into(), rust: true, ..Default::default() });
|
||||
t(LangString { original: "{rust}".into(), rust: false, ..Default::default() });
|
||||
t(LangString {
|
||||
original: "{.rust}".into(),
|
||||
rust: true,
|
||||
|
|
@ -233,7 +233,7 @@ fn test_lang_string_parse() {
|
|||
..Default::default()
|
||||
});
|
||||
// error
|
||||
t(LangString { original: "{class=first=second}".into(), rust: true, ..Default::default() });
|
||||
t(LangString { original: "{class=first=second}".into(), rust: false, ..Default::default() });
|
||||
// error
|
||||
t(LangString {
|
||||
original: "{class=first.second}".into(),
|
||||
|
|
@ -261,7 +261,7 @@ fn test_lang_string_parse() {
|
|||
..Default::default()
|
||||
});
|
||||
// error
|
||||
t(LangString { original: r#"{class=f"irst"}"#.into(), rust: true, ..Default::default() });
|
||||
t(LangString { original: r#"{class=f"irst"}"#.into(), rust: false, ..Default::default() });
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ use std::path::{Path, PathBuf};
|
|||
use std::rc::Rc;
|
||||
use std::sync::mpsc::{channel, Receiver};
|
||||
|
||||
use rinja::Template;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_hir::def_id::{DefIdMap, LOCAL_CRATE};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
|
|
@ -14,15 +15,12 @@ use rustc_span::{sym, FileName, Symbol};
|
|||
|
||||
use super::print_item::{full_path, item_path, print_item};
|
||||
use super::search_index::build_index;
|
||||
use super::sidebar::{print_sidebar, sidebar_module_like, Sidebar};
|
||||
use super::write_shared::write_shared;
|
||||
use super::{
|
||||
collect_spans_and_sources, scrape_examples_help,
|
||||
sidebar::print_sidebar,
|
||||
sidebar::{sidebar_module_like, Sidebar},
|
||||
AllTypes, LinkFromSrc, StylePath,
|
||||
};
|
||||
use super::{collect_spans_and_sources, scrape_examples_help, AllTypes, LinkFromSrc, StylePath};
|
||||
use crate::clean::types::ExternalLocation;
|
||||
use crate::clean::utils::has_doc_flag;
|
||||
use crate::clean::{self, types::ExternalLocation, ExternalCrate};
|
||||
use crate::clean::{self, ExternalCrate};
|
||||
use crate::config::{ModuleSorting, RenderOptions};
|
||||
use crate::docfs::{DocFS, PathError};
|
||||
use crate::error::Error;
|
||||
|
|
@ -36,7 +34,6 @@ use crate::html::url_parts_builder::UrlPartsBuilder;
|
|||
use crate::html::{layout, sources, static_files};
|
||||
use crate::scrape_examples::AllCallLocations;
|
||||
use crate::try_err;
|
||||
use rinja::Template;
|
||||
|
||||
/// Major driving force in all rustdoc rendering. This contains information
|
||||
/// about where in the tree-like hierarchy rendering is occurring and controls
|
||||
|
|
|
|||
|
|
@ -30,21 +30,17 @@ mod tests;
|
|||
|
||||
mod context;
|
||||
mod print_item;
|
||||
mod sidebar;
|
||||
pub(crate) mod sidebar;
|
||||
mod span_map;
|
||||
mod type_layout;
|
||||
mod write_shared;
|
||||
|
||||
pub(crate) use self::context::*;
|
||||
pub(crate) use self::span_map::{collect_spans_and_sources, LinkFromSrc};
|
||||
|
||||
use std::collections::VecDeque;
|
||||
use std::fmt::{self, Write};
|
||||
use std::fs;
|
||||
use std::iter::Peekable;
|
||||
use std::path::PathBuf;
|
||||
use std::rc::Rc;
|
||||
use std::str;
|
||||
use std::{fs, str};
|
||||
|
||||
use rinja::Template;
|
||||
use rustc_attr::{ConstStability, DeprecatedSince, Deprecation, StabilityLevel, StableSince};
|
||||
|
|
@ -55,14 +51,14 @@ use rustc_hir::Mutability;
|
|||
use rustc_middle::ty::print::PrintTraitRefExt;
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_session::RustcVersion;
|
||||
use rustc_span::{
|
||||
symbol::{sym, Symbol},
|
||||
BytePos, FileName, RealFileName, DUMMY_SP,
|
||||
};
|
||||
use rustc_span::symbol::{sym, Symbol};
|
||||
use rustc_span::{BytePos, FileName, RealFileName, DUMMY_SP};
|
||||
use serde::ser::SerializeMap;
|
||||
use serde::{Serialize, Serializer};
|
||||
|
||||
use crate::clean::{self, ItemId, RenderedLink, SelfTy};
|
||||
pub(crate) use self::context::*;
|
||||
pub(crate) use self::span_map::{collect_spans_and_sources, LinkFromSrc};
|
||||
use crate::clean::{self, ItemId, RenderedLink};
|
||||
use crate::error::Error;
|
||||
use crate::formats::cache::Cache;
|
||||
use crate::formats::item_type::ItemType;
|
||||
|
|
@ -73,15 +69,13 @@ use crate::html::format::{
|
|||
print_default_space, print_generic_bounds, print_where_clause, visibility_print_with_space,
|
||||
Buffer, Ending, HrefError, PrintWithSpace,
|
||||
};
|
||||
use crate::html::highlight;
|
||||
use crate::html::markdown::{
|
||||
HeadingOffset, IdMap, Markdown, MarkdownItemInfo, MarkdownSummaryLine,
|
||||
};
|
||||
use crate::html::sources;
|
||||
use crate::html::static_files::SCRAPE_EXAMPLES_HELP_MD;
|
||||
use crate::html::{highlight, sources};
|
||||
use crate::scrape_examples::{CallData, CallLocation};
|
||||
use crate::try_none;
|
||||
use crate::DOC_RUST_LANG_ORG_CHANNEL;
|
||||
use crate::{try_none, DOC_RUST_LANG_ORG_CHANNEL};
|
||||
|
||||
pub(crate) fn ensure_trailing_slash(v: &str) -> impl fmt::Display + '_ {
|
||||
crate::html::format::display_fn(move |f| {
|
||||
|
|
@ -338,7 +332,6 @@ struct AllTypes {
|
|||
macros: FxHashSet<ItemEntry>,
|
||||
functions: FxHashSet<ItemEntry>,
|
||||
type_aliases: FxHashSet<ItemEntry>,
|
||||
opaque_tys: FxHashSet<ItemEntry>,
|
||||
statics: FxHashSet<ItemEntry>,
|
||||
constants: FxHashSet<ItemEntry>,
|
||||
attribute_macros: FxHashSet<ItemEntry>,
|
||||
|
|
@ -358,7 +351,6 @@ impl AllTypes {
|
|||
macros: new_set(100),
|
||||
functions: new_set(100),
|
||||
type_aliases: new_set(100),
|
||||
opaque_tys: new_set(100),
|
||||
statics: new_set(100),
|
||||
constants: new_set(100),
|
||||
attribute_macros: new_set(100),
|
||||
|
|
@ -382,7 +374,6 @@ impl AllTypes {
|
|||
ItemType::Macro => self.macros.insert(ItemEntry::new(new_url, name)),
|
||||
ItemType::Function => self.functions.insert(ItemEntry::new(new_url, name)),
|
||||
ItemType::TypeAlias => self.type_aliases.insert(ItemEntry::new(new_url, name)),
|
||||
ItemType::OpaqueTy => self.opaque_tys.insert(ItemEntry::new(new_url, name)),
|
||||
ItemType::Static => self.statics.insert(ItemEntry::new(new_url, name)),
|
||||
ItemType::Constant => self.constants.insert(ItemEntry::new(new_url, name)),
|
||||
ItemType::ProcAttribute => {
|
||||
|
|
@ -422,9 +413,6 @@ impl AllTypes {
|
|||
if !self.type_aliases.is_empty() {
|
||||
sections.insert(ItemSection::TypeAliases);
|
||||
}
|
||||
if !self.opaque_tys.is_empty() {
|
||||
sections.insert(ItemSection::OpaqueTypes);
|
||||
}
|
||||
if !self.statics.is_empty() {
|
||||
sections.insert(ItemSection::Statics);
|
||||
}
|
||||
|
|
@ -478,7 +466,6 @@ impl AllTypes {
|
|||
print_entries(f, &self.functions, ItemSection::Functions);
|
||||
print_entries(f, &self.type_aliases, ItemSection::TypeAliases);
|
||||
print_entries(f, &self.trait_aliases, ItemSection::TraitAliases);
|
||||
print_entries(f, &self.opaque_tys, ItemSection::OpaqueTypes);
|
||||
print_entries(f, &self.statics, ItemSection::Statics);
|
||||
print_entries(f, &self.constants, ItemSection::Constants);
|
||||
}
|
||||
|
|
@ -1090,22 +1077,26 @@ fn render_assoc_item(
|
|||
clean::MethodItem(m, _) => {
|
||||
assoc_method(w, item, &m.generics, &m.decl, link, parent, cx, render_mode)
|
||||
}
|
||||
kind @ (clean::TyAssocConstItem(generics, ty) | clean::AssocConstItem(generics, ty, _)) => {
|
||||
assoc_const(
|
||||
w,
|
||||
item,
|
||||
generics,
|
||||
ty,
|
||||
match kind {
|
||||
clean::TyAssocConstItem(..) => None,
|
||||
clean::AssocConstItem(.., default) => Some(default),
|
||||
_ => unreachable!(),
|
||||
},
|
||||
link,
|
||||
if parent == ItemType::Trait { 4 } else { 0 },
|
||||
cx,
|
||||
)
|
||||
}
|
||||
clean::TyAssocConstItem(generics, ty) => assoc_const(
|
||||
w,
|
||||
item,
|
||||
generics,
|
||||
ty,
|
||||
None,
|
||||
link,
|
||||
if parent == ItemType::Trait { 4 } else { 0 },
|
||||
cx,
|
||||
),
|
||||
clean::AssocConstItem(ci) => assoc_const(
|
||||
w,
|
||||
item,
|
||||
&ci.generics,
|
||||
&ci.type_,
|
||||
Some(&ci.kind),
|
||||
link,
|
||||
if parent == ItemType::Trait { 4 } else { 0 },
|
||||
cx,
|
||||
),
|
||||
clean::TyAssocTypeItem(ref generics, ref bounds) => assoc_type(
|
||||
w,
|
||||
item,
|
||||
|
|
@ -1381,21 +1372,20 @@ fn render_deref_methods(
|
|||
|
||||
fn should_render_item(item: &clean::Item, deref_mut_: bool, tcx: TyCtxt<'_>) -> bool {
|
||||
let self_type_opt = match *item.kind {
|
||||
clean::MethodItem(ref method, _) => method.decl.self_type(),
|
||||
clean::TyMethodItem(ref method) => method.decl.self_type(),
|
||||
clean::MethodItem(ref method, _) => method.decl.receiver_type(),
|
||||
clean::TyMethodItem(ref method) => method.decl.receiver_type(),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
if let Some(self_ty) = self_type_opt {
|
||||
let (by_mut_ref, by_box, by_value) = match self_ty {
|
||||
SelfTy::SelfBorrowed(_, mutability)
|
||||
| SelfTy::SelfExplicit(clean::BorrowedRef { mutability, .. }) => {
|
||||
let (by_mut_ref, by_box, by_value) = match *self_ty {
|
||||
clean::Type::BorrowedRef { mutability, .. } => {
|
||||
(mutability == Mutability::Mut, false, false)
|
||||
}
|
||||
SelfTy::SelfExplicit(clean::Type::Path { path }) => {
|
||||
clean::Type::Path { ref path } => {
|
||||
(false, Some(path.def_id()) == tcx.lang_items().owned_box(), false)
|
||||
}
|
||||
SelfTy::SelfValue => (false, false, true),
|
||||
clean::Type::SelfTy => (false, false, true),
|
||||
_ => (false, false, false),
|
||||
};
|
||||
|
||||
|
|
@ -1690,8 +1680,7 @@ fn render_impl(
|
|||
w.write_str("</h4></section>");
|
||||
}
|
||||
}
|
||||
kind @ (clean::TyAssocConstItem(generics, ty)
|
||||
| clean::AssocConstItem(generics, ty, _)) => {
|
||||
clean::TyAssocConstItem(generics, ty) => {
|
||||
let source_id = format!("{item_type}.{name}");
|
||||
let id = cx.derive_id(&source_id);
|
||||
write!(w, "<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">");
|
||||
|
|
@ -1706,11 +1695,29 @@ fn render_impl(
|
|||
item,
|
||||
generics,
|
||||
ty,
|
||||
match kind {
|
||||
clean::TyAssocConstItem(..) => None,
|
||||
clean::AssocConstItem(.., default) => Some(default),
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None,
|
||||
link.anchor(if trait_.is_some() { &source_id } else { &id }),
|
||||
0,
|
||||
cx,
|
||||
);
|
||||
w.write_str("</h4></section>");
|
||||
}
|
||||
clean::AssocConstItem(ci) => {
|
||||
let source_id = format!("{item_type}.{name}");
|
||||
let id = cx.derive_id(&source_id);
|
||||
write!(w, "<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">");
|
||||
render_rightside(w, cx, item, render_mode);
|
||||
if trait_.is_some() {
|
||||
// Anchors are only used on trait impls.
|
||||
write!(w, "<a href=\"#{id}\" class=\"anchor\">§</a>");
|
||||
}
|
||||
w.write_str("<h4 class=\"code-header\">");
|
||||
assoc_const(
|
||||
w,
|
||||
item,
|
||||
&ci.generics,
|
||||
&ci.type_,
|
||||
Some(&ci.kind),
|
||||
link.anchor(if trait_.is_some() { &source_id } else { &id }),
|
||||
0,
|
||||
cx,
|
||||
|
|
@ -1773,20 +1780,23 @@ fn render_impl(
|
|||
|
||||
let mut impl_items = Buffer::empty_from(w);
|
||||
let mut default_impl_items = Buffer::empty_from(w);
|
||||
let impl_ = i.inner_impl();
|
||||
|
||||
for trait_item in &i.inner_impl().items {
|
||||
doc_impl_item(
|
||||
&mut default_impl_items,
|
||||
&mut impl_items,
|
||||
cx,
|
||||
trait_item,
|
||||
if trait_.is_some() { &i.impl_item } else { parent },
|
||||
link,
|
||||
render_mode,
|
||||
false,
|
||||
trait_,
|
||||
rendering_params,
|
||||
);
|
||||
if !impl_.is_negative_trait_impl() {
|
||||
for trait_item in &impl_.items {
|
||||
doc_impl_item(
|
||||
&mut default_impl_items,
|
||||
&mut impl_items,
|
||||
cx,
|
||||
trait_item,
|
||||
if trait_.is_some() { &i.impl_item } else { parent },
|
||||
link,
|
||||
render_mode,
|
||||
false,
|
||||
trait_,
|
||||
rendering_params,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn render_default_items(
|
||||
|
|
@ -1837,13 +1847,15 @@ fn render_impl(
|
|||
// We don't emit documentation for default items if they appear in the
|
||||
// Implementations on Foreign Types or Implementors sections.
|
||||
if rendering_params.show_default_items {
|
||||
if let Some(t) = trait_ {
|
||||
if let Some(t) = trait_
|
||||
&& !impl_.is_negative_trait_impl()
|
||||
{
|
||||
render_default_items(
|
||||
&mut default_impl_items,
|
||||
&mut impl_items,
|
||||
cx,
|
||||
t,
|
||||
i.inner_impl(),
|
||||
impl_,
|
||||
&i.impl_item,
|
||||
render_mode,
|
||||
rendering_params,
|
||||
|
|
@ -1875,7 +1887,7 @@ fn render_impl(
|
|||
}
|
||||
|
||||
if let Some(ref dox) = i.impl_item.opt_doc_value() {
|
||||
if trait_.is_none() && i.inner_impl().items.is_empty() {
|
||||
if trait_.is_none() && impl_.items.is_empty() {
|
||||
w.write_str(
|
||||
"<div class=\"item-info\">\
|
||||
<div class=\"stab empty-impl\">This impl block contains no items.</div>\
|
||||
|
|
@ -2160,7 +2172,6 @@ pub(crate) enum ItemSection {
|
|||
AssociatedConstants,
|
||||
ForeignTypes,
|
||||
Keywords,
|
||||
OpaqueTypes,
|
||||
AttributeMacros,
|
||||
DeriveMacros,
|
||||
TraitAliases,
|
||||
|
|
@ -2193,7 +2204,6 @@ impl ItemSection {
|
|||
AssociatedConstants,
|
||||
ForeignTypes,
|
||||
Keywords,
|
||||
OpaqueTypes,
|
||||
AttributeMacros,
|
||||
DeriveMacros,
|
||||
TraitAliases,
|
||||
|
|
@ -2223,7 +2233,6 @@ impl ItemSection {
|
|||
Self::AssociatedConstants => "associated-consts",
|
||||
Self::ForeignTypes => "foreign-types",
|
||||
Self::Keywords => "keywords",
|
||||
Self::OpaqueTypes => "opaque-types",
|
||||
Self::AttributeMacros => "attributes",
|
||||
Self::DeriveMacros => "derives",
|
||||
Self::TraitAliases => "trait-aliases",
|
||||
|
|
@ -2253,7 +2262,6 @@ impl ItemSection {
|
|||
Self::AssociatedConstants => "Associated Constants",
|
||||
Self::ForeignTypes => "Foreign Types",
|
||||
Self::Keywords => "Keywords",
|
||||
Self::OpaqueTypes => "Opaque Types",
|
||||
Self::AttributeMacros => "Attribute Macros",
|
||||
Self::DeriveMacros => "Derive Macros",
|
||||
Self::TraitAliases => "Trait Aliases",
|
||||
|
|
@ -2284,7 +2292,6 @@ fn item_ty_to_section(ty: ItemType) -> ItemSection {
|
|||
ItemType::AssocConst => ItemSection::AssociatedConstants,
|
||||
ItemType::ForeignType => ItemSection::ForeignTypes,
|
||||
ItemType::Keyword => ItemSection::Keywords,
|
||||
ItemType::OpaqueTy => ItemSection::OpaqueTypes,
|
||||
ItemType::ProcAttribute => ItemSection::AttributeMacros,
|
||||
ItemType::ProcDerive => ItemSection::DeriveMacros,
|
||||
ItemType::TraitAlias => ItemSection::TraitAliases,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,10 @@
|
|||
use std::cell::{RefCell, RefMut};
|
||||
use std::cmp::Ordering;
|
||||
use std::fmt;
|
||||
use std::rc::Rc;
|
||||
|
||||
use itertools::Itertools;
|
||||
use rinja::Template;
|
||||
use rustc_data_structures::captures::Captures;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_hir as hir;
|
||||
|
|
@ -8,10 +15,6 @@ use rustc_middle::ty::{self, TyCtxt};
|
|||
use rustc_span::hygiene::MacroKind;
|
||||
use rustc_span::symbol::{kw, sym, Symbol};
|
||||
use rustc_target::abi::VariantIdx;
|
||||
use std::cell::{RefCell, RefMut};
|
||||
use std::cmp::Ordering;
|
||||
use std::fmt;
|
||||
use std::rc::Rc;
|
||||
|
||||
use super::type_layout::document_type_layout;
|
||||
use super::{
|
||||
|
|
@ -26,7 +29,7 @@ use crate::clean;
|
|||
use crate::config::ModuleSorting;
|
||||
use crate::formats::item_type::ItemType;
|
||||
use crate::formats::Impl;
|
||||
use crate::html::escape::Escape;
|
||||
use crate::html::escape::{Escape, EscapeBodyTextWithWbr};
|
||||
use crate::html::format::{
|
||||
display_fn, join_with_double_colon, print_abi_with_space, print_constness_with_space,
|
||||
print_where_clause, visibility_print_with_space, Buffer, Ending, PrintWithSpace,
|
||||
|
|
@ -36,9 +39,6 @@ use crate::html::markdown::{HeadingOffset, MarkdownSummaryLine};
|
|||
use crate::html::render::{document_full, document_item_info};
|
||||
use crate::html::url_parts_builder::UrlPartsBuilder;
|
||||
|
||||
use itertools::Itertools;
|
||||
use rinja::Template;
|
||||
|
||||
/// Generates a Rinja template struct for rendering items with common methods.
|
||||
///
|
||||
/// Usage:
|
||||
|
|
@ -202,7 +202,6 @@ pub(super) fn print_item(cx: &mut Context<'_>, item: &clean::Item, buf: &mut Buf
|
|||
clean::ConstantItem(..) => "Constant ",
|
||||
clean::ForeignTypeItem => "Foreign Type ",
|
||||
clean::KeywordItem => "Keyword ",
|
||||
clean::OpaqueTyItem(..) => "Opaque Type ",
|
||||
clean::TraitAliasItem(..) => "Trait Alias ",
|
||||
_ => {
|
||||
// We don't generate pages for any other type.
|
||||
|
|
@ -267,10 +266,9 @@ pub(super) fn print_item(cx: &mut Context<'_>, item: &clean::Item, buf: &mut Buf
|
|||
clean::PrimitiveItem(_) => item_primitive(buf, cx, item),
|
||||
clean::StaticItem(ref i) => item_static(buf, cx, item, i, None),
|
||||
clean::ForeignStaticItem(ref i, safety) => item_static(buf, cx, item, i, Some(*safety)),
|
||||
clean::ConstantItem(generics, ty, c) => item_constant(buf, cx, item, generics, ty, c),
|
||||
clean::ConstantItem(ci) => item_constant(buf, cx, item, &ci.generics, &ci.type_, &ci.kind),
|
||||
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),
|
||||
clean::TraitAliasItem(ref ta) => item_trait_alias(buf, cx, item, ta),
|
||||
_ => {
|
||||
// We don't generate pages for any other type.
|
||||
|
|
@ -423,7 +421,7 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items:
|
|||
"<div class=\"item-name\"><code>{}extern crate {} as {};",
|
||||
visibility_print_with_space(myitem, cx),
|
||||
anchor(myitem.item_id.expect_def_id(), src, cx),
|
||||
myitem.name.unwrap(),
|
||||
EscapeBodyTextWithWbr(myitem.name.unwrap().as_str()),
|
||||
),
|
||||
None => write!(
|
||||
w,
|
||||
|
|
@ -520,7 +518,7 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items:
|
|||
{stab_tags}\
|
||||
</div>\
|
||||
{docs_before}{docs}{docs_after}",
|
||||
name = myitem.name.unwrap(),
|
||||
name = EscapeBodyTextWithWbr(myitem.name.unwrap().as_str()),
|
||||
visibility_and_hidden = visibility_and_hidden,
|
||||
stab_tags = extra_info_tags(myitem, item, tcx),
|
||||
class = myitem.type_(),
|
||||
|
|
@ -558,7 +556,7 @@ fn extra_info_tags<'a, 'tcx: 'a>(
|
|||
display_fn(move |f| {
|
||||
write!(
|
||||
f,
|
||||
r#"<span class="stab {class}" title="{title}">{contents}</span>"#,
|
||||
r#"<wbr><span class="stab {class}" title="{title}">{contents}</span>"#,
|
||||
title = Escape(title),
|
||||
)
|
||||
})
|
||||
|
|
@ -1197,35 +1195,6 @@ fn item_trait_alias(
|
|||
.unwrap();
|
||||
}
|
||||
|
||||
fn item_opaque_ty(
|
||||
w: &mut impl fmt::Write,
|
||||
cx: &mut Context<'_>,
|
||||
it: &clean::Item,
|
||||
t: &clean::OpaqueTy,
|
||||
) {
|
||||
wrap_item(w, |w| {
|
||||
write!(
|
||||
w,
|
||||
"{attrs}type {name}{generics}{where_clause} = impl {bounds};",
|
||||
attrs = render_attributes_in_pre(it, "", cx),
|
||||
name = it.name.unwrap(),
|
||||
generics = t.generics.print(cx),
|
||||
where_clause = print_where_clause(&t.generics, cx, 0, Ending::Newline),
|
||||
bounds = bounds(&t.bounds, false, cx),
|
||||
)
|
||||
.unwrap();
|
||||
});
|
||||
|
||||
write!(w, "{}", document(cx, it, None, HeadingOffset::H2)).unwrap();
|
||||
|
||||
// Render any items associated directly to this alias, as otherwise they
|
||||
// won't be visible anywhere in the docs. It would be nice to also show
|
||||
// associated items from the aliased type (see discussion in #32077), but
|
||||
// we need #14072 to make sense of the generics.
|
||||
write!(w, "{}", render_assoc_items(cx, it, it.item_id.expect_def_id(), AssocItemRender::All))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
fn item_type_alias(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean::TypeAlias) {
|
||||
wrap_item(w, |w| {
|
||||
write!(
|
||||
|
|
@ -1841,7 +1810,7 @@ fn item_constant(
|
|||
it: &clean::Item,
|
||||
generics: &clean::Generics,
|
||||
ty: &clean::Type,
|
||||
c: &clean::Constant,
|
||||
c: &clean::ConstantKind,
|
||||
) {
|
||||
wrap_item(w, |w| {
|
||||
let tcx = cx.tcx();
|
||||
|
|
@ -1911,7 +1880,7 @@ fn item_fields(
|
|||
w: &mut Buffer,
|
||||
cx: &mut Context<'_>,
|
||||
it: &clean::Item,
|
||||
fields: &Vec<clean::Item>,
|
||||
fields: &[clean::Item],
|
||||
ctor_kind: Option<CtorKind>,
|
||||
) {
|
||||
let mut fields = fields
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue