Merge from rustc
This commit is contained in:
commit
7d12e50f73
1778 changed files with 31621 additions and 19057 deletions
|
|
@ -1092,9 +1092,6 @@ class RustBuild(object):
|
|||
if not os.path.exists(cargo_dir):
|
||||
eprint('ERROR: vendoring required, but .cargo/config does not exist.')
|
||||
raise Exception("{} not found".format(cargo_dir))
|
||||
else:
|
||||
if os.path.exists(cargo_dir):
|
||||
shutil.rmtree(cargo_dir)
|
||||
|
||||
def parse_args(args):
|
||||
"""Parse the command line arguments that the python script needs."""
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ v("llvm-libunwind", "rust.llvm-libunwind", "use LLVM libunwind")
|
|||
o("optimize-llvm", "llvm.optimize", "build optimized LLVM")
|
||||
o("llvm-assertions", "llvm.assertions", "build LLVM with assertions")
|
||||
o("llvm-enzyme", "llvm.enzyme", "build LLVM with enzyme")
|
||||
o("llvm-offload", "llvm.offload", "build LLVM with gpu offload support")
|
||||
o("llvm-plugins", "llvm.plugins", "build LLVM with plugin interface")
|
||||
o("debug-assertions", "rust.debug-assertions", "build with debugging assertions")
|
||||
o("debug-assertions-std", "rust.debug-assertions-std", "build the standard library with debugging assertions")
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ use std::path::{Path, PathBuf};
|
|||
use std::process::Stdio;
|
||||
use std::{env, fs, str};
|
||||
|
||||
use build_helper::git::get_closest_merge_commit;
|
||||
use serde_derive::Deserialize;
|
||||
|
||||
use crate::core::build_steps::tool::SourceType;
|
||||
|
|
@ -27,7 +26,7 @@ use crate::core::builder::{
|
|||
use crate::core::config::{DebuginfoLevel, LlvmLibunwind, RustcLto, TargetSelection};
|
||||
use crate::utils::exec::command;
|
||||
use crate::utils::helpers::{
|
||||
self, exe, get_clang_cl_resource_dir, is_debug_info, is_dylib, symlink_dir, t, up_to_date,
|
||||
exe, get_clang_cl_resource_dir, is_debug_info, is_dylib, symlink_dir, t, up_to_date,
|
||||
};
|
||||
use crate::{CLang, Compiler, DependencyType, GitRepo, LLVM_TOOLS, Mode};
|
||||
|
||||
|
|
@ -125,23 +124,9 @@ impl Step for Std {
|
|||
// 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_commit(Some(&builder.src), &builder.config.git_config(), &[])
|
||||
.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
|
||||
};
|
||||
let force_recompile = builder.rust_info().is_managed_git_subrepository()
|
||||
&& builder.download_rustc()
|
||||
&& builder.config.last_modified_commit(&["library"], "download-rustc", true).is_none();
|
||||
|
||||
run.builder.ensure(Std {
|
||||
compiler: run.builder.compiler(run.builder.top_stage, run.build_triple()),
|
||||
|
|
|
|||
|
|
@ -170,7 +170,14 @@ impl<P: Step> Step for RustbookSrc<P> {
|
|||
builder.add_rustc_lib_path(compiler, &mut rustbook_cmd);
|
||||
}
|
||||
|
||||
rustbook_cmd.arg("build").arg(&src).arg("-d").arg(&out).run(builder);
|
||||
rustbook_cmd
|
||||
.arg("build")
|
||||
.arg(&src)
|
||||
.arg("-d")
|
||||
.arg(&out)
|
||||
.arg("--rust-root")
|
||||
.arg(&builder.src)
|
||||
.run(builder);
|
||||
|
||||
for lang in &self.languages {
|
||||
let out = out.join(lang);
|
||||
|
|
|
|||
|
|
@ -472,6 +472,21 @@ impl Step for Llvm {
|
|||
cfg.define("LLVM_ENABLE_PROJECTS", enabled_llvm_projects.join(";"));
|
||||
}
|
||||
|
||||
let mut enabled_llvm_runtimes = Vec::new();
|
||||
|
||||
if builder.config.llvm_offload {
|
||||
enabled_llvm_runtimes.push("offload");
|
||||
//FIXME(ZuseZ4): LLVM intends to drop the offload dependency on openmp.
|
||||
//Remove this line once they achieved it.
|
||||
enabled_llvm_runtimes.push("openmp");
|
||||
}
|
||||
|
||||
if !enabled_llvm_runtimes.is_empty() {
|
||||
enabled_llvm_runtimes.sort();
|
||||
enabled_llvm_runtimes.dedup();
|
||||
cfg.define("LLVM_ENABLE_RUNTIMES", enabled_llvm_runtimes.join(";"));
|
||||
}
|
||||
|
||||
if let Some(num_linkers) = builder.config.llvm_link_jobs {
|
||||
if num_linkers > 0 {
|
||||
cfg.define("LLVM_PARALLEL_LINK_JOBS", num_linkers.to_string());
|
||||
|
|
|
|||
|
|
@ -1734,13 +1734,15 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
|
|||
} else {
|
||||
// We need to properly build cargo using the suitable stage compiler.
|
||||
|
||||
// HACK: currently tool stages are off-by-one compared to compiler stages, i.e. if
|
||||
// you give `tool::Cargo` a stage 1 rustc, it will cause stage 2 rustc to be built
|
||||
// and produce a cargo built with stage 2 rustc. To fix this, we need to chop off
|
||||
// the compiler stage by 1 to align with expected `./x test run-make --stage N`
|
||||
// behavior, i.e. we need to pass `N - 1` compiler stage to cargo. See also Miri
|
||||
// which does a similar hack.
|
||||
let compiler = builder.compiler(builder.top_stage - 1, compiler.host);
|
||||
let compiler = builder.download_rustc().then_some(compiler).unwrap_or_else(||
|
||||
// HACK: currently tool stages are off-by-one compared to compiler stages, i.e. if
|
||||
// you give `tool::Cargo` a stage 1 rustc, it will cause stage 2 rustc to be built
|
||||
// and produce a cargo built with stage 2 rustc. To fix this, we need to chop off
|
||||
// the compiler stage by 1 to align with expected `./x test run-make --stage N`
|
||||
// behavior, i.e. we need to pass `N - 1` compiler stage to cargo. See also Miri
|
||||
// which does a similar hack.
|
||||
builder.compiler(builder.top_stage - 1, compiler.host));
|
||||
|
||||
builder.ensure(tool::Cargo { compiler, target: compiler.host })
|
||||
};
|
||||
|
||||
|
|
@ -1834,6 +1836,9 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
|
|||
if builder.config.cmd.only_modified() {
|
||||
cmd.arg("--only-modified");
|
||||
}
|
||||
if let Some(compiletest_diff_tool) = &builder.config.compiletest_diff_tool {
|
||||
cmd.arg("--compiletest-diff-tool").arg(compiletest_diff_tool);
|
||||
}
|
||||
|
||||
let mut flags = if is_rustdoc { Vec::new() } else { vec!["-Crpath".to_string()] };
|
||||
flags.push(format!("-Cdebuginfo={}", builder.config.rust_debuginfo_level_tests));
|
||||
|
|
@ -3549,9 +3554,7 @@ impl Step for TestFloatParse {
|
|||
let path = self.path.to_str().unwrap();
|
||||
let crate_name = self.path.components().last().unwrap().as_os_str().to_str().unwrap();
|
||||
|
||||
if !builder.download_rustc() {
|
||||
builder.ensure(compile::Std::new(compiler, self.host));
|
||||
}
|
||||
builder.ensure(tool::TestFloatParse { host: self.host });
|
||||
|
||||
// Run any unit tests in the crate
|
||||
let cargo_test = tool::prepare_tool_cargo(
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
use std::path::PathBuf;
|
||||
use std::{env, fs};
|
||||
|
||||
use build_helper::git::get_closest_merge_commit;
|
||||
|
||||
use crate::core::build_steps::compile;
|
||||
use crate::core::build_steps::toolstate::ToolState;
|
||||
use crate::core::builder;
|
||||
|
|
@ -10,7 +8,7 @@ use crate::core::builder::{Builder, Cargo as CargoCommand, RunConfig, ShouldRun,
|
|||
use crate::core::config::TargetSelection;
|
||||
use crate::utils::channel::GitInfo;
|
||||
use crate::utils::exec::{BootstrapCommand, command};
|
||||
use crate::utils::helpers::{add_dylib_path, exe, git, t};
|
||||
use crate::utils::helpers::{add_dylib_path, exe, t};
|
||||
use crate::{Compiler, Kind, Mode, gha};
|
||||
|
||||
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
|
||||
|
|
@ -596,28 +594,11 @@ impl Step for Rustdoc {
|
|||
&& target_compiler.stage > 0
|
||||
&& builder.rust_info().is_managed_git_subrepository()
|
||||
{
|
||||
let commit = get_closest_merge_commit(
|
||||
Some(&builder.config.src),
|
||||
&builder.config.git_config(),
|
||||
&[],
|
||||
)
|
||||
.unwrap();
|
||||
let files_to_track = &["src/librustdoc", "src/tools/rustdoc"];
|
||||
|
||||
let librustdoc_src = builder.config.src.join("src/librustdoc");
|
||||
let rustdoc_src = builder.config.src.join("src/tools/rustdoc");
|
||||
|
||||
// FIXME: The change detection logic here is quite similar to `Config::download_ci_rustc_commit`.
|
||||
// It would be better to unify them.
|
||||
let has_changes = !git(Some(&builder.config.src))
|
||||
.allow_failure()
|
||||
.run_always()
|
||||
.args(["diff-index", "--quiet", &commit])
|
||||
.arg("--")
|
||||
.arg(librustdoc_src)
|
||||
.arg(rustdoc_src)
|
||||
.run(builder);
|
||||
|
||||
if !has_changes {
|
||||
// Check if unchanged
|
||||
if builder.config.last_modified_commit(files_to_track, "download-rustc", true).is_some()
|
||||
{
|
||||
let precompiled_rustdoc = builder
|
||||
.config
|
||||
.ci_rustc_dir()
|
||||
|
|
@ -1097,6 +1078,38 @@ tool_extended!((self, builder),
|
|||
Rustfmt, "src/tools/rustfmt", "rustfmt", stable=true, add_bins_to_sysroot = ["rustfmt", "cargo-fmt"];
|
||||
);
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct TestFloatParse {
|
||||
pub host: TargetSelection,
|
||||
}
|
||||
|
||||
impl Step for TestFloatParse {
|
||||
type Output = ();
|
||||
const ONLY_HOSTS: bool = true;
|
||||
const DEFAULT: bool = false;
|
||||
|
||||
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
|
||||
run.path("src/etc/test-float-parse")
|
||||
}
|
||||
|
||||
fn run(self, builder: &Builder<'_>) {
|
||||
let bootstrap_host = builder.config.build;
|
||||
let compiler = builder.compiler(builder.top_stage, bootstrap_host);
|
||||
|
||||
builder.ensure(ToolBuild {
|
||||
compiler,
|
||||
target: bootstrap_host,
|
||||
tool: "test-float-parse",
|
||||
mode: Mode::ToolStd,
|
||||
path: "src/etc/test-float-parse",
|
||||
source_type: SourceType::InTree,
|
||||
extra_features: Vec::new(),
|
||||
allow_features: "",
|
||||
cargo_args: Vec::new(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl Builder<'_> {
|
||||
/// Gets a `BootstrapCommand` which is ready to run `tool` in `stage` built for
|
||||
/// `host`.
|
||||
|
|
|
|||
|
|
@ -224,6 +224,7 @@ pub struct Config {
|
|||
pub llvm_assertions: bool,
|
||||
pub llvm_tests: bool,
|
||||
pub llvm_enzyme: bool,
|
||||
pub llvm_offload: bool,
|
||||
pub llvm_plugins: bool,
|
||||
pub llvm_optimize: bool,
|
||||
pub llvm_thin_lto: bool,
|
||||
|
|
@ -368,6 +369,9 @@ pub struct Config {
|
|||
/// The paths to work with. For example: with `./x check foo bar` we get
|
||||
/// `paths=["foo", "bar"]`.
|
||||
pub paths: Vec<PathBuf>,
|
||||
|
||||
/// Command for visual diff display, e.g. `diff-tool --color=always`.
|
||||
pub compiletest_diff_tool: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
|
|
@ -892,6 +896,7 @@ define_config! {
|
|||
android_ndk: Option<PathBuf> = "android-ndk",
|
||||
optimized_compiler_builtins: Option<bool> = "optimized-compiler-builtins",
|
||||
jobs: Option<u32> = "jobs",
|
||||
compiletest_diff_tool: Option<String> = "compiletest-diff-tool",
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -934,6 +939,7 @@ define_config! {
|
|||
use_libcxx: Option<bool> = "use-libcxx",
|
||||
use_linker: Option<String> = "use-linker",
|
||||
allow_old_toolchain: Option<bool> = "allow-old-toolchain",
|
||||
offload: Option<bool> = "offload",
|
||||
polly: Option<bool> = "polly",
|
||||
clang: Option<bool> = "clang",
|
||||
enable_warnings: Option<bool> = "enable-warnings",
|
||||
|
|
@ -1512,6 +1518,7 @@ impl Config {
|
|||
android_ndk,
|
||||
optimized_compiler_builtins,
|
||||
jobs,
|
||||
compiletest_diff_tool,
|
||||
} = toml.build.unwrap_or_default();
|
||||
|
||||
config.jobs = Some(threads_from_config(flags.jobs.unwrap_or(jobs.unwrap_or(0))));
|
||||
|
|
@ -1642,6 +1649,7 @@ impl Config {
|
|||
// we'll infer default values for them later
|
||||
let mut llvm_tests = None;
|
||||
let mut llvm_enzyme = None;
|
||||
let mut llvm_offload = None;
|
||||
let mut llvm_plugins = None;
|
||||
let mut debug = None;
|
||||
let mut debug_assertions = None;
|
||||
|
|
@ -1879,6 +1887,7 @@ impl Config {
|
|||
use_libcxx,
|
||||
use_linker,
|
||||
allow_old_toolchain,
|
||||
offload,
|
||||
polly,
|
||||
clang,
|
||||
enable_warnings,
|
||||
|
|
@ -1895,6 +1904,7 @@ impl Config {
|
|||
set(&mut config.ninja_in_file, ninja);
|
||||
llvm_tests = tests;
|
||||
llvm_enzyme = enzyme;
|
||||
llvm_offload = offload;
|
||||
llvm_plugins = plugins;
|
||||
set(&mut config.llvm_optimize, optimize_toml);
|
||||
set(&mut config.llvm_thin_lto, thin_lto);
|
||||
|
|
@ -1916,6 +1926,7 @@ impl Config {
|
|||
set(&mut config.llvm_use_libcxx, use_libcxx);
|
||||
config.llvm_use_linker.clone_from(&use_linker);
|
||||
config.llvm_allow_old_toolchain = allow_old_toolchain.unwrap_or(false);
|
||||
config.llvm_offload = offload.unwrap_or(false);
|
||||
config.llvm_polly = polly.unwrap_or(false);
|
||||
config.llvm_clang = clang.unwrap_or(false);
|
||||
config.llvm_enable_warnings = enable_warnings.unwrap_or(false);
|
||||
|
|
@ -2092,6 +2103,7 @@ impl Config {
|
|||
|
||||
config.llvm_tests = llvm_tests.unwrap_or(false);
|
||||
config.llvm_enzyme = llvm_enzyme.unwrap_or(false);
|
||||
config.llvm_offload = llvm_offload.unwrap_or(false);
|
||||
config.llvm_plugins = llvm_plugins.unwrap_or(false);
|
||||
config.rust_optimize = optimize.unwrap_or(RustOptimize::Bool(true));
|
||||
|
||||
|
|
@ -2158,6 +2170,7 @@ impl Config {
|
|||
config.rust_debuginfo_level_tests = debuginfo_level_tests.unwrap_or(DebuginfoLevel::None);
|
||||
config.optimized_compiler_builtins =
|
||||
optimized_compiler_builtins.unwrap_or(config.channel != "dev");
|
||||
config.compiletest_diff_tool = compiletest_diff_tool;
|
||||
|
||||
let download_rustc = config.download_rustc_commit.is_some();
|
||||
// See https://github.com/rust-lang/compiler-team/issues/326
|
||||
|
|
@ -2754,25 +2767,25 @@ impl Config {
|
|||
}
|
||||
};
|
||||
|
||||
let files_to_track = &[
|
||||
self.src.join("compiler"),
|
||||
self.src.join("library"),
|
||||
self.src.join("src/version"),
|
||||
self.src.join("src/stage0"),
|
||||
self.src.join("src/ci/channel"),
|
||||
];
|
||||
let files_to_track =
|
||||
&["compiler", "library", "src/version", "src/stage0", "src/ci/channel"];
|
||||
|
||||
// Look for a version to compare to based on the current commit.
|
||||
// Only commits merged by bors will have CI artifacts.
|
||||
let commit =
|
||||
get_closest_merge_commit(Some(&self.src), &self.git_config(), files_to_track).unwrap();
|
||||
if commit.is_empty() {
|
||||
println!("ERROR: could not find commit hash for downloading rustc");
|
||||
println!("HELP: maybe your repository history is too shallow?");
|
||||
println!("HELP: consider disabling `download-rustc`");
|
||||
println!("HELP: or fetch enough history to include one upstream commit");
|
||||
crate::exit!(1);
|
||||
}
|
||||
let commit = match self.last_modified_commit(files_to_track, "download-rustc", if_unchanged)
|
||||
{
|
||||
Some(commit) => commit,
|
||||
None => {
|
||||
if if_unchanged {
|
||||
return None;
|
||||
}
|
||||
println!("ERROR: could not find commit hash for downloading rustc");
|
||||
println!("HELP: maybe your repository history is too shallow?");
|
||||
println!("HELP: consider disabling `download-rustc`");
|
||||
println!("HELP: or fetch enough history to include one upstream commit");
|
||||
crate::exit!(1);
|
||||
}
|
||||
};
|
||||
|
||||
if CiEnv::is_ci() && {
|
||||
let head_sha =
|
||||
|
|
@ -2787,31 +2800,7 @@ impl Config {
|
|||
return None;
|
||||
}
|
||||
|
||||
// Warn if there were changes to the compiler or standard library since the ancestor commit.
|
||||
let has_changes = !t!(helpers::git(Some(&self.src))
|
||||
.args(["diff-index", "--quiet", &commit])
|
||||
.arg("--")
|
||||
.args(files_to_track)
|
||||
.as_command_mut()
|
||||
.status())
|
||||
.success();
|
||||
if has_changes {
|
||||
if if_unchanged {
|
||||
if self.is_verbose() {
|
||||
println!(
|
||||
"WARNING: saw changes to compiler/ or library/ since {commit}; \
|
||||
ignoring `download-rustc`"
|
||||
);
|
||||
}
|
||||
return None;
|
||||
}
|
||||
println!(
|
||||
"WARNING: `download-rustc` is enabled, but there are changes to \
|
||||
compiler/ or library/"
|
||||
);
|
||||
}
|
||||
|
||||
Some(commit.to_string())
|
||||
Some(commit)
|
||||
}
|
||||
|
||||
fn parse_download_ci_llvm(
|
||||
|
|
@ -2882,14 +2871,7 @@ impl Config {
|
|||
|
||||
// Warn if there were changes to the compiler or standard library since the ancestor commit.
|
||||
let mut git = helpers::git(Some(&self.src));
|
||||
git.args(["diff-index", "--quiet", &commit, "--"]);
|
||||
|
||||
// Handle running from a directory other than the top level
|
||||
let top_level = &self.src;
|
||||
|
||||
for path in modified_paths {
|
||||
git.arg(top_level.join(path));
|
||||
}
|
||||
git.args(["diff-index", "--quiet", &commit, "--"]).args(modified_paths);
|
||||
|
||||
let has_changes = !t!(git.as_command_mut().status()).success();
|
||||
if has_changes {
|
||||
|
|
@ -2981,6 +2963,7 @@ pub(crate) fn check_incompatible_options_for_ci_llvm(
|
|||
use_libcxx,
|
||||
use_linker,
|
||||
allow_old_toolchain,
|
||||
offload,
|
||||
polly,
|
||||
clang,
|
||||
enable_warnings,
|
||||
|
|
@ -3003,6 +2986,7 @@ pub(crate) fn check_incompatible_options_for_ci_llvm(
|
|||
err!(current_llvm_config.use_libcxx, use_libcxx);
|
||||
err!(current_llvm_config.use_linker, use_linker);
|
||||
err!(current_llvm_config.allow_old_toolchain, allow_old_toolchain);
|
||||
err!(current_llvm_config.offload, offload);
|
||||
err!(current_llvm_config.polly, polly);
|
||||
err!(current_llvm_config.clang, clang);
|
||||
err!(current_llvm_config.build_config, build_config);
|
||||
|
|
|
|||
|
|
@ -541,27 +541,32 @@ impl Build {
|
|||
}
|
||||
let output = helpers::git(Some(&self.src))
|
||||
.args(["config", "--file"])
|
||||
.arg(self.config.src.join(".gitmodules"))
|
||||
.arg(".gitmodules")
|
||||
.args(["--get-regexp", "path"])
|
||||
.run_capture(self)
|
||||
.stdout();
|
||||
for line in output.lines() {
|
||||
std::thread::scope(|s| {
|
||||
// Look for `submodule.$name.path = $path`
|
||||
// Sample output: `submodule.src/rust-installer.path src/tools/rust-installer`
|
||||
let submodule = line.split_once(' ').unwrap().1;
|
||||
self.update_existing_submodule(submodule);
|
||||
}
|
||||
for line in output.lines() {
|
||||
let submodule = line.split_once(' ').unwrap().1;
|
||||
let config = self.config.clone();
|
||||
s.spawn(move || {
|
||||
Self::update_existing_submodule(&config, submodule);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// Updates the given submodule only if it's initialized already; nothing happens otherwise.
|
||||
pub fn update_existing_submodule(&self, submodule: &str) {
|
||||
pub fn update_existing_submodule(config: &Config, submodule: &str) {
|
||||
// Avoid running git when there isn't a git checkout.
|
||||
if !self.config.submodules() {
|
||||
if !config.submodules() {
|
||||
return;
|
||||
}
|
||||
|
||||
if GitInfo::new(false, Path::new(submodule)).is_managed_git_subrepository() {
|
||||
self.config.update_submodule(submodule);
|
||||
config.update_submodule(submodule);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -280,4 +280,14 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
|
|||
severity: ChangeSeverity::Info,
|
||||
summary: "Allow setting `--jobs` in config.toml with `build.jobs`.",
|
||||
},
|
||||
ChangeInfo {
|
||||
change_id: 131181,
|
||||
severity: ChangeSeverity::Info,
|
||||
summary: "New option `build.compiletest-diff-tool` that adds support for a custom differ for compiletest",
|
||||
},
|
||||
ChangeInfo {
|
||||
change_id: 131513,
|
||||
severity: ChangeSeverity::Info,
|
||||
summary: "New option `llvm.offload` to control whether the llvm offload runtime for GPU support is built. Implicitly enables the openmp runtime as dependency.",
|
||||
},
|
||||
];
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ use std::path::Path;
|
|||
|
||||
use super::helpers;
|
||||
use crate::Build;
|
||||
use crate::utils::helpers::{output, t};
|
||||
use crate::utils::helpers::{start_process, t};
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
pub enum GitInfo {
|
||||
|
|
@ -56,7 +56,7 @@ impl GitInfo {
|
|||
}
|
||||
|
||||
// Ok, let's scrape some info
|
||||
let ver_date = output(
|
||||
let ver_date = start_process(
|
||||
helpers::git(Some(dir))
|
||||
.arg("log")
|
||||
.arg("-1")
|
||||
|
|
@ -65,14 +65,14 @@ impl GitInfo {
|
|||
.as_command_mut(),
|
||||
);
|
||||
let ver_hash =
|
||||
output(helpers::git(Some(dir)).arg("rev-parse").arg("HEAD").as_command_mut());
|
||||
let short_ver_hash = output(
|
||||
start_process(helpers::git(Some(dir)).arg("rev-parse").arg("HEAD").as_command_mut());
|
||||
let short_ver_hash = start_process(
|
||||
helpers::git(Some(dir)).arg("rev-parse").arg("--short=9").arg("HEAD").as_command_mut(),
|
||||
);
|
||||
GitInfo::Present(Some(Info {
|
||||
commit_date: ver_date.trim().to_string(),
|
||||
sha: ver_hash.trim().to_string(),
|
||||
short_sha: short_ver_hash.trim().to_string(),
|
||||
commit_date: ver_date().trim().to_string(),
|
||||
sha: ver_hash().trim().to_string(),
|
||||
short_sha: short_ver_hash().trim().to_string(),
|
||||
}))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -288,6 +288,33 @@ pub fn output(cmd: &mut Command) -> String {
|
|||
String::from_utf8(output.stdout).unwrap()
|
||||
}
|
||||
|
||||
/// Spawn a process and return a closure that will wait for the process
|
||||
/// to finish and then return its output. This allows the spawned process
|
||||
/// to do work without immediately blocking bootstrap.
|
||||
#[track_caller]
|
||||
pub fn start_process(cmd: &mut Command) -> impl FnOnce() -> String {
|
||||
let child = match cmd.stderr(Stdio::inherit()).stdout(Stdio::piped()).spawn() {
|
||||
Ok(child) => child,
|
||||
Err(e) => fail(&format!("failed to execute command: {cmd:?}\nERROR: {e}")),
|
||||
};
|
||||
|
||||
let command = format!("{:?}", cmd);
|
||||
|
||||
move || {
|
||||
let output = child.wait_with_output().unwrap();
|
||||
|
||||
if !output.status.success() {
|
||||
panic!(
|
||||
"command did not execute successfully: {}\n\
|
||||
expected success, got: {}",
|
||||
command, output.status
|
||||
);
|
||||
}
|
||||
|
||||
String::from_utf8(output.stdout).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the last-modified time for `path`, or zero if it doesn't exist.
|
||||
pub fn mtime(path: &Path) -> SystemTime {
|
||||
fs::metadata(path).and_then(|f| f.modified()).unwrap_or(UNIX_EPOCH)
|
||||
|
|
|
|||
58
src/ci/docker/host-aarch64/aarch64-gnu-debug/Dockerfile
Normal file
58
src/ci/docker/host-aarch64/aarch64-gnu-debug/Dockerfile
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
FROM ubuntu:22.04
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
g++ \
|
||||
make \
|
||||
ninja-build \
|
||||
file \
|
||||
curl \
|
||||
ca-certificates \
|
||||
python3 \
|
||||
python3-dev \
|
||||
libxml2-dev \
|
||||
libncurses-dev \
|
||||
libedit-dev \
|
||||
swig \
|
||||
doxygen \
|
||||
git \
|
||||
cmake \
|
||||
sudo \
|
||||
gdb \
|
||||
libssl-dev \
|
||||
pkg-config \
|
||||
xz-utils \
|
||||
lld \
|
||||
clang \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY scripts/sccache.sh /scripts/
|
||||
RUN sh /scripts/sccache.sh
|
||||
|
||||
ENV RUSTBUILD_FORCE_CLANG_BASED_TESTS 1
|
||||
ENV RUN_CHECK_WITH_PARALLEL_QUERIES 1
|
||||
|
||||
# llvm.use-linker conflicts with downloading CI LLVM
|
||||
ENV NO_DOWNLOAD_CI_LLVM 1
|
||||
|
||||
ENV RUST_CONFIGURE_ARGS \
|
||||
--build=aarch64-unknown-linux-gnu \
|
||||
--enable-debug \
|
||||
--enable-lld \
|
||||
--set llvm.use-linker=lld \
|
||||
--set target.aarch64-unknown-linux-gnu.linker=clang \
|
||||
--set target.aarch64-unknown-linux-gnu.cc=clang \
|
||||
--set target.aarch64-unknown-linux-gnu.cxx=clang++
|
||||
|
||||
# This job appears to be checking two separate things:
|
||||
# - That we can build the compiler with `--enable-debug`
|
||||
# (without necessarily testing the result).
|
||||
# - That the tests with `//@ needs-force-clang-based-tests` pass, since they
|
||||
# don't run by default unless RUSTBUILD_FORCE_CLANG_BASED_TESTS is set.
|
||||
# - FIXME(https://github.com/rust-lang/rust/pull/126155#issuecomment-2156314273):
|
||||
# Currently we only run the subset of tests with "clang" in their name.
|
||||
# - See also FIXME(#132034)
|
||||
|
||||
ENV SCRIPT \
|
||||
python3 ../x.py --stage 2 build && \
|
||||
python3 ../x.py --stage 2 test tests/run-make --test-args clang
|
||||
|
|
@ -56,9 +56,9 @@ ENV \
|
|||
CFLAGS_x86_64_fortanix_unknown_sgx="-D__ELF__ -isystem/usr/include/x86_64-linux-gnu -mlvi-hardening -mllvm -x86-experimental-lvi-inline-asm-hardening" \
|
||||
CXX_x86_64_fortanix_unknown_sgx=clang++-11 \
|
||||
CXXFLAGS_x86_64_fortanix_unknown_sgx="-D__ELF__ -isystem/usr/include/x86_64-linux-gnu -mlvi-hardening -mllvm -x86-experimental-lvi-inline-asm-hardening" \
|
||||
AR_i686_unknown_freebsd=i686-unknown-freebsd13-ar \
|
||||
CC_i686_unknown_freebsd=i686-unknown-freebsd13-clang \
|
||||
CXX_i686_unknown_freebsd=i686-unknown-freebsd13-clang++ \
|
||||
AR_i686_unknown_freebsd=i686-unknown-freebsd12-ar \
|
||||
CC_i686_unknown_freebsd=i686-unknown-freebsd12-clang \
|
||||
CXX_i686_unknown_freebsd=i686-unknown-freebsd12-clang++ \
|
||||
CC_aarch64_unknown_uefi=clang-11 \
|
||||
CXX_aarch64_unknown_uefi=clang++-11 \
|
||||
CC_i686_unknown_uefi=clang-11 \
|
||||
|
|
@ -118,6 +118,7 @@ ENV TARGETS=$TARGETS,wasm32-wasi
|
|||
ENV TARGETS=$TARGETS,wasm32-wasip1
|
||||
ENV TARGETS=$TARGETS,wasm32-wasip1-threads
|
||||
ENV TARGETS=$TARGETS,wasm32-wasip2
|
||||
ENV TARGETS=$TARGETS,wasm32v1-none
|
||||
ENV TARGETS=$TARGETS,sparcv9-sun-solaris
|
||||
ENV TARGETS=$TARGETS,x86_64-pc-solaris
|
||||
ENV TARGETS=$TARGETS,x86_64-unknown-linux-gnux32
|
||||
|
|
|
|||
|
|
@ -29,9 +29,9 @@ COPY scripts/cmake.sh /scripts/
|
|||
RUN /scripts/cmake.sh
|
||||
|
||||
ENV \
|
||||
AR_x86_64_unknown_freebsd=x86_64-unknown-freebsd13-ar \
|
||||
CC_x86_64_unknown_freebsd=x86_64-unknown-freebsd13-clang \
|
||||
CXX_x86_64_unknown_freebsd=x86_64-unknown-freebsd13-clang++
|
||||
AR_x86_64_unknown_freebsd=x86_64-unknown-freebsd12-ar \
|
||||
CC_x86_64_unknown_freebsd=x86_64-unknown-freebsd12-clang \
|
||||
CXX_x86_64_unknown_freebsd=x86_64-unknown-freebsd12-clang++
|
||||
|
||||
ENV HOSTS=x86_64-unknown-freebsd
|
||||
|
||||
|
|
|
|||
|
|
@ -51,7 +51,8 @@ ENV SCRIPT \
|
|||
/scripts/check-default-config-profiles.sh && \
|
||||
python3 ../x.py check --target=i686-pc-windows-gnu --host=i686-pc-windows-gnu && \
|
||||
python3 ../x.py clippy bootstrap -Dwarnings && \
|
||||
python3 ../x.py clippy compiler library -Aclippy::all -Dclippy::correctness && \
|
||||
python3 ../x.py clippy library -Aclippy::all -Dclippy::correctness && \
|
||||
python3 ../x.py clippy compiler -Aclippy::all -Dclippy::correctness -Dclippy::clone_on_ref_ptr && \
|
||||
python3 ../x.py build --stage 0 src/tools/build-manifest && \
|
||||
python3 ../x.py test --stage 0 src/tools/compiletest && \
|
||||
python3 ../x.py test --stage 0 core alloc std test proc_macro && \
|
||||
|
|
|
|||
|
|
@ -49,9 +49,7 @@ ENV RUST_CONFIGURE_ARGS \
|
|||
# (without necessarily testing the result).
|
||||
# - That the tests with `//@ needs-force-clang-based-tests` pass, since they
|
||||
# don't run by default unless RUSTBUILD_FORCE_CLANG_BASED_TESTS is set.
|
||||
# - FIXME(https://github.com/rust-lang/rust/pull/126155#issuecomment-2156314273):
|
||||
# Currently we only run the subset of tests with "clang" in their name.
|
||||
|
||||
ENV SCRIPT \
|
||||
python3 ../x.py --stage 2 build && \
|
||||
python3 ../x.py --stage 2 test tests/run-make --test-args clang
|
||||
python3 ../x.py --stage 2 test tests/run-make
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ set -eux
|
|||
|
||||
arch=$1
|
||||
binutils_version=2.40
|
||||
freebsd_version=13.2
|
||||
triple=$arch-unknown-freebsd13
|
||||
freebsd_version=12.3
|
||||
triple=$arch-unknown-freebsd12
|
||||
sysroot=/usr/local/$triple
|
||||
|
||||
hide_output() {
|
||||
|
|
@ -59,7 +59,7 @@ done
|
|||
|
||||
# Originally downloaded from:
|
||||
# URL=https://download.freebsd.org/ftp/releases/${freebsd_arch}/${freebsd_version}-RELEASE/base.txz
|
||||
URL=https://ci-mirrors.rust-lang.org/rustc/2024-02-18-freebsd-${freebsd_version}-${freebsd_arch}-base.txz
|
||||
URL=https://ci-mirrors.rust-lang.org/rustc/2022-05-06-freebsd-${freebsd_version}-${freebsd_arch}-base.txz
|
||||
curl "$URL" | tar xJf - -C "$sysroot" --wildcards "${files_to_extract[@]}"
|
||||
|
||||
# Clang can do cross-builds out of the box, if we give it the right
|
||||
|
|
@ -68,7 +68,7 @@ curl "$URL" | tar xJf - -C "$sysroot" --wildcards "${files_to_extract[@]}"
|
|||
# there might be other problems.)
|
||||
#
|
||||
# The --target option is last because the cross-build of LLVM uses
|
||||
# --target without an OS version ("-freebsd" vs. "-freebsd13"). This
|
||||
# --target without an OS version ("-freebsd" vs. "-freebsd12"). This
|
||||
# makes Clang default to libstdc++ (which no longer exists), and also
|
||||
# controls other features, like GNU-style symbol table hashing and
|
||||
# anything predicated on the version number in the __FreeBSD__
|
||||
|
|
|
|||
|
|
@ -287,7 +287,7 @@ class TestEnvironment:
|
|||
|
||||
@property
|
||||
def package_server_log_path(self) -> Path:
|
||||
return self.tmp_dir().joinpath("package_server_log")
|
||||
return self.tmp_dir().joinpath(f"repo_{self.TEST_REPO_NAME}.log")
|
||||
|
||||
@property
|
||||
def emulator_log_path(self) -> Path:
|
||||
|
|
@ -401,6 +401,7 @@ class TestEnvironment:
|
|||
# Set configs
|
||||
configs = {
|
||||
"log.enabled": "true",
|
||||
"log.dir": self.tmp_dir(),
|
||||
"test.is_isolated": "true",
|
||||
"test.experimental_structured_output": "true",
|
||||
}
|
||||
|
|
@ -575,43 +576,19 @@ class TestEnvironment:
|
|||
stderr_handler=self.subprocess_logger.debug,
|
||||
)
|
||||
|
||||
# Add repository
|
||||
check_call_with_logging(
|
||||
[
|
||||
ffx_path,
|
||||
"repository",
|
||||
"add-from-pm",
|
||||
"--repository",
|
||||
self.TEST_REPO_NAME,
|
||||
self.repo_dir(),
|
||||
],
|
||||
env=ffx_env,
|
||||
stdout_handler=self.subprocess_logger.debug,
|
||||
stderr_handler=self.subprocess_logger.debug,
|
||||
)
|
||||
|
||||
# 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,
|
||||
"repository",
|
||||
"server",
|
||||
"start",
|
||||
"--background",
|
||||
"--address",
|
||||
"[::]:0",
|
||||
"--repo-path",
|
||||
self.repo_dir(),
|
||||
"--repository",
|
||||
self.TEST_REPO_NAME
|
||||
],
|
||||
env=ffx_env,
|
||||
stdout_handler=self.subprocess_logger.debug,
|
||||
|
|
@ -1009,6 +986,21 @@ class TestEnvironment:
|
|||
stderr_handler=self.subprocess_logger.debug,
|
||||
)
|
||||
|
||||
# Stop the package server
|
||||
self.env_logger.info("Stopping package server...")
|
||||
check_call_with_logging(
|
||||
[
|
||||
self.tool_path("ffx"),
|
||||
"repository",
|
||||
"server",
|
||||
"stop",
|
||||
self.TEST_REPO_NAME
|
||||
],
|
||||
env=self.ffx_cmd_env(),
|
||||
stdout_handler=self.subprocess_logger.debug,
|
||||
stderr_handler=self.subprocess_logger.debug,
|
||||
)
|
||||
|
||||
# Stop ffx isolation
|
||||
self.env_logger.info("Stopping ffx isolation...")
|
||||
self.stop_ffx_isolation()
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
set -euo pipefail
|
||||
|
||||
LINUX_VERSION=v6.12-rc2
|
||||
LINUX_VERSION=28e848386b92645f93b9f2fdba5882c3ca7fb3e2
|
||||
|
||||
# Build rustc, rustdoc, cargo, clippy-driver and rustfmt
|
||||
../x.py build --stage 2 library rustdoc clippy rustfmt
|
||||
|
|
|
|||
|
|
@ -123,6 +123,9 @@ auto:
|
|||
- image: aarch64-gnu
|
||||
<<: *job-aarch64-linux
|
||||
|
||||
- image: aarch64-gnu-debug
|
||||
<<: *job-aarch64-linux
|
||||
|
||||
- image: arm-android
|
||||
<<: *job-linux-4c
|
||||
|
||||
|
|
@ -253,7 +256,9 @@ auto:
|
|||
<<: *job-linux-4c
|
||||
|
||||
- image: x86_64-gnu-debug
|
||||
<<: *job-linux-4c
|
||||
# This seems to be needed because a full stage 2 build + run-make tests
|
||||
# overwhelms the storage capacity of the standard 4c runner.
|
||||
<<: *job-linux-4c-largedisk
|
||||
|
||||
- image: x86_64-gnu-distcheck
|
||||
<<: *job-linux-8c
|
||||
|
|
|
|||
|
|
@ -47,11 +47,6 @@ source "$ci_dir/shared.sh"
|
|||
|
||||
export CARGO_REGISTRIES_CRATES_IO_PROTOCOL=sparse
|
||||
|
||||
# suppress change-tracker warnings on CI
|
||||
if [ "$CI" != "" ]; then
|
||||
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set change-id=99999999"
|
||||
fi
|
||||
|
||||
# If runner uses an incompatible option and `FORCE_CI_RUSTC` is not defined,
|
||||
# switch to in-tree rustc.
|
||||
if [ "$FORCE_CI_RUSTC" == "" ]; then
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit c7ebae25cb4801a31b6f05353f6d85bfa6feedd1
|
||||
Subproject commit 1f07c242f8162a711a5ac5a4ea8fa7ec884ee7a9
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit f40a8b420ec4b4505d9489965e261f1d5c28ba23
|
||||
Subproject commit ddbf1b4e2858fedb71b7c42eb15c4576517dc125
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit c64e52a3d306eac0129f3ad6c6d8806ab99ae2e9
|
||||
Subproject commit 23ce619966541bf2c80d45fdfeecf3393e360a13
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit 07bc9ca9eb1cd6d9fbbf758c2753b748804a134f
|
||||
Subproject commit 59d94ea75a0b157e148af14c73c2dd60efb7b60a
|
||||
|
|
@ -66,9 +66,10 @@
|
|||
- [powerpc-unknown-openbsd](platform-support/powerpc-unknown-openbsd.md)
|
||||
- [powerpc-unknown-linux-muslspe](platform-support/powerpc-unknown-linux-muslspe.md)
|
||||
- [powerpc64-ibm-aix](platform-support/aix.md)
|
||||
- [riscv32e*-unknown-none-elf](platform-support/riscv32e-unknown-none-elf.md)
|
||||
- [riscv32i*-unknown-none-elf](platform-support/riscv32-unknown-none-elf.md)
|
||||
- [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)
|
||||
|
|
@ -86,6 +87,7 @@
|
|||
- [wasm32-wasip2](platform-support/wasm32-wasip2.md)
|
||||
- [wasm32-unknown-emscripten](platform-support/wasm32-unknown-emscripten.md)
|
||||
- [wasm32-unknown-unknown](platform-support/wasm32-unknown-unknown.md)
|
||||
- [wasm32v1-none](platform-support/wasm32v1-none.md)
|
||||
- [wasm64-unknown-unknown](platform-support/wasm64-unknown-unknown.md)
|
||||
- [\*-win7-windows-msvc](platform-support/win7-windows-msvc.md)
|
||||
- [x86_64-fortanix-unknown-sgx](platform-support/x86_64-fortanix-unknown-sgx.md)
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ target | notes
|
|||
[`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 (version 13.2)
|
||||
`x86_64-unknown-freebsd` | 64-bit FreeBSD
|
||||
`x86_64-unknown-illumos` | illumos
|
||||
`x86_64-unknown-linux-musl` | 64-bit Linux with musl 1.2.3
|
||||
[`x86_64-unknown-netbsd`](platform-support/netbsd.md) | NetBSD/amd64
|
||||
|
|
@ -166,7 +166,7 @@ target | std | notes
|
|||
`i586-unknown-linux-musl` | ✓ | 32-bit Linux w/o SSE, musl 1.2.3 [^x86_32-floats-x87]
|
||||
[`i686-linux-android`](platform-support/android.md) | ✓ | 32-bit x86 Android [^x86_32-floats-return-ABI]
|
||||
[`i686-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | 32-bit x86 MinGW (Windows 10+), LLVM ABI [^x86_32-floats-return-ABI]
|
||||
`i686-unknown-freebsd` | ✓ | 32-bit FreeBSD (version 13.2) [^x86_32-floats-return-ABI]
|
||||
`i686-unknown-freebsd` | ✓ | 32-bit FreeBSD [^x86_32-floats-return-ABI]
|
||||
`i686-unknown-linux-musl` | ✓ | 32-bit Linux with musl 1.2.3 [^x86_32-floats-return-ABI]
|
||||
[`i686-unknown-uefi`](platform-support/unknown-uefi.md) | ? | 32-bit UEFI
|
||||
[`loongarch64-unknown-none`](platform-support/loongarch-none.md) | * | LoongArch64 Bare-metal (LP64D ABI)
|
||||
|
|
@ -195,6 +195,7 @@ target | std | notes
|
|||
`wasm32-wasi` | ✓ | WebAssembly with WASI (undergoing a [rename to `wasm32-wasip1`][wasi-rename])
|
||||
[`wasm32-wasip1`](platform-support/wasm32-wasip1.md) | ✓ | WebAssembly with WASI
|
||||
[`wasm32-wasip1-threads`](platform-support/wasm32-wasip1-threads.md) | ✓ | WebAssembly with WASI Preview 1 and threads
|
||||
[`wasm32v1-none`](platform-support/wasm32v1-none.md) | * | WebAssembly limited to 1.0 features and no imports
|
||||
[`x86_64-apple-ios`](platform-support/apple-ios.md) | ✓ | 64-bit x86 iOS
|
||||
[`x86_64-apple-ios-macabi`](platform-support/apple-ios-macabi.md) | ✓ | Mac Catalyst on x86_64
|
||||
[`x86_64-fortanix-unknown-sgx`](platform-support/x86_64-fortanix-unknown-sgx.md) | ✓ | [Fortanix ABI] for 64-bit Intel SGX
|
||||
|
|
@ -257,7 +258,7 @@ target | std | host | notes
|
|||
[`aarch64-unknown-teeos`](platform-support/aarch64-unknown-teeos.md) | ? | | ARM64 TEEOS |
|
||||
[`aarch64-unknown-nto-qnx700`](platform-support/nto-qnx.md) | ? | | ARM64 QNX Neutrino 7.0 RTOS |
|
||||
[`aarch64-unknown-nto-qnx710`](platform-support/nto-qnx.md) | ✓ | | ARM64 QNX Neutrino 7.1 RTOS |
|
||||
`aarch64-unknown-freebsd` | ✓ | ✓ | ARM64 FreeBSD (version 13.2)
|
||||
`aarch64-unknown-freebsd` | ✓ | ✓ | ARM64 FreeBSD
|
||||
[`aarch64-unknown-hermit`](platform-support/hermit.md) | ✓ | | ARM64 Hermit
|
||||
`aarch64-unknown-illumos` | ✓ | ✓ | ARM64 illumos
|
||||
`aarch64-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (ILP32 ABI)
|
||||
|
|
@ -276,14 +277,14 @@ target | std | host | notes
|
|||
`armv4t-unknown-linux-gnueabi` | ? | | Armv4T Linux
|
||||
[`armv5te-none-eabi`](platform-support/armv5te-none-eabi.md) | * | | Bare Armv5TE
|
||||
`armv5te-unknown-linux-uclibceabi` | ? | | Armv5TE Linux with uClibc
|
||||
`armv6-unknown-freebsd` | ✓ | ✓ | Armv6 FreeBSD (version 13.2)
|
||||
`armv6-unknown-freebsd` | ✓ | ✓ | Armv6 FreeBSD
|
||||
[`armv6-unknown-netbsd-eabihf`](platform-support/netbsd.md) | ✓ | ✓ | Armv6 NetBSD w/hard-float
|
||||
[`armv6k-nintendo-3ds`](platform-support/armv6k-nintendo-3ds.md) | ? | | Armv6k Nintendo 3DS, Horizon (Requires devkitARM toolchain)
|
||||
[`armv7-rtems-eabihf`](platform-support/armv7-rtems-eabihf.md) | ? | | RTEMS OS for ARM BSPs
|
||||
[`armv7-sony-vita-newlibeabihf`](platform-support/armv7-sony-vita-newlibeabihf.md) | ✓ | | Armv7-A Cortex-A9 Sony PlayStation Vita (requires VITASDK toolchain)
|
||||
[`armv7-unknown-linux-uclibceabi`](platform-support/armv7-unknown-linux-uclibceabi.md) | ✓ | ✓ | Armv7-A Linux with uClibc, softfloat
|
||||
[`armv7-unknown-linux-uclibceabihf`](platform-support/armv7-unknown-linux-uclibceabihf.md) | ✓ | ? | Armv7-A Linux with uClibc, hardfloat
|
||||
`armv7-unknown-freebsd` | ✓ | ✓ | Armv7-A FreeBSD (version 13.2)
|
||||
`armv7-unknown-freebsd` | ✓ | ✓ | Armv7-A FreeBSD
|
||||
[`armv7-unknown-netbsd-eabihf`](platform-support/netbsd.md) | ✓ | ✓ | Armv7-A NetBSD w/hard-float
|
||||
[`armv7-unknown-trusty`](platform-support/trusty.md) | ? | |
|
||||
[`armv7-wrs-vxworks-eabihf`](platform-support/vxworks.md) | ✓ | | Armv7-A for VxWorks
|
||||
|
|
@ -342,9 +343,9 @@ target | std | host | notes
|
|||
[`powerpc-unknown-openbsd`](platform-support/powerpc-unknown-openbsd.md) | * | |
|
||||
[`powerpc-wrs-vxworks-spe`](platform-support/vxworks.md) | ✓ | |
|
||||
[`powerpc-wrs-vxworks`](platform-support/vxworks.md) | ✓ | |
|
||||
`powerpc64-unknown-freebsd` | ✓ | ✓ | PPC64 FreeBSD (ELFv1 and ELFv2, version 13.2)
|
||||
`powerpc64le-unknown-freebsd` | | | PPC64LE FreeBSD (version 13.2)
|
||||
`powerpc-unknown-freebsd` | | | PowerPC FreeBSD (version 13.2)
|
||||
`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`](platform-support/vxworks.md) | ✓ | |
|
||||
`powerpc64le-unknown-linux-musl` | ? | | 64-bit PowerPC Linux with musl 1.2.3, Little Endian
|
||||
|
|
@ -360,7 +361,7 @@ target | std | host | notes
|
|||
[`riscv32imafc-esp-espidf`](platform-support/esp-idf.md) | ✓ | | RISC-V ESP-IDF
|
||||
[`riscv32-wrs-vxworks`](platform-support/vxworks.md) | ✓ | |
|
||||
[`riscv64gc-unknown-hermit`](platform-support/hermit.md) | ✓ | | RISC-V Hermit
|
||||
`riscv64gc-unknown-freebsd` | | | RISC-V FreeBSD (version 13.2)
|
||||
`riscv64gc-unknown-freebsd` | | | RISC-V FreeBSD
|
||||
`riscv64gc-unknown-fuchsia` | | | RISC-V Fuchsia
|
||||
[`riscv64gc-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | RISC-V NetBSD
|
||||
[`riscv64gc-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/riscv64
|
||||
|
|
@ -413,8 +414,8 @@ target | std | host | notes
|
|||
[`riscv32imafc-unknown-nuttx-elf`](platform-support/nuttx.md) | * | | RISC-V 32bit with NuttX
|
||||
[`riscv64imac-unknown-nuttx-elf`](platform-support/nuttx.md) | * | | RISC-V 64bit with NuttX
|
||||
[`riscv64gc-unknown-nuttx-elf`](platform-support/nuttx.md) | * | | RISC-V 64bit with NuttX
|
||||
[`riscv32e-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | | Bare RISC-V (RV32E ISA)
|
||||
[`riscv32em-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | | Bare RISC-V (RV32EM ISA)
|
||||
[`riscv32emc-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | | Bare RISC-V (RV32EMC ISA)
|
||||
[`riscv32e-unknown-none-elf`](platform-support/riscv32e-unknown-none-elf.md) | * | | Bare RISC-V (RV32E ISA)
|
||||
[`riscv32em-unknown-none-elf`](platform-support/riscv32e-unknown-none-elf.md) | * | | Bare RISC-V (RV32EM ISA)
|
||||
[`riscv32emc-unknown-none-elf`](platform-support/riscv32e-unknown-none-elf.md) | * | | Bare RISC-V (RV32EMC ISA)
|
||||
|
||||
[runs on NVIDIA GPUs]: https://github.com/japaric-archived/nvptx#targets
|
||||
|
|
|
|||
|
|
@ -525,14 +525,6 @@ ${SDK_PATH}/tools/${ARCH}/ffx repository publish \
|
|||
pkg/repo
|
||||
```
|
||||
|
||||
Then we can add the repository to `ffx`'s package server as `hello-fuchsia` using:
|
||||
|
||||
```sh
|
||||
${SDK_PATH}/tools/${ARCH}/ffx repository add-from-pm \
|
||||
--repository hello-fuchsia \
|
||||
pkg/repo
|
||||
```
|
||||
|
||||
## Running a Fuchsia component on an emulator
|
||||
|
||||
At this point, we are ready to run our Fuchsia
|
||||
|
|
@ -590,7 +582,8 @@ Now, start a package repository server to serve our
|
|||
package to the emulator:
|
||||
|
||||
```sh
|
||||
${SDK_PATH}/tools/${ARCH}/ffx repository server start
|
||||
${SDK_PATH}/tools/${ARCH}/ffx repository server start \
|
||||
--background --repository hello-fuchsia --repo-path pkg-repo
|
||||
```
|
||||
|
||||
Once the repository server is up and running, register it with the target Fuchsia system running in the emulator:
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ The following target names are defined:
|
|||
|
||||
## Building the target
|
||||
|
||||
The target can be built by enabled in the `rustc` build:
|
||||
The target can be built by enabling it in the `rustc` build:
|
||||
|
||||
```toml
|
||||
[build]
|
||||
|
|
|
|||
|
|
@ -132,10 +132,20 @@ As of the time of this writing the proposals that are enabled by default (the
|
|||
|
||||
If you're compiling WebAssembly code for an engine that does not support a
|
||||
feature in LLVM's default feature set then the feature must be disabled at
|
||||
compile time. Note, though, that enabled features may be used in the standard
|
||||
library or precompiled libraries shipped via rustup. This means that not only
|
||||
does your own code need to be compiled with the correct set of flags but the
|
||||
Rust standard library additionally must be recompiled.
|
||||
compile time. There are two approaches to choose from:
|
||||
|
||||
- If you are targeting a feature set no smaller than the W3C WebAssembly Core
|
||||
1.0 recommendation -- which is equivalent to the WebAssembly MVP plus the
|
||||
`mutable-globals` feature -- and you are building `no_std`, then you can
|
||||
simply use the [`wasm32v1-none` target](./wasm32v1-none.md) instead of
|
||||
`wasm32-unknown-unknown`, which uses only those minimal features and
|
||||
includes a core and alloc library built with only those minimal features.
|
||||
|
||||
- Otherwise -- if you need std, or if you need to target the ultra-minimal
|
||||
"MVP" feature set, excluding `mutable-globals` -- you will need to manually
|
||||
specify `-Ctarget-cpu=mvp` and also rebuild the stdlib using that target to
|
||||
ensure no features are used in the stdlib. This in turn requires use of a
|
||||
nightly compiler.
|
||||
|
||||
Compiling all code for the initial release of WebAssembly looks like:
|
||||
|
||||
|
|
@ -150,9 +160,9 @@ then used to recompile the standard library in addition to your own code. This
|
|||
will produce a binary that uses only the original WebAssembly features by
|
||||
default and no proposals since its inception.
|
||||
|
||||
To enable individual features it can be done with `-Ctarget-feature=+foo`.
|
||||
Available features for Rust code itself are documented in the [reference] and
|
||||
can also be found through:
|
||||
To enable individual features on either this target or `wasm32v1-none`, pass
|
||||
arguments of the form `-Ctarget-feature=+foo`. Available features for Rust code
|
||||
itself are documented in the [reference] and can also be found through:
|
||||
|
||||
```sh
|
||||
$ rustc -Ctarget-feature=help --target wasm32-unknown-unknown
|
||||
|
|
|
|||
109
src/doc/rustc/src/platform-support/wasm32v1-none.md
Normal file
109
src/doc/rustc/src/platform-support/wasm32v1-none.md
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
# `wasm32v1-none`
|
||||
|
||||
**Tier: 2**
|
||||
|
||||
The `wasm32v1-none` target is a WebAssembly compilation target that:
|
||||
|
||||
- Imports nothing from its host environment
|
||||
- Enables no proposals / features past the [W3C WebAssembly Core 1.0 spec]
|
||||
|
||||
[W3C WebAssembly Core 1.0 spec]: https://www.w3.org/TR/wasm-core-1/
|
||||
|
||||
The target is very similar to [`wasm32-unknown-unknown`](./wasm32-unknown-unknown.md) and similarly uses LLVM's `wasm32-unknown-unknown` backend target. It contains only three minor differences:
|
||||
|
||||
* Setting the `target-cpu` to `mvp` rather than the default `generic`. Requesting `mvp` disables _all_ WebAssembly proposals / LLVM target feature flags.
|
||||
* Enabling the [Import/Export of Mutable Globals] proposal (i.e. the `+mutable-globals` LLVM target feature flag)
|
||||
* Not compiling the `std` library at all, rather than compiling it with stubs.
|
||||
|
||||
[Import/Export of Mutable Globals]: https://github.com/WebAssembly/mutable-global
|
||||
|
||||
## Target maintainers
|
||||
|
||||
- Alex Crichton, https://github.com/alexcrichton
|
||||
- Graydon Hoare, https://github.com/graydon
|
||||
|
||||
## Requirements
|
||||
|
||||
This target is cross-compiled. It does not support `std`, only `core` and `alloc`. Since it imports nothing from its environment, any `std` parts that use OS facilities would be stubbed out with functions-that-fail anyways, and the experience of working with the stub `std` in the `wasm32-unknown-unknown` target was deemed not something worth repeating here.
|
||||
|
||||
Everything else about this target's requirements, building, usage and testing is the same as what's described in the [`wasm32-unknown-unknown` document](./wasm32-unknown-unknown.md), just using the target string `wasm32v1-none` in place of `wasm32-unknown-unknown`.
|
||||
|
||||
## Conditionally compiling code
|
||||
|
||||
It's recommended to conditionally compile code for this target with:
|
||||
|
||||
```text
|
||||
#[cfg(all(target_family = "wasm", target_os = "none"))]
|
||||
```
|
||||
|
||||
Note that there is no way to tell via `#[cfg]` whether code will be running on
|
||||
the web or not.
|
||||
|
||||
## Enabled WebAssembly features
|
||||
|
||||
As noted above, _no WebAssembly proposals past 1.0_ are enabled on this target by default. Indeed, the entire point of this target is to have a way to compile for a stable "no post-1.0 proposals" subset of WebAssembly _on stable Rust_.
|
||||
|
||||
The [W3C WebAssembly Core 1.0 spec] was adopted as a W3C recommendation in December 2019, and includes exactly one "post-MVP" proposal: the [Import/Export of Mutable Globals] proposal.
|
||||
|
||||
All subsequent proposals are _disabled_ on this target by default, though they can be individually enabled by passing LLVM target-feature flags.
|
||||
|
||||
For reference sake, the set of proposals that LLVM supports at the time of writing, that this target _does not enable by default_, are listed here along with their LLVM target-feature flags:
|
||||
|
||||
* Post-1.0 proposals (integrated into the WebAssembly core 2.0 spec):
|
||||
* [Bulk memory] - `+bulk-memory`
|
||||
* [Sign-extending operations] - `+sign-ext`
|
||||
* [Non-trapping fp-to-int operations] - `+nontrapping-fptoint`
|
||||
* [Multi-value] - `+multivalue`
|
||||
* [Reference Types] - `+reference-types`
|
||||
* [Fixed-width SIMD] - `+simd128`
|
||||
* Post-2.0 proposals:
|
||||
* [Threads] (supported by atomics) - `+atomics`
|
||||
* [Exception handling] - `+exception-handling`
|
||||
* [Extended Constant Expressions] - `+extended-const`
|
||||
* [Half Precision] - `+half-precision`
|
||||
* [Multiple memories]- `+multimemory`
|
||||
* [Relaxed SIMD] - `+relaxed-simd`
|
||||
* [Tail call] - `+tail-call`
|
||||
|
||||
[Bulk memory]: https://github.com/WebAssembly/spec/blob/main/proposals/bulk-memory-operations/Overview.md
|
||||
[Sign-extending operations]: https://github.com/WebAssembly/spec/blob/main/proposals/sign-extension-ops/Overview.md
|
||||
[Non-trapping fp-to-int operations]: https://github.com/WebAssembly/spec/blob/main/proposals/nontrapping-float-to-int-conversion/Overview.md
|
||||
[Multi-value]: https://github.com/WebAssembly/spec/blob/main/proposals/multi-value/Overview.md
|
||||
[Reference Types]: https://github.com/WebAssembly/spec/blob/main/proposals/reference-types/Overview.md
|
||||
[Fixed-width SIMD]: https://github.com/WebAssembly/spec/blob/main/proposals/simd/SIMD.md
|
||||
[Threads]: https://github.com/webassembly/threads
|
||||
[Exception handling]: https://github.com/WebAssembly/exception-handling
|
||||
[Extended Constant Expressions]: https://github.com/WebAssembly/extended-const
|
||||
[Half Precision]: https://github.com/WebAssembly/half-precision
|
||||
[Multiple memories]: https://github.com/WebAssembly/multi-memory
|
||||
[Relaxed SIMD]: https://github.com/WebAssembly/relaxed-simd
|
||||
[Tail call]: https://github.com/WebAssembly/tail-call
|
||||
|
||||
Additional proposals in the future are, of course, also not enabled by default.
|
||||
|
||||
## Rationale relative to wasm32-unknown-unknown
|
||||
|
||||
As noted in the [`wasm32-unknown-unknown` document](./wasm32-unknown-unknown.md), it is possible to compile with `--target wasm32-unknown-unknown` and disable all WebAssembly proposals "by hand", by passing `-Ctarget-cpu=mvp`. Furthermore one can enable proposals one by one by passing LLVM target feature flags, such as `-Ctarget-feature=+mutable-globals`.
|
||||
|
||||
Is it therefore reasonable to wonder what the difference is between building with this:
|
||||
|
||||
```sh
|
||||
$ rustc --target wasm32-unknown-unknown -Ctarget-cpu=mvp -Ctarget-feature=+mutable-globals
|
||||
```
|
||||
|
||||
and building with this:
|
||||
|
||||
```sh
|
||||
$ rustc --target wasm32v1-none
|
||||
```
|
||||
|
||||
The difference is in how the `core` and `alloc` crates are compiled for distribution with the toolchain, and whether it works on _stable_ Rust toolchains or requires _nightly_ ones. Again referring back to the [`wasm32-unknown-unknown` document](./wasm32-unknown-unknown.md), note that to disable all post-MVP proposals on that target one _actually_ has to compile with this:
|
||||
|
||||
```sh
|
||||
$ export RUSTFLAGS="-Ctarget-cpu=mvp -Ctarget-feature=+mutable-globals"
|
||||
$ cargo +nightly build -Zbuild-std=panic_abort,std --target wasm32-unknown-unknown
|
||||
```
|
||||
|
||||
Which not only rebuilds `std`, `core` and `alloc` (which is somewhat costly and annoying) but more importantly requires the use of nightly Rust toolchains (for the `-Zbuild-std` flag). This is very undesirable for the target audience, which consists of people targeting WebAssembly implementations that prioritize stability, simplicity and/or security over feature support.
|
||||
|
||||
This `wasm32v1-none` target exists as an alternative option that works on stable Rust toolchains, without rebuilding the stdlib.
|
||||
|
|
@ -1208,7 +1208,7 @@ The compiler has some latitude in how an entity is encoded as long as the symbol
|
|||
|
||||
* Named functions, methods, and statics shall be represented by a *[path]* production.
|
||||
|
||||
* Paths should be rooted at the inner-most entity that can act as a path root.
|
||||
* Paths should be rooted at the innermost entity that can act as a path root.
|
||||
Roots can be crate-ids, inherent impls, trait impls, and (for items within default methods) trait definitions.
|
||||
|
||||
* The compiler is free to choose disambiguation indices and namespace tags from
|
||||
|
|
|
|||
20
src/doc/unstable-book/src/compiler-flags/regparm.md
Normal file
20
src/doc/unstable-book/src/compiler-flags/regparm.md
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
# `regparm`
|
||||
|
||||
The tracking issue for this feature is: https://github.com/rust-lang/rust/issues/131749.
|
||||
|
||||
------------------------
|
||||
|
||||
Option -Zregparm=N causes the compiler to pass N arguments
|
||||
in registers EAX, EDX, and ECX instead of on the stack for "C", "cdecl", and "stdcall" fn.
|
||||
It is UNSOUND to link together crates that use different values for this flag.
|
||||
It is only supported on `x86`.
|
||||
|
||||
It is equivalent to [Clang]'s and [GCC]'s `-mregparm`.
|
||||
|
||||
Supported values for this option are 0-3.
|
||||
|
||||
[Clang]: https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-mregparm
|
||||
[GCC]: https://gcc.gnu.org/onlinedocs/gcc/x86-Function-Attributes.html#index-regparm-function-attribute_002c-x86
|
||||
|
||||
Implementation details:
|
||||
For eligible arguments, llvm `inreg` attribute is set.
|
||||
|
|
@ -690,7 +690,6 @@ LeakSanitizer is run-time memory leak detector.
|
|||
|
||||
LeakSanitizer is supported on the following targets:
|
||||
|
||||
* `aarch64-apple-darwin`
|
||||
* `aarch64-unknown-linux-gnu`
|
||||
* `x86_64-apple-darwin`
|
||||
* `x86_64-unknown-linux-gnu`
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ while getopts ':vieh' OPTION; do
|
|||
case "$OPTION" in
|
||||
v)
|
||||
INVERT=1
|
||||
ERROR_MSG='should not be found'
|
||||
;;
|
||||
i)
|
||||
GREPFLAGS="i$GREPFLAGS"
|
||||
|
|
|
|||
|
|
@ -250,7 +250,7 @@ def get_known_directive_names():
|
|||
os.path.join(
|
||||
# We go back to `src`.
|
||||
os.path.dirname(os.path.dirname(__file__)),
|
||||
"tools/compiletest/src/command-list.rs",
|
||||
"tools/compiletest/src/directive-list.rs",
|
||||
),
|
||||
"r",
|
||||
encoding="utf8"
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
name = "rustdoc"
|
||||
version = "0.0.0"
|
||||
edition = "2021"
|
||||
build = "build.rs"
|
||||
|
||||
[lib]
|
||||
path = "lib.rs"
|
||||
|
|
@ -24,13 +25,15 @@ tracing = "0.1"
|
|||
tracing-tree = "0.3.0"
|
||||
threadpool = "1.8.1"
|
||||
unicode-segmentation = "1.9"
|
||||
sha2 = "0.10.8"
|
||||
|
||||
[dependencies.tracing-subscriber]
|
||||
version = "0.3.3"
|
||||
default-features = false
|
||||
features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"]
|
||||
|
||||
[build-dependencies]
|
||||
sha2 = "0.10.8"
|
||||
|
||||
[dev-dependencies]
|
||||
expect-test = "1.4.0"
|
||||
|
||||
|
|
|
|||
48
src/librustdoc/build.rs
Normal file
48
src/librustdoc/build.rs
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
fn main() {
|
||||
// generate sha256 files
|
||||
// this avoids having to perform hashing at runtime
|
||||
let files = &[
|
||||
"static/css/rustdoc.css",
|
||||
"static/css/noscript.css",
|
||||
"static/css/normalize.css",
|
||||
"static/js/main.js",
|
||||
"static/js/search.js",
|
||||
"static/js/settings.js",
|
||||
"static/js/src-script.js",
|
||||
"static/js/storage.js",
|
||||
"static/js/scrape-examples.js",
|
||||
"static/COPYRIGHT.txt",
|
||||
"static/LICENSE-APACHE.txt",
|
||||
"static/LICENSE-MIT.txt",
|
||||
"static/images/rust-logo.svg",
|
||||
"static/images/favicon.svg",
|
||||
"static/images/favicon-32x32.png",
|
||||
"static/fonts/FiraSans-Regular.woff2",
|
||||
"static/fonts/FiraSans-Medium.woff2",
|
||||
"static/fonts/FiraSans-LICENSE.txt",
|
||||
"static/fonts/SourceSerif4-Regular.ttf.woff2",
|
||||
"static/fonts/SourceSerif4-Bold.ttf.woff2",
|
||||
"static/fonts/SourceSerif4-It.ttf.woff2",
|
||||
"static/fonts/SourceSerif4-LICENSE.md",
|
||||
"static/fonts/SourceCodePro-Regular.ttf.woff2",
|
||||
"static/fonts/SourceCodePro-Semibold.ttf.woff2",
|
||||
"static/fonts/SourceCodePro-It.ttf.woff2",
|
||||
"static/fonts/SourceCodePro-LICENSE.txt",
|
||||
"static/fonts/NanumBarunGothic.ttf.woff2",
|
||||
"static/fonts/NanumBarunGothic-LICENSE.txt",
|
||||
];
|
||||
let out_dir = std::env::var("OUT_DIR").expect("standard Cargo environment variable");
|
||||
for path in files {
|
||||
let inpath = format!("html/{path}");
|
||||
println!("cargo::rerun-if-changed={inpath}");
|
||||
let bytes = std::fs::read(inpath).expect("static path exists");
|
||||
use sha2::Digest;
|
||||
let bytes = sha2::Sha256::digest(bytes);
|
||||
let mut digest = format!("-{bytes:x}");
|
||||
digest.truncate(9);
|
||||
let outpath = std::path::PathBuf::from(format!("{out_dir}/{path}.sha256"));
|
||||
std::fs::create_dir_all(outpath.parent().expect("all file paths are in a directory"))
|
||||
.expect("should be able to write to out_dir");
|
||||
std::fs::write(&outpath, digest.as_bytes()).expect("write to out_dir");
|
||||
}
|
||||
}
|
||||
|
|
@ -156,7 +156,7 @@ fn clean_param_env<'tcx>(
|
|||
.iter()
|
||||
.inspect(|param| {
|
||||
if cfg!(debug_assertions) {
|
||||
debug_assert!(!param.is_anonymous_lifetime() && !param.is_host_effect());
|
||||
debug_assert!(!param.is_anonymous_lifetime());
|
||||
if let ty::GenericParamDefKind::Type { synthetic, .. } = param.kind {
|
||||
debug_assert!(!synthetic && param.name != kw::SelfUpper);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -248,9 +248,7 @@ pub(crate) fn record_extern_fqn(cx: &mut DocContext<'_>, did: DefId, kind: ItemT
|
|||
// Check to see if it is a macro 2.0 or built-in macro
|
||||
if matches!(
|
||||
CStore::from_tcx(cx.tcx).load_macro_untracked(did, cx.tcx),
|
||||
LoadedMacro::MacroDef(def, _)
|
||||
if matches!(&def.kind, ast::ItemKind::MacroDef(ast_def)
|
||||
if !ast_def.macro_rules)
|
||||
LoadedMacro::MacroDef { def, .. } if !def.macro_rules
|
||||
) {
|
||||
once(crate_name).chain(relative).collect()
|
||||
} else {
|
||||
|
|
@ -747,24 +745,12 @@ fn build_macro(
|
|||
is_doc_hidden: bool,
|
||||
) -> clean::ItemKind {
|
||||
match CStore::from_tcx(cx.tcx).load_macro_untracked(def_id, cx.tcx) {
|
||||
LoadedMacro::MacroDef(item_def, _) => match macro_kind {
|
||||
LoadedMacro::MacroDef { def, .. } => match macro_kind {
|
||||
MacroKind::Bang => {
|
||||
if let ast::ItemKind::MacroDef(ref def) = item_def.kind {
|
||||
let vis =
|
||||
cx.tcx.visibility(import_def_id.map(|d| d.to_def_id()).unwrap_or(def_id));
|
||||
clean::MacroItem(clean::Macro {
|
||||
source: utils::display_macro_source(
|
||||
cx,
|
||||
name,
|
||||
def,
|
||||
def_id,
|
||||
vis,
|
||||
is_doc_hidden,
|
||||
),
|
||||
})
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
let vis = cx.tcx.visibility(import_def_id.map(|d| d.to_def_id()).unwrap_or(def_id));
|
||||
clean::MacroItem(clean::Macro {
|
||||
source: utils::display_macro_source(cx, name, &def, def_id, vis, is_doc_hidden),
|
||||
})
|
||||
}
|
||||
MacroKind::Derive | MacroKind::Attr => {
|
||||
clean::ProcMacroItem(clean::ProcMacro { kind: macro_kind, helpers: Vec::new() })
|
||||
|
|
|
|||
|
|
@ -216,7 +216,7 @@ fn clean_generic_bound<'tcx>(
|
|||
hir::GenericBound::Outlives(lt) => GenericBound::Outlives(clean_lifetime(lt, cx)),
|
||||
hir::GenericBound::Trait(ref t) => {
|
||||
// `T: ~const Destruct` is hidden because `T: Destruct` is a no-op.
|
||||
if t.modifiers == hir::TraitBoundModifier::MaybeConst
|
||||
if let hir::BoundConstness::Maybe(_) = t.modifiers.constness
|
||||
&& cx.tcx.lang_items().destruct_trait() == Some(t.trait_ref.trait_def_id().unwrap())
|
||||
{
|
||||
return None;
|
||||
|
|
@ -263,7 +263,7 @@ fn clean_poly_trait_ref_with_constraints<'tcx>(
|
|||
trait_: clean_trait_ref_with_constraints(cx, poly_trait_ref, constraints),
|
||||
generic_params: clean_bound_vars(poly_trait_ref.bound_vars()),
|
||||
},
|
||||
hir::TraitBoundModifier::None,
|
||||
hir::TraitBoundModifiers::NONE,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -368,7 +368,9 @@ pub(crate) fn clean_predicate<'tcx>(
|
|||
// FIXME(generic_const_exprs): should this do something?
|
||||
ty::ClauseKind::ConstEvaluatable(..)
|
||||
| ty::ClauseKind::WellFormed(..)
|
||||
| ty::ClauseKind::ConstArgHasType(..) => None,
|
||||
| ty::ClauseKind::ConstArgHasType(..)
|
||||
// FIXME(effects): We can probably use this `HostEffect` pred to render `~const`.
|
||||
| ty::ClauseKind::HostEffect(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -542,7 +544,7 @@ fn clean_generic_param_def(
|
|||
synthetic,
|
||||
})
|
||||
}
|
||||
ty::GenericParamDefKind::Const { has_default, synthetic, is_host_effect: _ } => {
|
||||
ty::GenericParamDefKind::Const { has_default, synthetic } => {
|
||||
(def.name, GenericParamDefKind::Const {
|
||||
ty: Box::new(clean_middle_ty(
|
||||
ty::Binder::dummy(
|
||||
|
|
@ -617,7 +619,7 @@ fn clean_generic_param<'tcx>(
|
|||
synthetic,
|
||||
})
|
||||
}
|
||||
hir::GenericParamKind::Const { ty, default, synthetic, is_host_effect: _ } => {
|
||||
hir::GenericParamKind::Const { ty, default, synthetic } => {
|
||||
(param.name.ident().name, GenericParamDefKind::Const {
|
||||
ty: Box::new(clean_ty(ty, cx)),
|
||||
default: default.map(|ct| {
|
||||
|
|
@ -797,7 +799,7 @@ fn clean_ty_generics<'tcx>(
|
|||
}
|
||||
true
|
||||
}
|
||||
ty::GenericParamDefKind::Const { is_host_effect, .. } => !is_host_effect,
|
||||
ty::GenericParamDefKind::Const { .. } => true,
|
||||
})
|
||||
.map(|param| clean_generic_param_def(param, ParamDefaults::Yes, cx))
|
||||
.collect();
|
||||
|
|
@ -1398,7 +1400,6 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo
|
|||
clean_ty_generics(cx, tcx.generics_of(assoc_item.def_id), ty::GenericPredicates {
|
||||
parent: None,
|
||||
predicates,
|
||||
effects_min_tys: ty::List::empty(),
|
||||
});
|
||||
simplify::move_bounds_to_generic_parameters(&mut generics);
|
||||
|
||||
|
|
@ -2189,7 +2190,7 @@ pub(crate) fn clean_middle_ty<'tcx>(
|
|||
}
|
||||
|
||||
ty::Alias(ty::Weak, data) => {
|
||||
if cx.tcx.features().lazy_type_alias {
|
||||
if cx.tcx.features().lazy_type_alias() {
|
||||
// Weak type alias `data` represents the `type X` in `type X = Y`. If we need `Y`,
|
||||
// we need to use `type_of`.
|
||||
let path = clean_middle_path(
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ use arrayvec::ArrayVec;
|
|||
use rustc_ast::MetaItemInner;
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_attr::{ConstStability, Deprecation, Stability, StableSince};
|
||||
use rustc_const_eval::const_eval::is_unstable_const_fn;
|
||||
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
|
||||
use rustc_hir::def::{CtorKind, DefKind, Res};
|
||||
use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId};
|
||||
|
|
@ -641,12 +640,11 @@ impl Item {
|
|||
asyncness: ty::Asyncness,
|
||||
) -> hir::FnHeader {
|
||||
let sig = tcx.fn_sig(def_id).skip_binder();
|
||||
let constness =
|
||||
if tcx.is_const_fn(def_id) || is_unstable_const_fn(tcx, def_id).is_some() {
|
||||
hir::Constness::Const
|
||||
} else {
|
||||
hir::Constness::NotConst
|
||||
};
|
||||
let constness = if tcx.is_const_fn(def_id) {
|
||||
hir::Constness::Const
|
||||
} else {
|
||||
hir::Constness::NotConst
|
||||
};
|
||||
let asyncness = match asyncness {
|
||||
ty::Asyncness::Yes => hir::IsAsync::Async(DUMMY_SP),
|
||||
ty::Asyncness::No => hir::IsAsync::NotAsync,
|
||||
|
|
@ -664,9 +662,7 @@ impl Item {
|
|||
safety
|
||||
},
|
||||
abi,
|
||||
constness: if tcx.is_const_fn(def_id)
|
||||
|| is_unstable_const_fn(tcx, def_id).is_some()
|
||||
{
|
||||
constness: if tcx.is_const_fn(def_id) {
|
||||
hir::Constness::Const
|
||||
} else {
|
||||
hir::Constness::NotConst
|
||||
|
|
@ -966,8 +962,8 @@ pub(crate) trait AttributesExt {
|
|||
|
||||
fn cfg(&self, tcx: TyCtxt<'_>, hidden_cfg: &FxHashSet<Cfg>) -> Option<Arc<Cfg>> {
|
||||
let sess = tcx.sess;
|
||||
let doc_cfg_active = tcx.features().doc_cfg;
|
||||
let doc_auto_cfg_active = tcx.features().doc_auto_cfg;
|
||||
let doc_cfg_active = tcx.features().doc_cfg();
|
||||
let doc_auto_cfg_active = tcx.features().doc_auto_cfg();
|
||||
|
||||
fn single<T: IntoIterator>(it: T) -> Option<T::Item> {
|
||||
let mut iter = it.into_iter();
|
||||
|
|
@ -1257,7 +1253,7 @@ impl Eq for Attributes {}
|
|||
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||
pub(crate) enum GenericBound {
|
||||
TraitBound(PolyTrait, hir::TraitBoundModifier),
|
||||
TraitBound(PolyTrait, hir::TraitBoundModifiers),
|
||||
Outlives(Lifetime),
|
||||
/// `use<'a, T>` precise-capturing bound syntax
|
||||
Use(Vec<Symbol>),
|
||||
|
|
@ -1265,19 +1261,22 @@ pub(crate) enum GenericBound {
|
|||
|
||||
impl GenericBound {
|
||||
pub(crate) fn sized(cx: &mut DocContext<'_>) -> GenericBound {
|
||||
Self::sized_with(cx, hir::TraitBoundModifier::None)
|
||||
Self::sized_with(cx, hir::TraitBoundModifiers::NONE)
|
||||
}
|
||||
|
||||
pub(crate) fn maybe_sized(cx: &mut DocContext<'_>) -> GenericBound {
|
||||
Self::sized_with(cx, hir::TraitBoundModifier::Maybe)
|
||||
Self::sized_with(cx, hir::TraitBoundModifiers {
|
||||
polarity: hir::BoundPolarity::Maybe(DUMMY_SP),
|
||||
constness: hir::BoundConstness::Never,
|
||||
})
|
||||
}
|
||||
|
||||
fn sized_with(cx: &mut DocContext<'_>, modifier: hir::TraitBoundModifier) -> GenericBound {
|
||||
fn sized_with(cx: &mut DocContext<'_>, modifiers: hir::TraitBoundModifiers) -> GenericBound {
|
||||
let did = cx.tcx.require_lang_item(LangItem::Sized, None);
|
||||
let empty = ty::Binder::dummy(ty::GenericArgs::empty());
|
||||
let path = clean_middle_path(cx, did, false, ThinVec::new(), empty);
|
||||
inline::record_extern_fqn(cx, did, ItemType::Trait);
|
||||
GenericBound::TraitBound(PolyTrait { trait_: path, generic_params: Vec::new() }, modifier)
|
||||
GenericBound::TraitBound(PolyTrait { trait_: path, generic_params: Vec::new() }, modifiers)
|
||||
}
|
||||
|
||||
pub(crate) fn is_trait_bound(&self) -> bool {
|
||||
|
|
@ -1285,8 +1284,10 @@ impl GenericBound {
|
|||
}
|
||||
|
||||
pub(crate) fn is_sized_bound(&self, cx: &DocContext<'_>) -> bool {
|
||||
use rustc_hir::TraitBoundModifier as TBM;
|
||||
if let GenericBound::TraitBound(PolyTrait { ref trait_, .. }, TBM::None) = *self
|
||||
if let GenericBound::TraitBound(
|
||||
PolyTrait { ref trait_, .. },
|
||||
rustc_hir::TraitBoundModifiers::NONE,
|
||||
) = *self
|
||||
&& Some(trait_.def_id()) == cx.tcx.lang_items().sized_trait()
|
||||
{
|
||||
return true;
|
||||
|
|
@ -1361,8 +1362,7 @@ impl GenericParamDef {
|
|||
|
||||
pub(crate) fn is_synthetic_param(&self) -> bool {
|
||||
match self.kind {
|
||||
GenericParamDefKind::Lifetime { .. } => false,
|
||||
GenericParamDefKind::Const { synthetic: is_host_effect, .. } => is_host_effect,
|
||||
GenericParamDefKind::Lifetime { .. } | GenericParamDefKind::Const { .. } => false,
|
||||
GenericParamDefKind::Type { synthetic, .. } => synthetic,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,10 +114,6 @@ pub(crate) fn clean_middle_generic_args<'tcx>(
|
|||
|
||||
// Elide internal host effect args.
|
||||
let param = generics.param_at(index, cx.tcx);
|
||||
if param.is_host_effect() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let arg = ty::Binder::bind_with_vars(arg, bound_vars);
|
||||
|
||||
// Elide arguments that coincide with their default.
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use rustc_data_structures::unord::UnordSet;
|
|||
use rustc_errors::codes::*;
|
||||
use rustc_errors::emitter::{DynEmitter, HumanEmitter, stderr_destination};
|
||||
use rustc_errors::json::JsonEmitter;
|
||||
use rustc_errors::{DiagCtxtHandle, ErrorGuaranteed, TerminalUrl};
|
||||
use rustc_errors::{ErrorGuaranteed, TerminalUrl};
|
||||
use rustc_feature::UnstableFeatures;
|
||||
use rustc_hir::def::Res;
|
||||
use rustc_hir::def_id::{DefId, DefIdMap, DefIdSet, LocalDefId};
|
||||
|
|
@ -21,8 +21,8 @@ use rustc_middle::ty::{ParamEnv, Ty, TyCtxt};
|
|||
use rustc_session::config::{self, CrateType, ErrorOutputType, Input, ResolveDocLinks};
|
||||
pub(crate) use rustc_session::config::{Options, UnstableOptions};
|
||||
use rustc_session::{Session, lint};
|
||||
use rustc_span::source_map;
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::{Span, source_map};
|
||||
use tracing::{debug, info};
|
||||
|
||||
use crate::clean::inline::build_external_trait;
|
||||
|
|
@ -381,45 +381,10 @@ pub(crate) fn run_global_ctxt(
|
|||
);
|
||||
}
|
||||
|
||||
fn report_deprecated_attr(name: &str, dcx: DiagCtxtHandle<'_>, sp: Span) {
|
||||
let mut msg =
|
||||
dcx.struct_span_warn(sp, format!("the `#![doc({name})]` attribute is deprecated"));
|
||||
msg.note(
|
||||
"see issue #44136 <https://github.com/rust-lang/rust/issues/44136> \
|
||||
for more information",
|
||||
);
|
||||
|
||||
if name == "no_default_passes" {
|
||||
msg.help("`#![doc(no_default_passes)]` no longer functions; you may want to use `#![doc(document_private_items)]`");
|
||||
} else if name.starts_with("passes") {
|
||||
msg.help("`#![doc(passes = \"...\")]` no longer functions; you may want to use `#![doc(document_private_items)]`");
|
||||
} else if name.starts_with("plugins") {
|
||||
msg.warn("`#![doc(plugins = \"...\")]` no longer functions; see CVE-2018-1000622 <https://nvd.nist.gov/vuln/detail/CVE-2018-1000622>");
|
||||
}
|
||||
|
||||
msg.emit();
|
||||
}
|
||||
|
||||
// Process all of the crate attributes, extracting plugin metadata along
|
||||
// with the passes which we are supposed to run.
|
||||
for attr in krate.module.attrs.lists(sym::doc) {
|
||||
let dcx = ctxt.sess().dcx();
|
||||
|
||||
let name = attr.name_or_empty();
|
||||
// `plugins = "..."`, `no_default_passes`, and `passes = "..."` have no effect
|
||||
if attr.is_word() && name == sym::no_default_passes {
|
||||
report_deprecated_attr("no_default_passes", dcx, attr.span());
|
||||
} else if attr.value_str().is_some() {
|
||||
match name {
|
||||
sym::passes => {
|
||||
report_deprecated_attr("passes = \"...\"", dcx, attr.span());
|
||||
}
|
||||
sym::plugins => {
|
||||
report_deprecated_attr("plugins = \"...\"", dcx, attr.span());
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
if attr.is_word() && name == sym::document_private_items {
|
||||
ctxt.render_options.document_private = true;
|
||||
|
|
|
|||
|
|
@ -289,7 +289,12 @@ fn parse_source(
|
|||
// Recurse through functions body. It is necessary because the doctest source code is
|
||||
// wrapped in a function to limit the number of AST errors. If we don't recurse into
|
||||
// functions, we would thing all top-level items (so basically nothing).
|
||||
fn check_item(item: &ast::Item, info: &mut ParseSourceInfo, crate_name: &Option<&str>) {
|
||||
fn check_item(
|
||||
item: &ast::Item,
|
||||
info: &mut ParseSourceInfo,
|
||||
crate_name: &Option<&str>,
|
||||
is_top_level: bool,
|
||||
) {
|
||||
if !info.has_global_allocator
|
||||
&& item.attrs.iter().any(|attr| attr.name_or_empty() == sym::global_allocator)
|
||||
{
|
||||
|
|
@ -297,13 +302,15 @@ fn parse_source(
|
|||
}
|
||||
match item.kind {
|
||||
ast::ItemKind::Fn(ref fn_item) if !info.has_main_fn => {
|
||||
if item.ident.name == sym::main {
|
||||
if item.ident.name == sym::main && is_top_level {
|
||||
info.has_main_fn = true;
|
||||
}
|
||||
if let Some(ref body) = fn_item.body {
|
||||
for stmt in &body.stmts {
|
||||
match stmt.kind {
|
||||
ast::StmtKind::Item(ref item) => check_item(item, info, crate_name),
|
||||
ast::StmtKind::Item(ref item) => {
|
||||
check_item(item, info, crate_name, false)
|
||||
}
|
||||
ast::StmtKind::MacCall(..) => info.found_macro = true,
|
||||
_ => {}
|
||||
}
|
||||
|
|
@ -329,7 +336,7 @@ fn parse_source(
|
|||
loop {
|
||||
match parser.parse_item(ForceCollect::No) {
|
||||
Ok(Some(item)) => {
|
||||
check_item(&item, info, crate_name);
|
||||
check_item(&item, info, crate_name, true);
|
||||
|
||||
if info.has_main_fn && info.found_extern_crate {
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ 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,7 +26,6 @@ use rustc_span::symbol::kw;
|
|||
use rustc_span::{Symbol, sym};
|
||||
use rustc_target::spec::abi::Abi;
|
||||
use tracing::{debug, trace};
|
||||
use {rustc_ast as ast, rustc_hir as hir};
|
||||
|
||||
use super::url_parts_builder::{UrlPartsBuilder, estimate_item_path_byte_length};
|
||||
use crate::clean::types::ExternalLocation;
|
||||
|
|
@ -399,13 +399,13 @@ impl clean::GenericBound {
|
|||
) -> impl Display + 'a + Captures<'tcx> {
|
||||
display_fn(move |f| match self {
|
||||
clean::GenericBound::Outlives(lt) => write!(f, "{}", lt.print()),
|
||||
clean::GenericBound::TraitBound(ty, modifier) => {
|
||||
f.write_str(match modifier {
|
||||
hir::TraitBoundModifier::None => "",
|
||||
hir::TraitBoundModifier::Maybe => "?",
|
||||
hir::TraitBoundModifier::Negative => "!",
|
||||
// `const` and `~const` trait bounds are experimental; don't render them.
|
||||
hir::TraitBoundModifier::Const | hir::TraitBoundModifier::MaybeConst => "",
|
||||
clean::GenericBound::TraitBound(ty, modifiers) => {
|
||||
// `const` and `~const` trait bounds are experimental; don't render them.
|
||||
let hir::TraitBoundModifiers { polarity, constness: _ } = modifiers;
|
||||
f.write_str(match polarity {
|
||||
hir::BoundPolarity::Positive => "",
|
||||
hir::BoundPolarity::Maybe(_) => "?",
|
||||
hir::BoundPolarity::Negative(_) => "!",
|
||||
})?;
|
||||
ty.print(cx).fmt(f)
|
||||
}
|
||||
|
|
@ -554,10 +554,8 @@ fn generate_macro_def_id_path(
|
|||
// Check to see if it is a macro 2.0 or built-in macro.
|
||||
// More information in <https://rust-lang.github.io/rfcs/1584-macros.html>.
|
||||
let is_macro_2 = match cstore.load_macro_untracked(def_id, tcx) {
|
||||
LoadedMacro::MacroDef(def, _) => {
|
||||
// If `ast_def.macro_rules` is `true`, then it's not a macro 2.0.
|
||||
matches!(&def.kind, ast::ItemKind::MacroDef(ast_def) if !ast_def.macro_rules)
|
||||
}
|
||||
// If `def.macro_rules` is `true`, then it's not a macro 2.0.
|
||||
LoadedMacro::MacroDef { def, .. } => !def.macro_rules,
|
||||
_ => false,
|
||||
};
|
||||
|
||||
|
|
@ -1368,6 +1366,24 @@ impl clean::Impl {
|
|||
write!(f, " -> ")?;
|
||||
fmt_type(&bare_fn.decl.output, f, use_absolute, cx)?;
|
||||
}
|
||||
} else if let clean::Type::Path { path } = type_
|
||||
&& let Some(generics) = path.generics()
|
||||
&& generics.len() == 1
|
||||
&& self.kind.is_fake_variadic()
|
||||
{
|
||||
let ty = generics[0];
|
||||
let wrapper = anchor(path.def_id(), path.last(), cx);
|
||||
if f.alternate() {
|
||||
write!(f, "{wrapper:#}<")?;
|
||||
} else {
|
||||
write!(f, "{wrapper}<")?;
|
||||
}
|
||||
self.print_type(ty, f, use_absolute, cx)?;
|
||||
if f.alternate() {
|
||||
write!(f, ">")?;
|
||||
} else {
|
||||
write!(f, ">")?;
|
||||
}
|
||||
} else {
|
||||
fmt_type(&type_, f, use_absolute, cx)?;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1010,7 +1010,9 @@ fn render_stability_since_raw_with_extra(
|
|||
// don't display const unstable if entirely unstable
|
||||
None
|
||||
} else {
|
||||
let unstable = if let Some(n) = issue {
|
||||
let unstable = if let Some(n) = issue
|
||||
&& let Some(feature) = feature
|
||||
{
|
||||
format!(
|
||||
"<a \
|
||||
href=\"https://github.com/rust-lang/rust/issues/{n}\" \
|
||||
|
|
@ -2010,9 +2012,9 @@ fn render_rightside(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, render
|
|||
);
|
||||
if let Some(link) = src_href {
|
||||
if has_stability {
|
||||
write!(rightside, " · <a class=\"src\" href=\"{link}\">source</a>")
|
||||
write!(rightside, " · <a class=\"src\" href=\"{link}\">Source</a>")
|
||||
} else {
|
||||
write!(rightside, "<a class=\"src rightside\" href=\"{link}\">source</a>")
|
||||
write!(rightside, "<a class=\"src rightside\" href=\"{link}\">Source</a>")
|
||||
}
|
||||
}
|
||||
if has_stability && has_src_ref {
|
||||
|
|
|
|||
|
|
@ -759,7 +759,10 @@ pub(crate) fn get_function_type_for_search<'tcx>(
|
|||
}
|
||||
});
|
||||
let (mut inputs, mut output, where_clause) = match item.kind {
|
||||
clean::FunctionItem(ref f) | clean::MethodItem(ref f, _) | clean::TyMethodItem(ref f) => {
|
||||
clean::ForeignFunctionItem(ref f, _)
|
||||
| clean::FunctionItem(ref f)
|
||||
| clean::MethodItem(ref f, _)
|
||||
| clean::TyMethodItem(ref f) => {
|
||||
get_fn_inputs_and_outputs(f, tcx, impl_or_trait_generics, cache)
|
||||
}
|
||||
_ => return None,
|
||||
|
|
|
|||
|
|
@ -60,8 +60,8 @@ pub(crate) fn document_type_layout<'a, 'cx: 'a>(
|
|||
span_bug!(tcx.def_span(ty_def_id), "not an adt")
|
||||
};
|
||||
let name = adt.variant(variant_idx).name;
|
||||
let is_unsized = variant_layout.abi.is_unsized();
|
||||
let is_uninhabited = variant_layout.abi.is_uninhabited();
|
||||
let is_unsized = variant_layout.is_unsized();
|
||||
let is_uninhabited = variant_layout.is_uninhabited();
|
||||
let size = variant_layout.size.bytes() - tag_size;
|
||||
let type_layout_size = TypeLayoutSize { is_unsized, is_uninhabited, size };
|
||||
(name, type_layout_size)
|
||||
|
|
@ -72,8 +72,8 @@ pub(crate) fn document_type_layout<'a, 'cx: 'a>(
|
|||
};
|
||||
|
||||
let type_layout_size = tcx.layout_of(param_env.and(ty)).map(|layout| {
|
||||
let is_unsized = layout.abi.is_unsized();
|
||||
let is_uninhabited = layout.abi.is_uninhabited();
|
||||
let is_unsized = layout.is_unsized();
|
||||
let is_uninhabited = layout.is_uninhabited();
|
||||
let size = layout.size.bytes();
|
||||
TypeLayoutSize { is_unsized, is_uninhabited, size }
|
||||
});
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ pub(crate) fn write_shared(
|
|||
md_opts.output = cx.dst.clone();
|
||||
md_opts.external_html = cx.shared.layout.external_html.clone();
|
||||
try_err!(
|
||||
crate::markdown::render(&index_page, md_opts, cx.shared.edition()),
|
||||
crate::markdown::render_and_write(&index_page, md_opts, cx.shared.edition()),
|
||||
&index_page
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -185,7 +185,7 @@ h1, h2, h3, h4 {
|
|||
grid-template-columns: minmax(105px, 1fr) minmax(0, max-content);
|
||||
grid-template-rows: minmax(25px, min-content) min-content min-content;
|
||||
padding-bottom: 6px;
|
||||
margin-bottom: 11px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.rustdoc-breadcrumbs {
|
||||
grid-area: main-heading-breadcrumbs;
|
||||
|
|
@ -230,7 +230,7 @@ h4.code-header {
|
|||
padding: 0;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
.structfield {
|
||||
.structfield, .sub-variant-field {
|
||||
margin: 0.6em 0;
|
||||
}
|
||||
|
||||
|
|
@ -959,7 +959,7 @@ pre, .rustdoc.src .example-wrap, .example-wrap .src-line-numbers {
|
|||
background: var(--table-alt-row-background-color);
|
||||
}
|
||||
|
||||
.docblock .stab, .docblock-short .stab {
|
||||
.docblock .stab, .docblock-short .stab, .docblock p code {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
|
|
@ -1004,6 +1004,7 @@ nav.sub {
|
|||
display: flex;
|
||||
height: 34px;
|
||||
flex-grow: 1;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.src nav.sub {
|
||||
margin: 0 0 -10px 0;
|
||||
|
|
@ -2253,7 +2254,12 @@ in src-script.js and main.js
|
|||
|
||||
/* We don't display this button on mobile devices. */
|
||||
#copy-path {
|
||||
display: none;
|
||||
/* display: none; avoided as a layout hack.
|
||||
When there's one line, we get an effective line-height of 34px,
|
||||
because that's how big the image is, but if the header wraps,
|
||||
they're packed more tightly than that. */
|
||||
width: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
/* Text label takes up too much space at this size. */
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ pub(crate) struct StaticFile {
|
|||
}
|
||||
|
||||
impl StaticFile {
|
||||
fn new(filename: &str, bytes: &'static [u8]) -> StaticFile {
|
||||
Self { filename: static_filename(filename, bytes), bytes }
|
||||
fn new(filename: &str, bytes: &'static [u8], sha256: &'static str) -> StaticFile {
|
||||
Self { filename: static_filename(filename, sha256), bytes }
|
||||
}
|
||||
|
||||
pub(crate) fn minified(&self) -> Vec<u8> {
|
||||
|
|
@ -55,17 +55,9 @@ pub(crate) fn suffix_path(filename: &str, suffix: &str) -> PathBuf {
|
|||
filename.into()
|
||||
}
|
||||
|
||||
pub(crate) fn static_filename(filename: &str, contents: &[u8]) -> PathBuf {
|
||||
pub(crate) fn static_filename(filename: &str, sha256: &str) -> PathBuf {
|
||||
let filename = filename.rsplit('/').next().unwrap();
|
||||
suffix_path(filename, &static_suffix(contents))
|
||||
}
|
||||
|
||||
fn static_suffix(bytes: &[u8]) -> String {
|
||||
use sha2::Digest;
|
||||
let bytes = sha2::Sha256::digest(bytes);
|
||||
let mut digest = format!("-{bytes:x}");
|
||||
digest.truncate(9);
|
||||
digest
|
||||
suffix_path(filename, &sha256)
|
||||
}
|
||||
|
||||
macro_rules! static_files {
|
||||
|
|
@ -74,8 +66,9 @@ macro_rules! static_files {
|
|||
$(pub $field: StaticFile,)+
|
||||
}
|
||||
|
||||
// sha256 files are generated in build.rs
|
||||
pub(crate) static STATIC_FILES: std::sync::LazyLock<StaticFiles> = std::sync::LazyLock::new(|| StaticFiles {
|
||||
$($field: StaticFile::new($file_path, include_bytes!($file_path)),)+
|
||||
$($field: StaticFile::new($file_path, include_bytes!($file_path), include_str!(concat!(env!("OUT_DIR"), "/", $file_path, ".sha256"))),)+
|
||||
});
|
||||
|
||||
pub(crate) fn for_each<E>(f: impl Fn(&StaticFile) -> Result<(), E>) -> Result<(), E> {
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
{% match src_href %}
|
||||
{% when Some with (href) %}
|
||||
{% if !stability_since_raw.is_empty() +%} · {%+ endif %}
|
||||
<a class="src" href="{{href|safe}}">source</a> {#+ #}
|
||||
<a class="src" href="{{href|safe}}">Source</a> {#+ #}
|
||||
{% else %}
|
||||
{% endmatch %}
|
||||
</span> {# #}
|
||||
|
|
|
|||
|
|
@ -552,20 +552,18 @@ impl FromClean<clean::GenericBound> for GenericBound {
|
|||
}
|
||||
|
||||
pub(crate) fn from_trait_bound_modifier(
|
||||
modifier: rustc_hir::TraitBoundModifier,
|
||||
modifiers: rustc_hir::TraitBoundModifiers,
|
||||
) -> TraitBoundModifier {
|
||||
use rustc_hir::TraitBoundModifier::*;
|
||||
match modifier {
|
||||
None => TraitBoundModifier::None,
|
||||
Maybe => TraitBoundModifier::Maybe,
|
||||
MaybeConst => TraitBoundModifier::MaybeConst,
|
||||
// FIXME(const_trait_impl): Create rjt::TBM::Const and map to it once always-const bounds
|
||||
// are less experimental.
|
||||
Const => TraitBoundModifier::None,
|
||||
// FIXME(negative-bounds): This bound should be rendered negative, but
|
||||
// since that's experimental, maybe let's not add it to the rustdoc json
|
||||
// API just now...
|
||||
Negative => TraitBoundModifier::None,
|
||||
use rustc_hir as hir;
|
||||
let hir::TraitBoundModifiers { constness, polarity } = modifiers;
|
||||
match (constness, polarity) {
|
||||
(hir::BoundConstness::Never, hir::BoundPolarity::Positive) => TraitBoundModifier::None,
|
||||
(hir::BoundConstness::Never, hir::BoundPolarity::Maybe(_)) => TraitBoundModifier::Maybe,
|
||||
(hir::BoundConstness::Maybe(_), hir::BoundPolarity::Positive) => {
|
||||
TraitBoundModifier::MaybeConst
|
||||
}
|
||||
// FIXME: Fill out the rest of this matrix.
|
||||
_ => TraitBoundModifier::None,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@ extern crate rustc_abi;
|
|||
extern crate rustc_ast;
|
||||
extern crate rustc_ast_pretty;
|
||||
extern crate rustc_attr;
|
||||
extern crate rustc_const_eval;
|
||||
extern crate rustc_data_structures;
|
||||
extern crate rustc_driver;
|
||||
extern crate rustc_errors;
|
||||
|
|
@ -817,7 +816,7 @@ fn main_args(
|
|||
return wrap_return(
|
||||
dcx,
|
||||
interface::run_compiler(config, |_compiler| {
|
||||
markdown::render(&md_input, render_options, edition)
|
||||
markdown::render_and_write(&md_input, render_options, edition)
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,9 +31,9 @@ where
|
|||
allowed_lints.extend(lint_opts.iter().map(|(lint, _)| lint).cloned());
|
||||
|
||||
let lints = || {
|
||||
lint::builtin::HardwiredLints::get_lints()
|
||||
lint::builtin::HardwiredLints::lint_vec()
|
||||
.into_iter()
|
||||
.chain(rustc_lint::SoftLints::get_lints())
|
||||
.chain(rustc_lint::SoftLints::lint_vec())
|
||||
};
|
||||
|
||||
let lint_opts = lints()
|
||||
|
|
|
|||
|
|
@ -1,3 +1,13 @@
|
|||
//! Standalone markdown rendering.
|
||||
//!
|
||||
//! For the (much more common) case of rendering markdown in doc-comments, see
|
||||
//! [crate::html::markdown].
|
||||
//!
|
||||
//! This is used when [rendering a markdown file to an html file][docs], without processing
|
||||
//! rust source code.
|
||||
//!
|
||||
//! [docs]: https://doc.rust-lang.org/stable/rustdoc/#using-standalone-markdown-files
|
||||
|
||||
use std::fmt::Write as _;
|
||||
use std::fs::{File, create_dir_all, read_to_string};
|
||||
use std::io::prelude::*;
|
||||
|
|
@ -33,7 +43,7 @@ fn extract_leading_metadata(s: &str) -> (Vec<&str>, &str) {
|
|||
/// (e.g., output = "bar" => "bar/foo.html").
|
||||
///
|
||||
/// Requires session globals to be available, for symbol interning.
|
||||
pub(crate) fn render<P: AsRef<Path>>(
|
||||
pub(crate) fn render_and_write<P: AsRef<Path>>(
|
||||
input: P,
|
||||
options: RenderOptions,
|
||||
edition: Edition,
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ pub(crate) fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item
|
|||
|
||||
find_testable_code(dox, &mut tests, ErrorCodes::No, false, None);
|
||||
|
||||
if tests.found_tests == 0 && cx.tcx.features().rustdoc_missing_doc_code_examples {
|
||||
if tests.found_tests == 0 && cx.tcx.features().rustdoc_missing_doc_code_examples() {
|
||||
if should_have_doc_example(cx, item) {
|
||||
debug!("reporting error for {item:?} (hir_id={hir_id:?})");
|
||||
let sp = item.attr_span(cx.tcx);
|
||||
|
|
|
|||
|
|
@ -1419,7 +1419,7 @@ impl LinkCollector<'_, '_> {
|
|||
&& key.path_str.contains("::")
|
||||
// We only want to check this if this is an associated item.
|
||||
{
|
||||
if key.item_id.is_local() && !self.cx.tcx.features().intra_doc_pointers {
|
||||
if key.item_id.is_local() && !self.cx.tcx.features().intra_doc_pointers() {
|
||||
self.report_rawptr_assoc_feature_gate(diag.dox, &diag.link_range, diag.item);
|
||||
return None;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -161,6 +161,7 @@ static TARGETS: &[&str] = &[
|
|||
"wasm32-wasip1",
|
||||
"wasm32-wasip1-threads",
|
||||
"wasm32-wasip2",
|
||||
"wasm32v1-none",
|
||||
"x86_64-apple-darwin",
|
||||
"x86_64-apple-ios",
|
||||
"x86_64-apple-ios-macabi",
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit cf53cc54bb593b5ec3dc2be4b1702f50c36d24d5
|
||||
Subproject commit e75214ea4936d2f2c909a71a1237042cc0e14b07
|
||||
|
|
@ -31,6 +31,7 @@ declare_clippy_lint! {
|
|||
pub COGNITIVE_COMPLEXITY,
|
||||
nursery,
|
||||
"functions that should be split up into multiple functions"
|
||||
@eval_always = true
|
||||
}
|
||||
|
||||
pub struct CognitiveComplexity {
|
||||
|
|
|
|||
40
src/tools/clippy/clippy_lints/src/ctfe.rs
Normal file
40
src/tools/clippy/clippy_lints/src/ctfe.rs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_hir::intravisit::FnKind;
|
||||
use rustc_hir::{Body, FnDecl};
|
||||
use rustc_lint::Level::Deny;
|
||||
use rustc_lint::{LateContext, LateLintPass, Lint};
|
||||
use rustc_session::declare_lint_pass;
|
||||
use rustc_span::Span;
|
||||
|
||||
/// Ensures that Constant-time Function Evaluation is being done (specifically, MIR lint passes).
|
||||
/// As Clippy deactivates codegen, this lint ensures that CTFE (used in hard errors) is still ran.
|
||||
pub static CLIPPY_CTFE: &Lint = &Lint {
|
||||
name: &"clippy::CLIPPY_CTFE",
|
||||
default_level: Deny,
|
||||
desc: "Ensure CTFE is being made",
|
||||
edition_lint_opts: None,
|
||||
report_in_external_macro: true,
|
||||
future_incompatible: None,
|
||||
is_externally_loaded: true,
|
||||
crate_level_only: false,
|
||||
eval_always: true,
|
||||
..Lint::default_fields_for_macro()
|
||||
};
|
||||
|
||||
// No static CLIPPY_CTFE_INFO because we want this lint to be invisible
|
||||
|
||||
declare_lint_pass! { ClippyCtfe => [CLIPPY_CTFE] }
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for ClippyCtfe {
|
||||
fn check_fn(
|
||||
&mut self,
|
||||
cx: &LateContext<'_>,
|
||||
_: FnKind<'tcx>,
|
||||
_: &'tcx FnDecl<'tcx>,
|
||||
_: &'tcx Body<'tcx>,
|
||||
_: Span,
|
||||
defid: LocalDefId,
|
||||
) {
|
||||
cx.tcx.ensure().mir_drops_elaborated_and_const_checked(defid); // Lint
|
||||
}
|
||||
}
|
||||
|
|
@ -9,6 +9,7 @@ macro_rules! declare_clippy_lint {
|
|||
$desc:literal,
|
||||
$version_expr:expr,
|
||||
$version_lit:literal
|
||||
$(, $eval_always: literal)?
|
||||
) => {
|
||||
rustc_session::declare_tool_lint! {
|
||||
$(#[doc = $lit])*
|
||||
|
|
@ -17,6 +18,7 @@ macro_rules! declare_clippy_lint {
|
|||
$category,
|
||||
$desc,
|
||||
report_in_external_macro:true
|
||||
$(, @eval_always = $eval_always)?
|
||||
}
|
||||
|
||||
pub(crate) static ${concat($lint_name, _INFO)}: &'static crate::LintInfo = &crate::LintInfo {
|
||||
|
|
@ -33,11 +35,12 @@ macro_rules! declare_clippy_lint {
|
|||
pub $lint_name:ident,
|
||||
restriction,
|
||||
$desc:literal
|
||||
$(@eval_always = $eval_always: literal)?
|
||||
) => {
|
||||
declare_clippy_lint! {@
|
||||
$(#[doc = $lit])*
|
||||
pub $lint_name, Allow, crate::LintCategory::Restriction, $desc,
|
||||
Some($version), $version
|
||||
Some($version), $version $(, $eval_always)?
|
||||
}
|
||||
};
|
||||
(
|
||||
|
|
@ -46,12 +49,12 @@ macro_rules! declare_clippy_lint {
|
|||
pub $lint_name:ident,
|
||||
style,
|
||||
$desc:literal
|
||||
$(@eval_always = $eval_always: literal)?
|
||||
) => {
|
||||
declare_clippy_lint! {@
|
||||
$(#[doc = $lit])*
|
||||
pub $lint_name, Warn, crate::LintCategory::Style, $desc,
|
||||
Some($version), $version
|
||||
|
||||
Some($version), $version $(, $eval_always)?
|
||||
}
|
||||
};
|
||||
(
|
||||
|
|
@ -60,11 +63,12 @@ macro_rules! declare_clippy_lint {
|
|||
pub $lint_name:ident,
|
||||
correctness,
|
||||
$desc:literal
|
||||
$(@eval_always = $eval_always: literal)?
|
||||
) => {
|
||||
declare_clippy_lint! {@
|
||||
$(#[doc = $lit])*
|
||||
pub $lint_name, Deny, crate::LintCategory::Correctness, $desc,
|
||||
Some($version), $version
|
||||
Some($version), $version $(, $eval_always)?
|
||||
|
||||
}
|
||||
};
|
||||
|
|
@ -74,11 +78,12 @@ macro_rules! declare_clippy_lint {
|
|||
pub $lint_name:ident,
|
||||
perf,
|
||||
$desc:literal
|
||||
$(@eval_always = $eval_always: literal)?
|
||||
) => {
|
||||
declare_clippy_lint! {@
|
||||
$(#[doc = $lit])*
|
||||
pub $lint_name, Warn, crate::LintCategory::Perf, $desc,
|
||||
Some($version), $version
|
||||
Some($version), $version $(, $eval_always)?
|
||||
}
|
||||
};
|
||||
(
|
||||
|
|
@ -87,11 +92,12 @@ macro_rules! declare_clippy_lint {
|
|||
pub $lint_name:ident,
|
||||
complexity,
|
||||
$desc:literal
|
||||
$(@eval_always = $eval_always: literal)?
|
||||
) => {
|
||||
declare_clippy_lint! {@
|
||||
$(#[doc = $lit])*
|
||||
pub $lint_name, Warn, crate::LintCategory::Complexity, $desc,
|
||||
Some($version), $version
|
||||
Some($version), $version $(, $eval_always)?
|
||||
}
|
||||
};
|
||||
(
|
||||
|
|
@ -100,11 +106,12 @@ macro_rules! declare_clippy_lint {
|
|||
pub $lint_name:ident,
|
||||
suspicious,
|
||||
$desc:literal
|
||||
$(@eval_always = $eval_always: literal)?
|
||||
) => {
|
||||
declare_clippy_lint! {@
|
||||
$(#[doc = $lit])*
|
||||
pub $lint_name, Warn, crate::LintCategory::Suspicious, $desc,
|
||||
Some($version), $version
|
||||
Some($version), $version $(, $eval_always)?
|
||||
}
|
||||
};
|
||||
(
|
||||
|
|
@ -113,11 +120,12 @@ macro_rules! declare_clippy_lint {
|
|||
pub $lint_name:ident,
|
||||
nursery,
|
||||
$desc:literal
|
||||
$(@eval_always = $eval_always: literal)?
|
||||
) => {
|
||||
declare_clippy_lint! {@
|
||||
$(#[doc = $lit])*
|
||||
pub $lint_name, Allow, crate::LintCategory::Nursery, $desc,
|
||||
Some($version), $version
|
||||
Some($version), $version $(, $eval_always)?
|
||||
}
|
||||
};
|
||||
(
|
||||
|
|
@ -126,11 +134,12 @@ macro_rules! declare_clippy_lint {
|
|||
pub $lint_name:ident,
|
||||
pedantic,
|
||||
$desc:literal
|
||||
$(@eval_always = $eval_always: literal)?
|
||||
) => {
|
||||
declare_clippy_lint! {@
|
||||
$(#[doc = $lit])*
|
||||
pub $lint_name, Allow, crate::LintCategory::Pedantic, $desc,
|
||||
Some($version), $version
|
||||
Some($version), $version $(, $eval_always)?
|
||||
}
|
||||
};
|
||||
(
|
||||
|
|
@ -139,11 +148,12 @@ macro_rules! declare_clippy_lint {
|
|||
pub $lint_name:ident,
|
||||
cargo,
|
||||
$desc:literal
|
||||
$(@eval_always = $eval_always: literal)?
|
||||
) => {
|
||||
declare_clippy_lint! {@
|
||||
$(#[doc = $lit])*
|
||||
pub $lint_name, Allow, crate::LintCategory::Cargo, $desc,
|
||||
Some($version), $version
|
||||
Some($version), $version $(, $eval_always)?
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -166,7 +166,7 @@ declare_with_version! { RENAMED(RENAMED_VERSION): &[(&str, &str)] = &[
|
|||
#[clippy::version = ""]
|
||||
("clippy::positional_named_format_parameters", "named_arguments_used_positionally"),
|
||||
#[clippy::version = ""]
|
||||
("clippy::temporary_cstring_as_ptr", "temporary_cstring_as_ptr"),
|
||||
("clippy::temporary_cstring_as_ptr", "dangling_pointers_from_temporaries"),
|
||||
#[clippy::version = ""]
|
||||
("clippy::undropped_manually_drops", "undropped_manually_drops"),
|
||||
#[clippy::version = ""]
|
||||
|
|
|
|||
|
|
@ -324,7 +324,7 @@ fn check_copy_clone<'tcx>(cx: &LateContext<'tcx>, item: &Item<'_>, trait_ref: &h
|
|||
// If the current self type doesn't implement Copy (due to generic constraints), search to see if
|
||||
// there's a Copy impl for any instance of the adt.
|
||||
if !is_copy(cx, ty) {
|
||||
if ty_subs.non_erasable_generics(cx.tcx, ty_adt.did()).next().is_some() {
|
||||
if ty_subs.non_erasable_generics().next().is_some() {
|
||||
let has_copy_impl = cx.tcx.all_local_trait_impls(()).get(©_id).map_or(false, |impls| {
|
||||
impls.iter().any(|&id| {
|
||||
matches!(cx.tcx.type_of(id).instantiate_identity().kind(), ty::Adt(adt, _)
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ impl LateLintPass<'_> for EmptyEnum {
|
|||
fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
|
||||
if let ItemKind::Enum(..) = item.kind
|
||||
// Only suggest the `never_type` if the feature is enabled
|
||||
&& cx.tcx.features().never_type
|
||||
&& cx.tcx.features().never_type()
|
||||
&& let Some(adt) = cx.tcx.type_of(item.owner_id).instantiate_identity().ty_adt_def()
|
||||
&& adt.variants().is_empty()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use clippy_utils::source::snippet;
|
|||
use rustc_errors::{Applicability, SuggestionStyle};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::{
|
||||
AssocItemConstraint, GenericArg, GenericBound, GenericBounds, PredicateOrigin, TraitBoundModifier, TyKind,
|
||||
AssocItemConstraint, GenericArg, GenericBound, GenericBounds, PredicateOrigin, TraitBoundModifiers, TyKind,
|
||||
WherePredicate,
|
||||
};
|
||||
use rustc_hir_analysis::lower_ty;
|
||||
|
|
@ -234,7 +234,7 @@ fn collect_supertrait_bounds<'tcx>(cx: &LateContext<'tcx>, bounds: GenericBounds
|
|||
.iter()
|
||||
.filter_map(|bound| {
|
||||
if let GenericBound::Trait(poly_trait) = bound
|
||||
&& let TraitBoundModifier::None = poly_trait.modifiers
|
||||
&& let TraitBoundModifiers::NONE = poly_trait.modifiers
|
||||
&& let [.., path] = poly_trait.trait_ref.path.segments
|
||||
&& poly_trait.bound_generic_params.is_empty()
|
||||
&& let Some(trait_def_id) = path.res.opt_def_id()
|
||||
|
|
@ -300,7 +300,7 @@ fn check<'tcx>(cx: &LateContext<'tcx>, bounds: GenericBounds<'tcx>) {
|
|||
// simply comparing trait `DefId`s won't be enough. We also need to compare the generics.
|
||||
for (index, bound) in bounds.iter().enumerate() {
|
||||
if let GenericBound::Trait(poly_trait) = bound
|
||||
&& let TraitBoundModifier::None = poly_trait.modifiers
|
||||
&& let TraitBoundModifiers::NONE = poly_trait.modifiers
|
||||
&& let [.., path] = poly_trait.trait_ref.path.segments
|
||||
&& let implied_args = path.args.map_or([].as_slice(), |a| a.args)
|
||||
&& let implied_constraints = path.args.map_or([].as_slice(), |a| a.constraints)
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ extern crate clippy_utils;
|
|||
#[cfg_attr(feature = "internal", allow(clippy::missing_clippy_version_attribute))]
|
||||
mod utils;
|
||||
|
||||
pub mod ctfe; // Very important lint, do not remove (rust#125116)
|
||||
pub mod declared_lints;
|
||||
pub mod deprecated_lints;
|
||||
|
||||
|
|
@ -605,6 +606,8 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
|
|||
});
|
||||
}
|
||||
|
||||
store.register_late_pass(|_| Box::new(ctfe::ClippyCtfe));
|
||||
|
||||
store.register_late_pass(move |_| Box::new(operators::arithmetic_side_effects::ArithmeticSideEffects::new(conf)));
|
||||
store.register_late_pass(|_| Box::new(utils::dump_hir::DumpHir));
|
||||
store.register_late_pass(|_| Box::new(utils::author::Author));
|
||||
|
|
|
|||
|
|
@ -111,11 +111,7 @@ fn check_int_ty_and_feature(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
|
|||
let expr_ty = cx.typeck_results().expr_ty(expr);
|
||||
match expr_ty.peel_refs().kind() {
|
||||
ty::Uint(_) => true,
|
||||
ty::Int(_) => cx
|
||||
.tcx
|
||||
.features()
|
||||
.declared_features
|
||||
.contains(&Symbol::intern("int_roundings")),
|
||||
ty::Int(_) => cx.tcx.features().enabled(Symbol::intern("int_roundings")),
|
||||
|
||||
_ => false,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>]) {
|
|||
let indexed_arms: Vec<(usize, &Arm<'_>)> = arms.iter().enumerate().collect();
|
||||
for (&(i, arm1), &(j, arm2)) in search_same(&indexed_arms, hash, eq) {
|
||||
if matches!(arm2.pat.kind, PatKind::Wild) {
|
||||
if !cx.tcx.features().non_exhaustive_omitted_patterns_lint
|
||||
if !cx.tcx.features().non_exhaustive_omitted_patterns_lint()
|
||||
|| is_lint_allowed(cx, NON_EXHAUSTIVE_OMITTED_PATTERNS, arm2.hir_id)
|
||||
{
|
||||
let arm_span = adjusted_arm_span(cx, arm1.span);
|
||||
|
|
|
|||
|
|
@ -251,7 +251,7 @@ fn emit_redundant_guards<'tcx>(
|
|||
fn expr_can_be_pat(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
|
||||
for_each_expr_without_closures(expr, |expr| {
|
||||
if match expr.kind {
|
||||
ExprKind::ConstBlock(..) => cx.tcx.features().inline_const_pat,
|
||||
ExprKind::ConstBlock(..) => cx.tcx.features().inline_const_pat(),
|
||||
ExprKind::Call(c, ..) if let ExprKind::Path(qpath) = c.kind => {
|
||||
// Allow ctors
|
||||
matches!(cx.qpath_res(&qpath, c.hir_id), Res::Def(DefKind::Ctor(..), ..))
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::def_id::{DefId, DefIdMap};
|
||||
use rustc_hir::{GenericBound, Generics, PolyTraitRef, TraitBoundModifier, WherePredicate};
|
||||
use rustc_hir::{GenericBound, Generics, PolyTraitRef, TraitBoundModifiers, BoundPolarity, WherePredicate};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty::{ClauseKind, PredicatePolarity};
|
||||
use rustc_session::declare_lint_pass;
|
||||
|
|
@ -118,13 +118,13 @@ impl LateLintPass<'_> for NeedlessMaybeSized {
|
|||
let maybe_sized_params: DefIdMap<_> = type_param_bounds(generics)
|
||||
.filter(|bound| {
|
||||
bound.trait_bound.trait_ref.trait_def_id() == Some(sized_trait)
|
||||
&& bound.trait_bound.modifiers == TraitBoundModifier::Maybe
|
||||
&& matches!(bound.trait_bound.modifiers.polarity, BoundPolarity::Maybe(_))
|
||||
})
|
||||
.map(|bound| (bound.param, bound))
|
||||
.collect();
|
||||
|
||||
for bound in type_param_bounds(generics) {
|
||||
if bound.trait_bound.modifiers == TraitBoundModifier::None
|
||||
if bound.trait_bound.modifiers == TraitBoundModifiers::NONE
|
||||
&& let Some(sized_bound) = maybe_sized_params.get(&bound.param)
|
||||
&& let Some(path) = path_to_sized_bound(cx, bound.trait_bound)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ use rustc_errors::Applicability;
|
|||
use rustc_hir::def::Res;
|
||||
use rustc_hir::{
|
||||
GenericBound, Generics, Item, ItemKind, LangItem, Node, Path, PathSegment, PredicateOrigin, QPath,
|
||||
TraitBoundModifier, TraitItem, TraitRef, Ty, TyKind, WherePredicate,
|
||||
TraitBoundModifiers, TraitItem, TraitRef, Ty, TyKind, WherePredicate, BoundPolarity,
|
||||
};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::impl_lint_pass;
|
||||
|
|
@ -233,7 +233,7 @@ impl TraitBounds {
|
|||
fn cannot_combine_maybe_bound(&self, cx: &LateContext<'_>, bound: &GenericBound<'_>) -> bool {
|
||||
if !self.msrv.meets(msrvs::MAYBE_BOUND_IN_WHERE)
|
||||
&& let GenericBound::Trait(tr) = bound
|
||||
&& let TraitBoundModifier::Maybe = tr.modifiers
|
||||
&& let BoundPolarity::Maybe(_) = tr.modifiers.polarity
|
||||
{
|
||||
cx.tcx.lang_items().get(LangItem::Sized) == tr.trait_ref.path.res.opt_def_id()
|
||||
} else {
|
||||
|
|
@ -374,12 +374,12 @@ fn check_trait_bound_duplication<'tcx>(cx: &LateContext<'tcx>, generics: &'_ Gen
|
|||
struct ComparableTraitRef<'a, 'tcx> {
|
||||
cx: &'a LateContext<'tcx>,
|
||||
trait_ref: &'tcx TraitRef<'tcx>,
|
||||
modifier: TraitBoundModifier,
|
||||
modifiers: TraitBoundModifiers,
|
||||
}
|
||||
|
||||
impl PartialEq for ComparableTraitRef<'_, '_> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.modifier == other.modifier
|
||||
SpanlessEq::new(self.cx).eq_modifiers(self.modifiers, other.modifiers)
|
||||
&& SpanlessEq::new(self.cx)
|
||||
.paths_by_resolution()
|
||||
.eq_path(self.trait_ref.path, other.trait_ref.path)
|
||||
|
|
@ -390,8 +390,8 @@ impl Hash for ComparableTraitRef<'_, '_> {
|
|||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
let mut s = SpanlessHash::new(self.cx).paths_by_resolution();
|
||||
s.hash_path(self.trait_ref.path);
|
||||
s.hash_modifiers(self.modifiers);
|
||||
state.write_u64(s.finish());
|
||||
self.modifier.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -400,7 +400,7 @@ fn get_trait_info_from_bound<'a>(bound: &'a GenericBound<'_>) -> Option<(Res, &'
|
|||
let trait_path = t.trait_ref.path;
|
||||
let trait_span = {
|
||||
let path_span = trait_path.span;
|
||||
if let TraitBoundModifier::Maybe = t.modifiers {
|
||||
if let BoundPolarity::Maybe(_) = t.modifiers.polarity {
|
||||
path_span.with_lo(path_span.lo() - BytePos(1)) // include the `?`
|
||||
} else {
|
||||
path_span
|
||||
|
|
@ -427,7 +427,7 @@ fn rollup_traits<'cx, 'tcx>(
|
|||
ComparableTraitRef {
|
||||
cx,
|
||||
trait_ref: &t.trait_ref,
|
||||
modifier: t.modifiers,
|
||||
modifiers: t.modifiers,
|
||||
},
|
||||
t.span,
|
||||
))
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ impl From<&Attribute> for IdentIter {
|
|||
struct IdentCollector(Vec<Ident>);
|
||||
|
||||
impl Visitor<'_> for IdentCollector {
|
||||
fn visit_ident(&mut self, ident: Ident) {
|
||||
self.0.push(ident);
|
||||
fn visit_ident(&mut self, ident: &Ident) {
|
||||
self.0.push(*ident);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@ use rustc_hir::def::{DefKind, Res};
|
|||
use rustc_hir::{
|
||||
ArrayLen, AssocItemConstraint, BinOpKind, BindingMode, Block, BodyId, Closure, ConstArg, ConstArgKind, Expr,
|
||||
ExprField, ExprKind, FnRetTy, GenericArg, GenericArgs, HirId, HirIdMap, InlineAsmOperand, LetExpr, Lifetime,
|
||||
LifetimeName, Pat, PatField, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, Ty, TyKind,
|
||||
LifetimeName, Pat, PatField, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, TraitBoundModifiers, Ty,
|
||||
TyKind,
|
||||
};
|
||||
use rustc_lexer::{TokenKind, tokenize};
|
||||
use rustc_lint::LateContext;
|
||||
|
|
@ -126,6 +127,11 @@ impl<'a, 'tcx> SpanlessEq<'a, 'tcx> {
|
|||
pub fn eq_path_segments(&mut self, left: &[PathSegment<'_>], right: &[PathSegment<'_>]) -> bool {
|
||||
self.inter_expr().eq_path_segments(left, right)
|
||||
}
|
||||
|
||||
pub fn eq_modifiers(&mut self, left: TraitBoundModifiers, right: TraitBoundModifiers) -> bool {
|
||||
std::mem::discriminant(&left.constness) == std::mem::discriminant(&right.constness)
|
||||
&& std::mem::discriminant(&left.polarity) == std::mem::discriminant(&right.polarity)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct HirEqInterExpr<'a, 'b, 'tcx> {
|
||||
|
|
@ -1143,6 +1149,12 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn hash_modifiers(&mut self, modifiers: TraitBoundModifiers) {
|
||||
let TraitBoundModifiers { constness, polarity } = modifiers;
|
||||
std::mem::discriminant(&polarity).hash(&mut self.s);
|
||||
std::mem::discriminant(&constness).hash(&mut self.s);
|
||||
}
|
||||
|
||||
pub fn hash_stmt(&mut self, b: &Stmt<'_>) {
|
||||
std::mem::discriminant(&b.kind).hash(&mut self.s);
|
||||
|
||||
|
|
|
|||
|
|
@ -334,7 +334,7 @@ fn check_terminator<'tcx>(
|
|||
| TerminatorKind::TailCall { func, args, fn_span: _ } => {
|
||||
let fn_ty = func.ty(body, tcx);
|
||||
if let ty::FnDef(fn_def_id, _) = *fn_ty.kind() {
|
||||
if !is_const_fn(tcx, fn_def_id, msrv) {
|
||||
if !is_stable_const_fn(tcx, fn_def_id, msrv) {
|
||||
return Err((
|
||||
span,
|
||||
format!(
|
||||
|
|
@ -377,12 +377,12 @@ fn check_terminator<'tcx>(
|
|||
}
|
||||
}
|
||||
|
||||
fn is_const_fn(tcx: TyCtxt<'_>, def_id: DefId, msrv: &Msrv) -> bool {
|
||||
fn is_stable_const_fn(tcx: TyCtxt<'_>, def_id: DefId, msrv: &Msrv) -> bool {
|
||||
tcx.is_const_fn(def_id)
|
||||
&& tcx.lookup_const_stability(def_id).map_or(true, |const_stab| {
|
||||
&& tcx.lookup_const_stability(def_id).is_none_or(|const_stab| {
|
||||
if let rustc_attr::StabilityLevel::Stable { since, .. } = const_stab.level {
|
||||
// Checking MSRV is manually necessary because `rustc` has no such concept. This entire
|
||||
// function could be removed if `rustc` provided a MSRV-aware version of `is_const_fn`.
|
||||
// function could be removed if `rustc` provided a MSRV-aware version of `is_stable_const_fn`.
|
||||
// as a part of an unimplemented MSRV check https://github.com/rust-lang/rust/issues/65262.
|
||||
|
||||
let const_stab_rust_version = match since {
|
||||
|
|
@ -393,8 +393,12 @@ fn is_const_fn(tcx: TyCtxt<'_>, def_id: DefId, msrv: &Msrv) -> bool {
|
|||
|
||||
msrv.meets(const_stab_rust_version)
|
||||
} else {
|
||||
// Unstable const fn with the feature enabled.
|
||||
msrv.current().is_none()
|
||||
// Unstable const fn, check if the feature is enabled. We need both the regular stability
|
||||
// feature and (if set) the const stability feature to const-call this function.
|
||||
let stab = tcx.lookup_stability(def_id);
|
||||
let is_enabled = stab.is_some_and(|s| s.is_stable() || tcx.features().enabled(s.feature))
|
||||
&& const_stab.feature.is_none_or(|f| tcx.features().enabled(f));
|
||||
is_enabled && msrv.current().is_none()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -207,16 +207,7 @@ fn path_segment_certainty(
|
|||
if cx.tcx.res_generics_def_id(path_segment.res).is_some() {
|
||||
let generics = cx.tcx.generics_of(def_id);
|
||||
|
||||
let own_count = generics.own_params.len()
|
||||
- usize::from(generics.host_effect_index.is_some_and(|index| {
|
||||
// Check that the host index actually belongs to this resolution.
|
||||
// E.g. for `Add::add`, host_effect_index is `Some(2)`, but it's part of the parent `Add`
|
||||
// trait's generics.
|
||||
// Add params: [Self#0, Rhs#1, host#2] parent_count=0, count=3
|
||||
// Add::add params: [] parent_count=3, count=3
|
||||
// (3..3).contains(&host_effect_index) => false
|
||||
(generics.parent_count..generics.count()).contains(&index)
|
||||
}));
|
||||
let own_count = generics.own_params.len();
|
||||
let lhs = if (parent_certainty.is_certain() || generics.parent_count == 0) && own_count == 0 {
|
||||
Certainty::Certain(None)
|
||||
} else {
|
||||
|
|
@ -310,8 +301,7 @@ fn type_is_inferable_from_arguments(cx: &LateContext<'_>, expr: &Expr<'_>) -> bo
|
|||
|
||||
// Check that all type parameters appear in the functions input types.
|
||||
(0..(generics.parent_count + generics.own_params.len()) as u32).all(|index| {
|
||||
Some(index as usize) == generics.host_effect_index
|
||||
|| fn_sig
|
||||
fn_sig
|
||||
.inputs()
|
||||
.iter()
|
||||
.any(|input_ty| contains_param(*input_ty.skip_binder(), index))
|
||||
|
|
|
|||
|
|
@ -346,13 +346,13 @@ pub fn is_const_evaluatable<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) ->
|
|||
.cx
|
||||
.qpath_res(p, hir_id)
|
||||
.opt_def_id()
|
||||
.map_or(false, |id| self.cx.tcx.is_const_fn_raw(id)) => {},
|
||||
.map_or(false, |id| self.cx.tcx.is_const_fn(id)) => {},
|
||||
ExprKind::MethodCall(..)
|
||||
if self
|
||||
.cx
|
||||
.typeck_results()
|
||||
.type_dependent_def_id(e.hir_id)
|
||||
.map_or(false, |id| self.cx.tcx.is_const_fn_raw(id)) => {},
|
||||
.map_or(false, |id| self.cx.tcx.is_const_fn(id)) => {},
|
||||
ExprKind::Binary(_, lhs, rhs)
|
||||
if self.cx.typeck_results().expr_ty(lhs).peel_refs().is_primitive_ty()
|
||||
&& self.cx.typeck_results().expr_ty(rhs).peel_refs().is_primitive_ty() => {},
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
#![warn(clippy::author)]
|
||||
|
||||
fn main() {
|
||||
#[clippy::author]
|
||||
let x: char = 0x45 as char;
|
||||
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