diff options
Diffstat (limited to 'src')
79 files changed, 719 insertions, 427 deletions
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 952c70cec1c..b33fc02f49c 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -792,7 +792,7 @@ impl<'a> Builder<'a> { run::CollectLicenseMetadata, run::GenerateCopyright, ), - Kind::Setup => describe!(setup::Profile), + Kind::Setup => describe!(setup::Profile, setup::Hook, setup::Link, setup::Vscode), Kind::Clean => describe!(clean::CleanAll, clean::Rustc, clean::Std), // special-cased in Build::build() Kind::Format => vec![], @@ -1915,6 +1915,13 @@ impl<'a> Builder<'a> { } } + if matches!(mode, Mode::Std) { + if let Some(mir_opt_level) = self.config.rust_validate_mir_opts { + rustflags.arg("-Zvalidate-mir"); + rustflags.arg(&format!("-Zmir-opt-level={}", mir_opt_level)); + } + } + Cargo { command: cargo, rustflags, rustdocflags, allow_features } } diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index f0fcdf0d5a0..348d22a9ce6 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -459,72 +459,6 @@ impl Step for StdLink { let libdir = builder.sysroot_libdir(target_compiler, target); let hostdir = builder.sysroot_libdir(target_compiler, compiler.host); add_to_sysroot(builder, &libdir, &hostdir, &libstd_stamp(builder, compiler, target)); - - if compiler.stage == 0 { - // special handling for stage0, to make `rustup toolchain link` and `x dist --stage 0` - // work for stage0-sysroot - let sysroot = builder.out.join(&compiler.host.triple).join("stage0-sysroot"); - - let host_lib_dir = builder.initial_rustc.ancestors().nth(2).unwrap().join("lib"); - let host_bin_dir = builder.out.join(&builder.initial_rustc.parent().unwrap()); - let host_codegen_backends = - host_lib_dir.join("rustlib").join(&compiler.host.triple).join("codegen-backends"); - let sysroot_bin_dir = sysroot.join("bin"); - let sysroot_lib_dir = sysroot.join("lib"); - let sysroot_codegen_backends = builder.sysroot_codegen_backends(compiler); - - // Create the `bin` directory in stage0-sysroot - t!(fs::create_dir_all(&sysroot_bin_dir)); - - // copy bin files from `builder.initial_rustc/./` to `stage0-sysroot/bin` - if let Ok(files) = fs::read_dir(&host_bin_dir) { - for file in files { - let file = t!(file); - if file.file_name() == "rustfmt" { - // This is when `rustc` and `cargo` are set in `config.toml` - if !file.path().starts_with(&builder.out) { - builder.copy( - &file.path().into_boxed_path(), - &sysroot_bin_dir.join(file.file_name()), - ); - } else { - builder.copy( - &builder - .out - .join(&compiler.host.triple) - .join("rustfmt/bin/rustfmt"), - &sysroot_bin_dir.join(file.file_name()), - ); - } - } else { - builder.copy( - &file.path().into_boxed_path(), - &sysroot_bin_dir.join(file.file_name()), - ); - } - } - } - - // copy dylib files from `builder.initial_rustc/../lib/*` while excluding the `rustlib` directory to `stage0-sysroot/lib` - if let Ok(files) = fs::read_dir(&host_lib_dir) { - for file in files { - let file = t!(file); - let path = file.path(); - if path.is_file() - && is_dylib(&file.file_name().into_string().unwrap()) - && !path.starts_with(sysroot_lib_dir.join("rustlib").into_boxed_path()) - { - builder.copy(&path, &sysroot_lib_dir.join(path.file_name().unwrap())); - } - } - } - - t!(fs::create_dir_all(&sysroot_codegen_backends)); - // copy `codegen-backends` from `host_lib_dir/rustlib/codegen_backends` to `stage0-sysroot/lib/rustlib/host-triple/codegen-backends` if it exists. - if host_codegen_backends.exists() { - builder.cp_r(&host_codegen_backends, &sysroot_codegen_backends); - } - } } } diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 56f96734bbb..4a563bc396d 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -173,6 +173,7 @@ pub struct Config { pub rust_profile_use: Option<String>, pub rust_profile_generate: Option<String>, pub rust_lto: RustcLto, + pub rust_validate_mir_opts: Option<u32>, pub llvm_profile_use: Option<String>, pub llvm_profile_generate: bool, pub llvm_libunwind_default: Option<LlvmLibunwind>, @@ -770,6 +771,7 @@ define_config! { // ignored; this is set from an env var set by bootstrap.py download_rustc: Option<StringOrBool> = "download-rustc", lto: Option<String> = "lto", + validate_mir_opts: Option<u32> = "validate-mir-opts", } } @@ -1149,6 +1151,7 @@ impl Config { .as_deref() .map(|value| RustcLto::from_str(value).unwrap()) .unwrap_or_default(); + config.rust_validate_mir_opts = rust.validate_mir_opts; } else { config.rust_profile_use = flags.rust_profile_use; config.rust_profile_generate = flags.rust_profile_generate; diff --git a/src/bootstrap/download.rs b/src/bootstrap/download.rs index d6592d2d771..d1e2149d3f9 100644 --- a/src/bootstrap/download.rs +++ b/src/bootstrap/download.rs @@ -2,7 +2,7 @@ use std::{ env, ffi::{OsStr, OsString}, fs::{self, File}, - io::{self, BufRead, BufReader, ErrorKind}, + io::{BufRead, BufReader, ErrorKind}, path::{Path, PathBuf}, process::{Command, Stdio}, }; @@ -26,14 +26,6 @@ impl Config { self.verbose > 0 } - pub fn symlink_file<P: AsRef<Path>, Q: AsRef<Path>>(&self, src: P, link: Q) -> io::Result<()> { - #[cfg(unix)] - use std::os::unix::fs::symlink as symlink_file; - #[cfg(windows)] - use std::os::windows::fs::symlink_file; - if !self.dry_run() { symlink_file(src.as_ref(), link.as_ref()) } else { Ok(()) } - } - pub(crate) fn create(&self, path: &Path, s: &str) { if self.dry_run() { return; @@ -338,15 +330,6 @@ impl Config { let bin_root = self.out.join(host.triple).join("rustfmt"); let rustfmt_path = bin_root.join("bin").join(exe("rustfmt", host)); let rustfmt_stamp = bin_root.join(".rustfmt-stamp"); - - #[cfg(not(windows))] - { - let legacy_rustfmt = self.initial_rustc.with_file_name(exe("rustfmt", host)); - if !legacy_rustfmt.exists() { - t!(self.symlink_file(&rustfmt_path, &legacy_rustfmt)); - } - } - if rustfmt_path.exists() && !program_out_of_date(&rustfmt_stamp, &channel) { return Some(rustfmt_path); } diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index f07e710a9e6..9d1504c34e8 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -554,7 +554,8 @@ Arguments: Kind::Setup => { subcommand_help.push_str(&format!( "\n -x.py setup creates a `config.toml` which changes the defaults for x.py itself. +x.py setup creates a `config.toml` which changes the defaults for x.py itself, +as well as setting up a git pre-push hook, VS code config and toolchain link. Arguments: This subcommand accepts a 'profile' to use for builds. For example: @@ -564,7 +565,13 @@ Arguments: The profile is optional and you will be prompted interactively if it is not given. The following profiles are available: -{}", +{} + + To only set up the git hook, VS code or toolchain link, you may use + ./x.py setup hook + ./x.py setup vscode + ./x.py setup link +", Profile::all_for_help(" ").trim_end() )); } @@ -638,7 +645,7 @@ Arguments: } Kind::Setup => { let profile = if paths.len() > 1 { - eprintln!("\nerror: At most one profile can be passed to setup\n"); + eprintln!("\nerror: At most one option can be passed to setup\n"); usage(1, &opts, verbose, &subcommand_help) } else if let Some(path) = paths.pop() { let profile_string = t!(path.into_os_string().into_string().map_err( diff --git a/src/bootstrap/format.rs b/src/bootstrap/format.rs index 615794958d0..ae72a42973c 100644 --- a/src/bootstrap/format.rs +++ b/src/bootstrap/format.rs @@ -218,7 +218,7 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) { WalkBuilder::new(first) } } else { - WalkBuilder::new(first) + WalkBuilder::new(src.join(first)) }; for path in &paths[1..] { @@ -229,7 +229,7 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) { walker.add(path); } } else { - walker.add(path); + walker.add(src.join(path)); } } diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index f753720b353..f4abdf1cc57 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -20,6 +20,7 @@ use std::cell::{Cell, RefCell}; use std::collections::{HashMap, HashSet}; use std::env; use std::fs::{self, File}; +use std::io; use std::io::ErrorKind; use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; @@ -1406,7 +1407,7 @@ impl Build { src = t!(fs::canonicalize(src)); } else { let link = t!(fs::read_link(src)); - t!(self.config.symlink_file(link, dst)); + t!(self.symlink_file(link, dst)); return; } } @@ -1524,6 +1525,14 @@ impl Build { iter.map(|e| t!(e)).collect::<Vec<_>>().into_iter() } + fn symlink_file<P: AsRef<Path>, Q: AsRef<Path>>(&self, src: P, link: Q) -> io::Result<()> { + #[cfg(unix)] + use std::os::unix::fs::symlink as symlink_file; + #[cfg(windows)] + use std::os::windows::fs::symlink_file; + if !self.config.dry_run() { symlink_file(src.as_ref(), link.as_ref()) } else { Ok(()) } + } + /// Returns if config.ninja is enabled, and checks for ninja existence, /// exiting with a nicer error message if not. fn ninja(&self) -> bool { diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index d6e63fb937e..21157b02a78 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -516,7 +516,7 @@ impl Step for Llvm { let lib_llvm = out_dir.join("build").join("lib").join(lib_name); if !lib_llvm.exists() { - t!(builder.build.config.symlink_file("libLLVM.dylib", &lib_llvm)); + t!(builder.symlink_file("libLLVM.dylib", &lib_llvm)); } } diff --git a/src/bootstrap/setup.rs b/src/bootstrap/setup.rs index a027139df23..4480bce99d7 100644 --- a/src/bootstrap/setup.rs +++ b/src/bootstrap/setup.rs @@ -21,6 +21,7 @@ pub enum Profile { Library, Tools, User, + None, } /// A list of historical hashes of `src/etc/vscode_settings.json`. @@ -41,7 +42,7 @@ impl Profile { pub fn all() -> impl Iterator<Item = Self> { use Profile::*; // N.B. these are ordered by how they are displayed, not alphabetically - [Library, Compiler, Codegen, Tools, User].iter().copied() + [Library, Compiler, Codegen, Tools, User, None].iter().copied() } pub fn purpose(&self) -> String { @@ -52,6 +53,7 @@ impl Profile { Codegen => "Contribute to the compiler, and also modify LLVM or codegen", Tools => "Contribute to tools which depend on the compiler, but do not modify it directly (e.g. rustdoc, clippy, miri)", User => "Install Rust from source", + None => "Do not modify `config.toml`" } .to_string() } @@ -71,6 +73,7 @@ impl Profile { Profile::Library => "library", Profile::Tools => "tools", Profile::User => "user", + Profile::None => "none", } } } @@ -87,6 +90,7 @@ impl FromStr for Profile { "tools" | "tool" | "rustdoc" | "clippy" | "miri" | "rustfmt" | "rls" => { Ok(Profile::Tools) } + "none" => Ok(Profile::None), _ => Err(format!("unknown profile: '{}'", s)), } } @@ -144,17 +148,8 @@ impl Step for Profile { } pub fn setup(config: &Config, profile: Profile) { - let stage_path = - ["build", config.build.rustc_target_arg(), "stage1"].join(&MAIN_SEPARATOR.to_string()); - - if !rustup_installed() && profile != Profile::User { - eprintln!("`rustup` is not installed; cannot link `stage1` toolchain"); - } else if stage_dir_exists(&stage_path[..]) && !config.dry_run() { - attempt_toolchain_link(&stage_path[..]); - } - - let suggestions = match profile { - Profile::Codegen | Profile::Compiler => &["check", "build", "test"][..], + let suggestions: &[&str] = match profile { + Profile::Codegen | Profile::Compiler | Profile::None => &["check", "build", "test"], Profile::Tools => &[ "check", "build", @@ -167,11 +162,6 @@ pub fn setup(config: &Config, profile: Profile) { Profile::User => &["dist", "build"], }; - if !config.dry_run() { - t!(install_git_hook_maybe(&config)); - t!(create_vscode_settings_maybe(&config)); - } - println!(); println!("To get started, try one of the following commands:"); @@ -190,6 +180,9 @@ pub fn setup(config: &Config, profile: Profile) { } fn setup_config_toml(path: &PathBuf, profile: Profile, config: &Config) { + if profile == Profile::None { + return; + } if path.exists() { eprintln!(); eprintln!( @@ -217,6 +210,41 @@ fn setup_config_toml(path: &PathBuf, profile: Profile, config: &Config) { println!("`x.py` will now use the configuration at {}", include_path.display()); } +/// Creates a toolchain link for stage1 using `rustup` +#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] +pub struct Link; +impl Step for Link { + type Output = (); + const DEFAULT: bool = true; + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.alias("link") + } + fn make_run(run: RunConfig<'_>) { + if run.builder.config.dry_run() { + return; + } + if let [cmd] = &run.paths[..] { + if cmd.assert_single_path().path.as_path().as_os_str() == "link" { + run.builder.ensure(Link); + } + } + } + fn run(self, builder: &Builder<'_>) -> Self::Output { + let config = &builder.config; + if config.dry_run() { + return; + } + let stage_path = + ["build", config.build.rustc_target_arg(), "stage1"].join(&MAIN_SEPARATOR.to_string()); + + if !rustup_installed() { + eprintln!("`rustup` is not installed; cannot link `stage1` toolchain"); + } else if stage_dir_exists(&stage_path[..]) && !config.dry_run() { + attempt_toolchain_link(&stage_path[..]); + } + } +} + fn rustup_installed() -> bool { Command::new("rustup") .arg("--version") @@ -394,6 +422,35 @@ fn prompt_user(prompt: &str) -> io::Result<Option<PromptResult>> { } } +/// Installs `src/etc/pre-push.sh` as a Git hook +#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] +pub struct Hook; + +impl Step for Hook { + type Output = (); + const DEFAULT: bool = true; + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.alias("hook") + } + fn make_run(run: RunConfig<'_>) { + if run.builder.config.dry_run() { + return; + } + if let [cmd] = &run.paths[..] { + if cmd.assert_single_path().path.as_path().as_os_str() == "hook" { + run.builder.ensure(Hook); + } + } + } + fn run(self, builder: &Builder<'_>) -> Self::Output { + let config = &builder.config; + if config.dry_run() { + return; + } + t!(install_git_hook_maybe(&config)); + } +} + // install a git hook to automatically run tidy, if they want fn install_git_hook_maybe(config: &Config) -> io::Result<()> { let git = t!(config.git().args(&["rev-parse", "--git-common-dir"]).output().map(|output| { @@ -432,6 +489,35 @@ undesirable, simply delete the `pre-push` file from .git/hooks." Ok(()) } +/// Sets up or displays `src/etc/vscode_settings.json` +#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] +pub struct Vscode; + +impl Step for Vscode { + type Output = (); + const DEFAULT: bool = true; + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.alias("vscode") + } + fn make_run(run: RunConfig<'_>) { + if run.builder.config.dry_run() { + return; + } + if let [cmd] = &run.paths[..] { + if cmd.assert_single_path().path.as_path().as_os_str() == "vscode" { + run.builder.ensure(Vscode); + } + } + } + fn run(self, builder: &Builder<'_>) -> Self::Output { + let config = &builder.config; + if config.dry_run() { + return; + } + t!(create_vscode_settings_maybe(&config)); + } +} + /// Create a `.vscode/settings.json` file for rustc development, or just print it fn create_vscode_settings_maybe(config: &Config) -> io::Result<()> { let (current_hash, historical_hashes) = SETTINGS_HASHES.split_last().unwrap(); diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index d30532ef3c6..3c9a154da9a 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -595,7 +595,7 @@ impl Step for Rustdoc { features.push("jemalloc".to_string()); } - let cargo = prepare_tool_cargo( + let mut cargo = prepare_tool_cargo( builder, build_compiler, Mode::ToolRustc, @@ -606,6 +606,10 @@ impl Step for Rustdoc { features.as_slice(), ); + if builder.config.rustc_parallel { + cargo.rustflag("--cfg=parallel_compiler"); + } + let msg = tooling_output( Mode::ToolRustc, "rustdoc", diff --git a/src/ci/docker/host-x86_64/mingw-check/Dockerfile b/src/ci/docker/host-x86_64/mingw-check/Dockerfile index 4cc5d9f8a0d..98bd90210d6 100644 --- a/src/ci/docker/host-x86_64/mingw-check/Dockerfile +++ b/src/ci/docker/host-x86_64/mingw-check/Dockerfile @@ -23,6 +23,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ RUN curl -sL https://nodejs.org/dist/v16.9.0/node-v16.9.0-linux-x64.tar.xz | tar -xJ ENV PATH="/node-v16.9.0-linux-x64/bin:${PATH}" +ENV RUST_CONFIGURE_ARGS="--set rust.validate-mir-opts=3" + # Install es-check # Pin its version to prevent unrelated CI failures due to future es-check versions. RUN npm install es-check@6.1.1 eslint@8.6.0 -g @@ -38,7 +40,7 @@ COPY host-x86_64/mingw-check/validate-error-codes.sh /scripts/ ENV RUN_CHECK_WITH_PARALLEL_QUERIES 1 ENV SCRIPT python3 ../x.py --stage 2 test src/tools/expand-yaml-anchors && \ - python3 ../x.py check --target=i686-pc-windows-gnu --host=i686-pc-windows-gnu --all-targets && \ + python3 ../x.py check --target=i686-pc-windows-gnu --host=i686-pc-windows-gnu && \ 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 && \ diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version index 94ec2401292..9c550b2d728 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version +++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version @@ -1 +1 @@ -0.14.3 \ No newline at end of file +0.14.4 \ No newline at end of file diff --git a/src/ci/docker/scripts/fuchsia-test-runner.py b/src/ci/docker/scripts/fuchsia-test-runner.py index a6d84a3c18a..c3d532c4b27 100755 --- a/src/ci/docker/scripts/fuchsia-test-runner.py +++ b/src/ci/docker/scripts/fuchsia-test-runner.py @@ -507,9 +507,8 @@ class TestEnvironment: bin/{exe_name}={bin_path} lib/{libstd_name}={rust_dir}/lib/rustlib/{rustlib_dir}/lib/{libstd_name} lib/{libtest_name}={rust_dir}/lib/rustlib/{rustlib_dir}/lib/{libtest_name} - lib/ld.so.1={sdk_dir}/arch/{target_arch}/sysroot/lib/libc.so - lib/libzircon.so={sdk_dir}/arch/{target_arch}/sysroot/lib/libzircon.so - lib/libfdio.so={sdk_dir}/arch/{target_arch}/lib/libfdio.so + lib/ld.so.1={sdk_dir}/arch/{target_arch}/sysroot/dist/lib/ld.so.1 + lib/libfdio.so={sdk_dir}/arch/{target_arch}/dist/libfdio.so """ TEST_ENV_VARS: ClassVar[List[str]] = [ @@ -844,23 +843,34 @@ class TestEnvironment: "--", "--build-id-dir", os.path.join(self.sdk_dir, ".build-id"), - "--build-id-dir", - os.path.join(self.libs_dir(), ".build-id"), ] - # Add rust source if it's available - if args.rust_src is not None: + libs_build_id_path = os.path.join(self.libs_dir(), ".build-id") + if os.path.exists(libs_build_id_path): + # Add .build-id symbols if installed libs have been stripped into a + # .build-id directory command += [ - "--build-dir", - args.rust_src, + "--build-id-dir", + libs_build_id_path, + ] + else: + # If no .build-id directory is detected, then assume that the shared + # libs contain their debug symbols + command += [ + f"--symbol-path={self.rust_dir}/lib/rustlib/{self.target}/lib", ] + # Add rust source if it's available + rust_src_map = None + if args.rust_src is not None: + # This matches the remapped prefix used by compiletest. There's no + # clear way that we can determine this, so it's hard coded. + rust_src_map = f"/rustc/FAKE_PREFIX={args.rust_src}" + # Add fuchsia source if it's available + fuchsia_src_map = None if args.fuchsia_src is not None: - command += [ - "--build-dir", - os.path.join(args.fuchsia_src, "out", "default"), - ] + fuchsia_src_map = f"./../..={args.fuchsia_src}" # Load debug symbols for the test binary and automatically attach if args.test is not None: @@ -883,7 +893,28 @@ class TestEnvironment: test_name, ) + # The fake-test-src-base directory maps to the suite directory + # e.g. tests/ui/foo.rs has a path of rust/fake-test-src-base/foo.rs + fake_test_src_base = os.path.join( + args.rust_src, + "fake-test-src-base", + ) + real_test_src_base = os.path.join( + args.rust_src, + "tests", + args.test.split(os.path.sep)[0], + ) + test_src_map = f"{fake_test_src_base}={real_test_src_base}" + with open(self.zxdb_script_path(), mode="w", encoding="utf-8") as f: + print(f"set source-map += {test_src_map}", file=f) + + if rust_src_map is not None: + print(f"set source-map += {rust_src_map}", file=f) + + if fuchsia_src_map is not None: + print(f"set source-map += {fuchsia_src_map}", file=f) + print(f"attach {test_name[:31]}", file=f) command += [ @@ -900,6 +931,20 @@ class TestEnvironment: # Connect to the running emulator with zxdb subprocess.run(command, env=self.ffx_cmd_env(), check=False) + def syslog(self, args): + subprocess.run( + [ + self.tool_path("ffx"), + "--config", + self.ffx_user_config_path(), + "log", + "--since", + "now", + ], + env=self.ffx_cmd_env(), + check=False, + ) + def start(args): test_env = TestEnvironment.from_args(args) @@ -933,6 +978,12 @@ def debug(args): return 0 +def syslog(args): + test_env = TestEnvironment.read_from_file() + test_env.syslog(args) + return 0 + + def main(): parser = argparse.ArgumentParser() @@ -1028,6 +1079,11 @@ def main(): ) debug_parser.set_defaults(func=debug) + syslog_parser = subparsers.add_parser( + "syslog", help="prints the device syslog" + ) + syslog_parser.set_defaults(func=syslog) + args = parser.parse_args() return args.func(args) diff --git a/src/doc/index.md b/src/doc/index.md index bf08960f338..7c97c16c20b 100644 --- a/src/doc/index.md +++ b/src/doc/index.md @@ -4,6 +4,20 @@ nav { display: none; } +body { + font-family: serif; +} +h1, h2, h3, h4, h5, h6 { + font-family: sans-serif; +} +h3 { + font-size: 1.35rem; +} +h4 { + font-size: 1.1rem; +} + +/* Formatting for docs search bar */ #search-input { width: calc(100% - 58px); } @@ -21,53 +35,74 @@ nav { #search-but:hover, #search-input:focus { border-color: #55a9ff; } -h2 { - font-size: 18px; + +/* Formatting for external link icon */ +svg.external-link { + display: inline-block; + position: relative; + vertical-align: super; + width: 0.7rem; + height: 0.7rem; + padding-left: 2px; + top: 3px; } </style> -Welcome to an overview of the documentation provided by the [Rust project]. -All of these projects are managed by the Docs Team; there are other -unofficial documentation resources as well! +Welcome to an overview of the documentation provided by the [Rust +project]. This page contains links to various helpful references, +most of which are available offline (if opened with `rustup doc`). Many of these +resources take the form of "books"; we collectively call these "The Rust +Bookshelf." Some are large, some are small. -Many of these resources take the form of "books"; we collectively call these -"The Rust Bookshelf." Some are large, some are small. +All of these books are managed by the Rust Organization, but other unofficial +documentation resources are included here as well! -# Learn Rust +If you're just looking for the standard library reference, here it is: +[Rust API documentation](std/index.html) -If you'd like to learn Rust, this is the spot for you! All of these resources + +## Learning Rust + +If you'd like to learn Rust, this is the section for you! All of these resources assume that you have programmed before, but not in any specific language: -## The Rust Programming Language +### The Rust Programming Language -Affectionately nicknamed "the book," [The Rust Programming -Language](book/index.html) will give you an overview of the language from -first principles. You'll build a few projects along the way, and by the end, -you'll have a solid grasp of the language. +Affectionately nicknamed "the book," [The Rust Programming Language](book/index.html) +will give you an overview of the language from first principles. You'll build a +few projects along the way, and by the end, you'll have a solid grasp of how to +use the language. -## Rust By Example +### Rust By Example If reading multiple hundreds of pages about a language isn't your style, then -[Rust By Example](rust-by-example/index.html) has you covered. While the book talks about code with -a lot of words, RBE shows off a bunch of code, and keeps the talking to a -minimum. It also includes exercises! +[Rust By Example](rust-by-example/index.html) has you covered. RBE shows off a +bunch of code without using a lot of words. It also includes exercises! + +### Rustlings + +[Rustlings](https://github.com/rust-lang/rustlings) guides you +through downloading and setting up the Rust toolchain, then provides an +interactive tool that teaches you how to solve coding challenges in Rust. + +### Rust Playground -## Rustlings +The [Rust Playground](https://play.rust-lang.org) is a great place +to try out and share small bits of code, or experiment with some of the most +popular crates. -[Rustlings](https://github.com/rust-lang/rustlings) guides you through downloading and setting up the Rust toolchain, -and teaches you the basics of reading and writing Rust syntax. It's an -alternative to Rust by Example that works with your own environment. -# Use Rust +## Using Rust -Once you've gotten familiar with the language, these resources can help you -when you're actually using it day-to-day. +Once you've gotten familiar with the language, these resources can help you put +it to work. -## The Standard Library +### The Standard Library -Rust's standard library has [extensive API documentation](std/index.html), -with explanations of how to use various things, as well as example code for -accomplishing various tasks. +Rust's standard library has [extensive API documentation](std/index.html), with +explanations of how to use various things, as well as example code for +accomplishing various tasks. Code examples have a "Run" button on hover that +opens the sample in the playground. <div> <form action="std/index.html" method="get"> @@ -77,76 +112,143 @@ accomplishing various tasks. </form> </div> -## The Edition Guide +### Your Personal Documentation -[The Edition Guide](edition-guide/index.html) describes the Rust editions. +Whenever you are working in a crate, `cargo doc --open` will generate +documentation for your project _and_ all its dependencies in their correct +version, and open it in your browser. Add the flag `--document-private-items` to +also show items not marked `pub`. -## The Rustc Book +### The Edition Guide -[The Rustc Book](rustc/index.html) describes the Rust compiler, `rustc`. +[The Edition Guide](edition-guide/index.html) describes the Rust editions and +their differences. -## The Cargo Book +### The `rustc` Book -[The Cargo Book](cargo/index.html) is a guide to Cargo, Rust's build tool and dependency manager. +[The `rustc` Book](rustc/index.html) describes the Rust compiler, `rustc`. -## The Rustdoc Book +### The Cargo Book + +[The Cargo Book](cargo/index.html) is a guide to Cargo, Rust's build tool and +dependency manager. + +### The Rustdoc Book [The Rustdoc Book](rustdoc/index.html) describes our documentation tool, `rustdoc`. -## The Clippy Book +### The Clippy Book [The Clippy Book](clippy/index.html) describes our static analyzer, Clippy. -## Extended Error Listing +### Extended Error Listing Many of Rust's errors come with error codes, and you can request extended -diagnostics from the compiler on those errors. You can also [read them -here](error_codes/index.html), if you prefer to read them that way. +diagnostics from the compiler on those errors (with `rustc --explain`). You can +also read them here if you prefer: [rustc error codes](error_codes/index.html) + -# Master Rust +## Mastering Rust Once you're quite familiar with the language, you may find these advanced resources useful. -## The Reference +### The Reference -[The Reference](reference/index.html) is not a formal spec, but is more detailed and -comprehensive than the book. +[The Reference](reference/index.html) is not a formal spec, but is more detailed +and comprehensive than the book. -## The Style Guide +### The Style Guide -[The Rust Style Guide](style-guide/index.html) describes the standard formatting of Rust -code. Most developers use rustfmt to format their code, and rustfmt's default -formatting matches this style guide. +[The Rust Style Guide](style-guide/index.html) describes the standard formatting +of Rust code. Most developers use `cargo fmt` to invoke `rustfmt` and format the +code automatically (the result matches this style guide). -## The Rustonomicon +### The Rustonomicon -[The Rustonomicon](nomicon/index.html) is your guidebook to the dark arts of unsafe -Rust. It's also sometimes called "the 'nomicon." +[The Rustonomicon](nomicon/index.html) is your guidebook to the dark arts of +unsafe Rust. It's also sometimes called "the 'nomicon." -## The Unstable Book +### The Unstable Book -[The Unstable Book](unstable-book/index.html) has documentation for unstable features. +[The Unstable Book](unstable-book/index.html) has documentation for unstable +features. -## The `rustc` Contribution Guide +### The `rustc` Contribution Guide -[The `rustc` Guide](https://rustc-dev-guide.rust-lang.org/) documents how -the compiler works and how to contribute to it. This is useful if you want to build -or modify the Rust compiler from source (e.g. to target something non-standard). +[The `rustc` Guide](https://rustc-dev-guide.rust-lang.org/) +documents how the compiler works and how to contribute to it. This is useful if +you want to build or modify the Rust compiler from source (e.g. to target +something non-standard). -# Specialize Rust -When using Rust in specific domain areas, consider using the following resources tailored to each domain. +## Specialized Rust -## Embedded Systems +When using Rust in specific domains, consider using the following resources +tailored to each area. -When developing for Bare Metal or Embedded Linux systems, you may find these resources maintained by the [Embedded Working Group] useful. +### Embedded Systems + +When developing for Bare Metal or Embedded Linux systems, you may find these +resources maintained by the [Embedded Working Group] useful. [Embedded Working Group]: https://github.com/rust-embedded -### The Embedded Rust Book +#### The Embedded Rust Book -[The Embedded Rust Book] is targeted at developers familiar with embedded development and familiar with Rust, but have not used Rust for embedded development. +[The Embedded Rust Book] is targeted at developers familiar with embedded +development and familiar with Rust, but have not used Rust for embedded +development. [The Embedded Rust Book]: embedded-book/index.html [Rust project]: https://www.rust-lang.org + +<script> +// check if a given link is external +function isExternalLink(url) { + const tmp = document.createElement('a'); + tmp.href = url; + return tmp.host !== window.location.host; +} + +// Add the `external` class to all <a> tags with external links and append the external link SVG +function updateExternalAnchors() { + /* + External link SVG from Font-Awesome + CC BY-SA 3.0 https://creativecommons.org/licenses/by-sa/3.0 + via Wikimedia Commons + */ + const svgText = `<svg + class='external-link' + xmlns='http://www.w3.org/2000/svg' + viewBox='0 -256 1850 1850' + width='100%' + height='100%'> + <g transform='matrix(1,0,0,-1,30,1427)'> + <path d='M 1408,608 V 288 Q 1408,169 1323.5,84.5 1239,0 1120, + 0 H 288 Q 169,0 84.5,84.5 0,169 0,288 v 832 Q 0,1239 84.5,1323.5 169, + 1408 288,1408 h 704 q 14,0 23,-9 9,-9 9,-23 v -64 q 0,-14 -9,-23 -9, + -9 -23,-9 H 288 q -66,0 -113,-47 -47,-47 -47,-113 V 288 q 0,-66 47, + -113 47,-47 113,-47 h 832 q 66,0 113,47 47,47 47,113 v 320 q 0,14 9, + 23 9,9 23,9 h 64 q 14,0 23,-9 9,-9 9,-23 z m 384,864 V 960 q 0, + -26 -19,-45 -19,-19 -45,-19 -26,0 -45,19 L 1507,1091 855,439 q -10, + -10 -23,-10 -13,0 -23,10 L 695,553 q -10,10 -10,23 0,13 10,23 l 652, + 652 -176,176 q -19,19 -19,45 0,26 19,45 19,19 45,19 h 512 q 26,0 45, + -19 19,-19 19,-45 z' style='fill:currentColor' /> + </g> + </svg>`; + let allAnchors = document.getElementsByTagName("a"); + + for (var i = 0; i < allAnchors.length; ++i) { + let anchor = allAnchors[i]; + if (isExternalLink(anchor.href)) { + anchor.classList.add("external"); + anchor.innerHTML += svgText; + } + } +} + +// on page load, update external anchors +document.addEventListener("DOMContentLoaded", updateExternalAnchors); + +</script> diff --git a/src/doc/rustc/src/platform-support/fuchsia.md b/src/doc/rustc/src/platform-support/fuchsia.md index 0f165b268ba..63dde2aaedd 100644 --- a/src/doc/rustc/src/platform-support/fuchsia.md +++ b/src/doc/rustc/src/platform-support/fuchsia.md @@ -687,7 +687,9 @@ Rust compiler locally. See "[Targeting Fuchsia with a compiler built from source for the steps to build locally. You'll also need to download a copy of the Fuchsia SDK. The current minimum -supported SDK version is [9.20220726.1.1](https://chrome-infra-packages.appspot.com/p/fuchsia/sdk/core/linux-amd64/+/version:9.20220726.1.1). +supported SDK version is [10.20221207.2.89][minimum_supported_sdk_version]. + +[minimum_supported_sdk_version]: https://chrome-infra-packages.appspot.com/p/fuchsia/sdk/core/linux-amd64/+/version:10.20221207.2.89 Fuchsia's test runner interacts with the Fuchsia emulator and is located at `src/ci/docker/scripts/fuchsia-test-runner.py`. We can use it to start our @@ -697,7 +699,7 @@ test environment with: src/ci/docker/scripts/fuchsia-test-runner.py start --rust ${RUST_SRC_PATH}/install --sdk ${SDK_PATH} - --target-triple {x86_64-unknown-fuchsia|aarch64-unknown-fuchsia} + --target {x86_64-unknown-fuchsia|aarch64-unknown-fuchsia} ``` Where `${RUST_SRC_PATH}/install` is the `prefix` set in `config.toml` and @@ -717,17 +719,11 @@ run the full `tests/ui` test suite: --target x86_64-unknown-fuchsia \ --run=always --jobs 1 \ --test-args --target-rustcflags \ - --test-args -L \ - --test-args --target-rustcflags \ - --test-args ${SDK_PATH}/arch/{x64|arm64}/sysroot/lib \ - --test-args --target-rustcflags \ - --test-args -L \ + --test-args -Lnative=${SDK_PATH}/arch/{x64|arm64}/sysroot/lib \ --test-args --target-rustcflags \ - --test-args ${SDK_PATH}/arch/{x64|arm64}/lib \ + --test-args -Lnative=${SDK_PATH}/arch/{x64|arm64}/lib \ --test-args --target-rustcflags \ - --test-args -Cpanic=abort \ - --test-args --target-rustcflags \ - --test-args -Zpanic_abort_tests \ + --test-args -Clink-arg=--undefined-version \ --test-args --remote-test-client \ --test-args src/ci/docker/scripts/fuchsia-test-runner.py \ ) @@ -736,7 +732,18 @@ run the full `tests/ui` test suite: *Note: The test suite cannot be run in parallel at the moment, so `x.py` must be run with `--jobs 1` to ensure only one test runs at a time.* -When finished, the test runner can be used to stop the test environment: +By default, `x.py` compiles test binaries with `panic=unwind`. If you built your +Rust toolchain with `-Cpanic=abort`, you need to tell `x.py` to compile test +binaries with `panic=abort` as well: + +```sh + --test-args --target-rustcflags \ + --test-args -Cpanic=abort \ + --test-args --target-rustcflags \ + --test-args -Zpanic_abort_tests \ +``` + +When finished testing, the test runner can be used to stop the test environment: ```sh src/ci/docker/scripts/fuchsia-test-runner.py stop @@ -764,8 +771,9 @@ ${SDK_PATH}/tools/${ARCH}/ffx debug connect -- \ * `--symbol-path` gets required symbol paths, which are necessary for stepping through your program. -The "[displaying source code in `zxdb`](#displaying-source-code-in-zxdb)" section describes how you can -display Rust and/or Fuchsia source code in your debugging session. +The "[displaying source code in `zxdb`](#displaying-source-code-in-zxdb)" +section describes how you can display Rust and/or Fuchsia source code in your +debugging session. ### Using `zxdb` @@ -866,6 +874,64 @@ ${SDK_PATH}/tools/${ARCH}/ffx debug connect -- \ Linking to a Fuchsia checkout can help with debugging Fuchsia libraries, such as [fdio]. +### Debugging the compiler test suite + +Debugging the compiler test suite requires some special configuration: + +First, we have to properly configure zxdb so it will be able to find debug +symbols and source information for our test. The test runner can do this for us +with: + +```sh +src/ci/docker/scripts/fuchsia-test-runner.py debug \ + --rust-src ${RUST_SRC_PATH} \ + --fuchsia-src ${FUCHSIA_SRC_PATH} \ + --test ${TEST} +``` + +where `${TEST}` is relative to Rust's `tests` directory (e.g. `ui/abi/...`). + +This will start a zxdb session that is properly configured for the specific test +being run. All three arguments are optional, so you can omit `--fuchsia-src` if +you don't have it downloaded. Now is a good time to set any desired breakpoints, +like `b main`. + +Next, we have to tell `x.py` not to optimize or strip debug symbols from our +test suite binaries. We can do this by passing some new arguments to `rustc` +through our `x.py` invocation. The full invocation is: + +```sh +( \ + source config-env.sh && \ + ./x.py \ + --config config.toml \ + --stage=2 \ + test tests/${TEST} \ + --target x86_64-unknown-fuchsia \ + --run=always --jobs 1 \ + --test-args --target-rustcflags \ + --test-args -Lnative=${SDK_PATH}/arch/{x64|arm64}/sysroot/lib \ + --test-args --target-rustcflags \ + --test-args -Lnative=${SDK_PATH}/arch/{x64|arm64}/lib \ + --test-args --target-rustcflags \ + --test-args -Clink-arg=--undefined-version \ + --test-args --target-rustcflags \ + --test-args -Cdebuginfo=2 \ + --test-args --target-rustcflags \ + --test-args -Copt-level=0 \ + --test-args --target-rustcflags \ + --test-args -Cstrip=none \ + --test-args --remote-test-client \ + --test-args src/ci/docker/scripts/fuchsia-test-runner.py \ +) +``` + +*If you built your Rust toolchain with `panic=abort`, make sure to include the +previous flags so your test binaries are also compiled with `panic=abort`.* + +Upon running this command, the test suite binary will be run and zxdb will +attach and load any relevant debug symbols. + [Fuchsia team]: https://team-api.infra.rust-lang.org/v1/teams/fuchsia.json [Fuchsia]: https://fuchsia.dev/ [source tree]: https://fuchsia.dev/fuchsia-src/get-started/learn/build diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index 5e592227d49..c48f7998c5a 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -18,7 +18,6 @@ serde_json = "1.0" serde = { version = "1.0", features = ["derive"] } smallvec = "1.8.1" tempfile = "3" -thin-vec = "0.2.9" tracing = "0.1" tracing-tree = "0.2.0" diff --git a/src/librustdoc/clean/cfg/tests.rs b/src/librustdoc/clean/cfg/tests.rs index 81f67672436..bb62660e194 100644 --- a/src/librustdoc/clean/cfg/tests.rs +++ b/src/librustdoc/clean/cfg/tests.rs @@ -4,6 +4,7 @@ use rustc_ast::{LitKind, MetaItemLit, Path, StrStyle}; use rustc_span::create_default_session_globals_then; use rustc_span::symbol::{kw, Ident, Symbol}; use rustc_span::DUMMY_SP; +use thin_vec::thin_vec; fn word_cfg(s: &str) -> Cfg { Cfg::Cfg(Symbol::intern(s), None) @@ -34,7 +35,7 @@ macro_rules! dummy_meta_item_list { ($name:ident, [$($list:ident),* $(,)?]) => { MetaItem { path: Path::from_ident(Ident::from_str(stringify!($name))), - kind: MetaItemKind::List(vec![ + kind: MetaItemKind::List(thin_vec![ $( NestedMetaItem::MetaItem( dummy_meta_item_word(stringify!($list)), @@ -48,7 +49,7 @@ macro_rules! dummy_meta_item_list { ($name:ident, [$($list:expr),* $(,)?]) => { MetaItem { path: Path::from_ident(Ident::from_str(stringify!($name))), - kind: MetaItemKind::List(vec![ + kind: MetaItemKind::List(thin_vec![ $( NestedMetaItem::MetaItem($list), )* diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 0c70d31ed60..0e8f0cfc518 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -22,9 +22,9 @@ use rustc_hir::PredicateOrigin; use rustc_hir_analysis::hir_ty_to_ty; use rustc_infer::infer::region_constraints::{Constraint, RegionConstraintData}; use rustc_middle::middle::resolve_bound_vars as rbv; -use rustc_middle::ty::fold::ir::TypeFolder; +use rustc_middle::ty::fold::TypeFolder; use rustc_middle::ty::InternalSubsts; -use rustc_middle::ty::TypeVisitable; +use rustc_middle::ty::TypeVisitableExt; use rustc_middle::ty::{self, AdtKind, DefIdTree, EarlyBinder, Ty, TyCtxt}; use rustc_middle::{bug, span_bug}; use rustc_span::hygiene::{AstPass, MacroKind}; @@ -77,7 +77,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext< // This covers the case where somebody does an import which should pull in an item, // but there's already an item with the same namespace and same name. Rust gives // priority to the not-imported one, so we should, too. - items.extend(doc.items.iter().flat_map(|(item, renamed, import_id)| { + items.extend(doc.items.values().flat_map(|(item, renamed, import_id)| { // First, lower everything other than imports. if matches!(item.kind, hir::ItemKind::Use(_, hir::UseKind::Glob)) { return Vec::new(); @@ -90,7 +90,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext< } v })); - items.extend(doc.items.iter().flat_map(|(item, renamed, _)| { + items.extend(doc.items.values().flat_map(|(item, renamed, _)| { // Now we actually lower the imports, skipping everything else. if let hir::ItemKind::Use(path, hir::UseKind::Glob) = item.kind { let name = renamed.unwrap_or_else(|| cx.tcx.hir().name(item.hir_id())); @@ -1661,7 +1661,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T } TyKind::BareFn(barefn) => BareFunction(Box::new(clean_bare_fn_ty(barefn, cx))), // Rustdoc handles `TyKind::Err`s by turning them into `Type::Infer`s. - TyKind::Infer | TyKind::Err | TyKind::Typeof(..) => Infer, + TyKind::Infer | TyKind::Err(_) | TyKind::Typeof(..) => Infer, } } @@ -2114,17 +2114,29 @@ fn get_all_import_attributes<'hir>( attributes: &mut Vec<ast::Attribute>, is_inline: bool, ) { + let mut first = true; let hir_map = tcx.hir(); let mut visitor = OneLevelVisitor::new(hir_map, target_def_id); let mut visited = FxHashSet::default(); + // If the item is an import and has at least a path with two parts, we go into it. while let hir::ItemKind::Use(path, _) = item.kind && visited.insert(item.hir_id()) { - // We add the attributes from this import into the list. - add_without_unwanted_attributes(attributes, hir_map.attrs(item.hir_id()), is_inline); + if first { + // This is the "original" reexport so we get all its attributes without filtering them. + attributes.extend_from_slice(hir_map.attrs(item.hir_id())); + first = false; + } else { + add_without_unwanted_attributes(attributes, hir_map.attrs(item.hir_id()), is_inline); + } - let def_id = if path.segments.len() > 1 { - match path.segments[path.segments.len() - 2].res { + let def_id = if let [.., parent_segment, _] = &path.segments { + match parent_segment.res { hir::def::Res::Def(_, def_id) => def_id, + _ if parent_segment.ident.name == kw::Crate => { + // In case the "parent" is the crate, it'll give `Res::Err` so we need to + // circumvent it this way. + tcx.parent(item.owner_id.def_id.to_def_id()) + } _ => break, } } else { @@ -2341,9 +2353,7 @@ fn clean_maybe_renamed_item<'tcx>( if let Some(import_id) = import_id && let Some(hir::Node::Item(use_node)) = cx.tcx.hir().find_by_def_id(import_id) { - // First, we add the attributes from the current import. - extra_attrs.extend_from_slice(inline::load_attrs(cx, import_id.to_def_id())); - let is_inline = extra_attrs.lists(sym::doc).get_word_attr(sym::inline).is_some(); + let is_inline = inline::load_attrs(cx, import_id.to_def_id()).lists(sym::doc).get_word_attr(sym::inline).is_some(); // Then we get all the various imports' attributes. get_all_import_attributes(use_node, cx.tcx, item.owner_id.def_id, &mut extra_attrs, is_inline); add_without_unwanted_attributes(&mut extra_attrs, inline::load_attrs(cx, def_id), is_inline); diff --git a/src/librustdoc/clean/render_macro_matchers.rs b/src/librustdoc/clean/render_macro_matchers.rs index ed7683e36fd..ef38ca3c16c 100644 --- a/src/librustdoc/clean/render_macro_matchers.rs +++ b/src/librustdoc/clean/render_macro_matchers.rs @@ -63,7 +63,8 @@ fn snippet_equal_to_token(tcx: TyCtxt<'_>, matcher: &TokenTree) -> Option<String let snippet = source_map.span_to_snippet(span).ok()?; // Create a Parser. - let sess = ParseSess::new(FilePathMapping::empty()); + let sess = + ParseSess::new(rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), FilePathMapping::empty()); let file_name = source_map.span_to_filename(span); let mut parser = match rustc_parse::maybe_new_parser_from_source_str(&sess, file_name, snippet.clone()) { diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 5a564c2ac1c..c9c1c2c458a 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -470,6 +470,12 @@ pub(crate) fn get_auto_trait_and_blanket_impls( cx: &mut DocContext<'_>, item_def_id: DefId, ) -> impl Iterator<Item = Item> { + // FIXME: To be removed once `parallel_compiler` bugs are fixed! + // More information in <https://github.com/rust-lang/rust/pull/106930>. + if cfg!(parallel_compiler) { + return vec![].into_iter().chain(vec![].into_iter()); + } + let auto_impls = cx .sess() .prof diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 5ab7056be44..fbfc58a436b 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -115,8 +115,10 @@ pub(crate) fn new_handler( diagnostic_width: Option<usize>, unstable_opts: &UnstableOptions, ) -> rustc_errors::Handler { - let fallback_bundle = - rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false); + let fallback_bundle = rustc_errors::fallback_fluent_bundle( + rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), + false, + ); let emitter: Box<dyn Emitter + sync::Send> = match error_format { ErrorOutputType::HumanReadable(kind) => { let (short, color_config) = kind.unzip(); @@ -254,6 +256,7 @@ pub(crate) fn create_config( output_file: None, output_dir: None, file_loader: None, + locale_resources: rustc_driver::DEFAULT_LOCALE_RESOURCES, lint_caps, parse_sess_created: None, register_lints: Some(Box::new(crate::lint::register_lints)), diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 0eba81c7c1e..8a73d25d3f0 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -96,6 +96,7 @@ pub(crate) fn run(options: RustdocOptions) -> Result<(), ErrorGuaranteed> { output_file: None, output_dir: None, file_loader: None, + locale_resources: rustc_driver::DEFAULT_LOCALE_RESOURCES, lint_caps, parse_sess_created: None, register_lints: Some(Box::new(crate::lint::register_lints)), @@ -545,8 +546,10 @@ pub(crate) fn make_test( // Any errors in parsing should also appear when the doctest is compiled for real, so just // send all the errors that librustc_ast emits directly into a `Sink` instead of stderr. let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let fallback_bundle = - rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false); + let fallback_bundle = rustc_errors::fallback_fluent_bundle( + rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), + false, + ); supports_color = EmitterWriter::stderr( ColorConfig::Auto, None, @@ -741,8 +744,10 @@ fn check_if_attr_is_complete(source: &str, edition: Edition) -> bool { // Any errors in parsing should also appear when the doctest is compiled for real, so just // send all the errors that librustc_ast emits directly into a `Sink` instead of stderr. let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let fallback_bundle = - rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false); + let fallback_bundle = rustc_errors::fallback_fluent_bundle( + rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), + false, + ); let emitter = EmitterWriter::new( Box::new(io::sink()), diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index aa406f30cbe..6bdd9db9bfa 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -775,7 +775,7 @@ pub(crate) fn link_tooltip(did: DefId, fragment: &Option<UrlFragment>, cx: &Cont let fqp = fqp.iter().map(|sym| sym.as_str()).join("::"); if let &Some(UrlFragment::Item(id)) = fragment { let name = cx.tcx().item_name(id); - let descr = cx.tcx().def_kind(id).descr(id); + let descr = cx.tcx().def_descr(id); format!("{descr} {fqp}::{name}") } else { format!("{shortty} {fqp}") diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 9ef0b501c08..89f1ad71134 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -552,10 +552,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> SummaryLine<'a, I> { } fn check_if_allowed_tag(t: &Tag<'_>) -> bool { - matches!( - t, - Tag::Paragraph | Tag::Item | Tag::Emphasis | Tag::Strong | Tag::Link(..) | Tag::BlockQuote - ) + matches!(t, Tag::Paragraph | Tag::Emphasis | Tag::Strong | Tag::Link(..) | Tag::BlockQuote) } fn is_forbidden_tag(t: &Tag<'_>) -> bool { diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 910a7190b58..4fcf0873600 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -20,6 +20,7 @@ #![allow(clippy::collapsible_if, clippy::collapsible_else_if)] #![allow(rustc::potential_query_instability)] +extern crate thin_vec; #[macro_use] extern crate tracing; diff --git a/src/librustdoc/passes/lint/check_code_block_syntax.rs b/src/librustdoc/passes/lint/check_code_block_syntax.rs index 03be5e79971..26fbb03a43e 100644 --- a/src/librustdoc/passes/lint/check_code_block_syntax.rs +++ b/src/librustdoc/passes/lint/check_code_block_syntax.rs @@ -33,8 +33,10 @@ fn check_rust_syntax( code_block: RustCodeBlock, ) { let buffer = Lrc::new(Lock::new(Buffer::default())); - let fallback_bundle = - rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false); + let fallback_bundle = rustc_errors::fallback_fluent_bundle( + rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), + false, + ); let emitter = BufferEmitter { buffer: Lrc::clone(&buffer), fallback_bundle }; let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 9c1e5f4a3cd..277201e4de9 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -1,7 +1,7 @@ //! The Rust AST Visitor. Extracts useful information and massages it into a form //! usable for `clean`. -use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId, LocalDefIdSet}; @@ -26,8 +26,12 @@ pub(crate) struct Module<'hir> { pub(crate) where_inner: Span, pub(crate) mods: Vec<Module<'hir>>, pub(crate) def_id: LocalDefId, - // (item, renamed, import_id) - pub(crate) items: Vec<(&'hir hir::Item<'hir>, Option<Symbol>, Option<LocalDefId>)>, + /// The key is the item `ItemId` and the value is: (item, renamed, import_id). + /// We use `FxIndexMap` to keep the insert order. + pub(crate) items: FxIndexMap< + (LocalDefId, Option<Symbol>), + (&'hir hir::Item<'hir>, Option<Symbol>, Option<LocalDefId>), + >, pub(crate) foreigns: Vec<(&'hir hir::ForeignItem<'hir>, Option<Symbol>)>, } @@ -38,7 +42,7 @@ impl Module<'_> { def_id, where_inner, mods: Vec::new(), - items: Vec::new(), + items: FxIndexMap::default(), foreigns: Vec::new(), } } @@ -136,7 +140,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { inserted.insert(def_id) { let item = self.cx.tcx.hir().expect_item(local_def_id); - top_level_module.items.push((item, None, None)); + top_level_module.items.insert((local_def_id, Some(item.ident.name)), (item, None, None)); } } @@ -294,7 +298,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { renamed: Option<Symbol>, parent_id: Option<LocalDefId>, ) { - self.modules.last_mut().unwrap().items.push((item, renamed, parent_id)) + self.modules + .last_mut() + .unwrap() + .items + .insert((item.owner_id.def_id, renamed), (item, renamed, parent_id)); } fn visit_item_inner( diff --git a/src/tools/cargo b/src/tools/cargo -Subproject 17b3d0de0897e1c6b8ca347bd39f850bb0a5b9f +Subproject 9d5b32f503fc099c4064298465add14d4bce11e diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs index b4543aa2544..644604a2e3f 100644 --- a/src/tools/clippy/clippy_lints/src/dereference.rs +++ b/src/tools/clippy/clippy_lints/src/dereference.rs @@ -27,7 +27,7 @@ use rustc_middle::mir::{Rvalue, StatementKind}; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability}; use rustc_middle::ty::{ self, Binder, BoundVariableKind, Clause, EarlyBinder, FnSig, GenericArgKind, List, ParamTy, PredicateKind, - ProjectionPredicate, Ty, TyCtxt, TypeVisitable, TypeckResults, + ProjectionPredicate, Ty, TyCtxt, TypeVisitableExt, TypeckResults, }; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::{symbol::sym, Span, Symbol}; @@ -1022,7 +1022,7 @@ fn binding_ty_auto_deref_stability<'tcx>( )) .is_sized(cx.tcx, cx.param_env.without_caller_bounds()), ), - TyKind::OpaqueDef(..) | TyKind::Infer | TyKind::Typeof(..) | TyKind::TraitObject(..) | TyKind::Err => { + TyKind::OpaqueDef(..) | TyKind::Infer | TyKind::Typeof(..) | TyKind::TraitObject(..) | TyKind::Err(_) => { Position::ReborrowStable(precedence) }, }; @@ -1038,7 +1038,7 @@ fn ty_contains_infer(ty: &hir::Ty<'_>) -> bool { if self.0 || matches!( ty.kind, - TyKind::OpaqueDef(..) | TyKind::Infer | TyKind::Typeof(_) | TyKind::Err + TyKind::OpaqueDef(..) | TyKind::Infer | TyKind::Typeof(_) | TyKind::Err(_) ) { self.0 = true; diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs index 1cdcccd5f14..b8428d66a5d 100644 --- a/src/tools/clippy/clippy_lints/src/derive.rs +++ b/src/tools/clippy/clippy_lints/src/derive.rs @@ -514,7 +514,7 @@ fn param_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId) -> } ParamEnv::new( - tcx.mk_predicates(ty_predicates.iter().map(|&(p, _)| p).chain( + tcx.mk_predicates_from_iter(ty_predicates.iter().map(|&(p, _)| p).chain( params.iter().filter(|&&(_, needs_eq)| needs_eq).map(|&(param, _)| { tcx.mk_predicate(Binder::dummy(PredicateKind::Clause(Clause::Trait(TraitPredicate { trait_ref: tcx.mk_trait_ref(eq_trait_id, [tcx.mk_param_from_def(param)]), diff --git a/src/tools/clippy/clippy_lints/src/doc.rs b/src/tools/clippy/clippy_lints/src/doc.rs index 0b31e20fc87..6fdb7de25cc 100644 --- a/src/tools/clippy/clippy_lints/src/doc.rs +++ b/src/tools/clippy/clippy_lints/src/doc.rs @@ -704,8 +704,10 @@ fn check_code(cx: &LateContext<'_>, text: &str, edition: Edition, span: Span) { let filename = FileName::anon_source_code(&code); let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let fallback_bundle = - rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false); + let fallback_bundle = rustc_errors::fallback_fluent_bundle( + rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), + false + ); let emitter = EmitterWriter::new( Box::new(io::sink()), None, diff --git a/src/tools/clippy/clippy_lints/src/eta_reduction.rs b/src/tools/clippy/clippy_lints/src/eta_reduction.rs index ddade65c515..b2071f4dcb1 100644 --- a/src/tools/clippy/clippy_lints/src/eta_reduction.rs +++ b/src/tools/clippy/clippy_lints/src/eta_reduction.rs @@ -11,7 +11,7 @@ use rustc_hir::{Closure, Expr, ExprKind, Param, PatKind, Unsafety}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow}; use rustc_middle::ty::binding::BindingMode; -use rustc_middle::ty::{self, EarlyBinder, SubstsRef, Ty, TypeVisitable}; +use rustc_middle::ty::{self, EarlyBinder, SubstsRef, Ty, TypeVisitableExt}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::symbol::sym; diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs index 565c5b7af00..9011f0896a0 100644 --- a/src/tools/clippy/clippy_lints/src/lib.rs +++ b/src/tools/clippy/clippy_lints/src/lib.rs @@ -42,6 +42,7 @@ extern crate rustc_session; extern crate rustc_span; extern crate rustc_target; extern crate rustc_trait_selection; +extern crate thin_vec; #[macro_use] extern crate clippy_utils; diff --git a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs index 14f161f5102..d7e00047312 100644 --- a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs +++ b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs @@ -224,7 +224,7 @@ fn never_loop_expr(expr: &Expr<'_>, ignore_ids: &mut Vec<HirId>, main_loop_id: H | ExprKind::Path(_) | ExprKind::ConstBlock(_) | ExprKind::Lit(_) - | ExprKind::Err => NeverLoopResult::Otherwise, + | ExprKind::Err(_) => NeverLoopResult::Otherwise, } } diff --git a/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs b/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs index f587c69f730..b33a2478172 100644 --- a/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs +++ b/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs @@ -341,7 +341,7 @@ impl<'a, 'tcx> Visitor<'tcx> for SigDropHelper<'a, 'tcx> { ExprKind::ConstBlock(_) | ExprKind::Continue(_) | ExprKind::DropTemps(_) | - ExprKind::Err | + ExprKind::Err(_) | ExprKind::InlineAsm(_) | ExprKind::Let(_) | ExprKind::Lit(_) | diff --git a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs index 8ddbacc3d7a..0b0c6adc504 100644 --- a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs +++ b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs @@ -173,7 +173,7 @@ fn is_contains_sig(cx: &LateContext<'_>, call_id: HirId, iter_expr: &Expr<'_>) - && let Some(iter_item) = cx.tcx .associated_items(iter_trait) .find_by_name_and_kind(cx.tcx, Ident::with_dummy_span(Symbol::intern("Item")), AssocKind::Type, iter_trait) - && let substs = cx.tcx.intern_substs(&[GenericArg::from(typeck.expr_ty_adjusted(iter_expr))]) + && let substs = cx.tcx.mk_substs(&[GenericArg::from(typeck.expr_ty_adjusted(iter_expr))]) && let proj_ty = cx.tcx.mk_projection(iter_item.def_id, substs) && let Ok(item_ty) = cx.tcx.try_normalize_erasing_regions(cx.param_env, proj_ty) { diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs index 4e5af1c7c71..df26b36b7b3 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs @@ -414,7 +414,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty< } }); - let new_subst = cx.tcx.mk_substs( + let new_subst = cx.tcx.mk_substs_from_iter( call_substs.iter() .enumerate() .map(|(i, t)| diff --git a/src/tools/clippy/clippy_lints/src/mut_key.rs b/src/tools/clippy/clippy_lints/src/mut_key.rs index 3cc765108d7..5a533261cad 100644 --- a/src/tools/clippy/clippy_lints/src/mut_key.rs +++ b/src/tools/clippy/clippy_lints/src/mut_key.rs @@ -3,7 +3,7 @@ use clippy_utils::{def_path_def_ids, trait_ref_of_method}; use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty::TypeVisitable; +use rustc_middle::ty::TypeVisitableExt; use rustc_middle::ty::{Adt, Array, Ref, Slice, Tuple, Ty}; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::def_id::LocalDefId; diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs index 996ea6ed723..da3b6fa9899 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs @@ -18,7 +18,7 @@ use rustc_hir_typeck::expr_use_visitor as euv; use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::mir::FakeReadCause; -use rustc_middle::ty::{self, TypeVisitable}; +use rustc_middle::ty::{self, TypeVisitableExt}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::def_id::LocalDefId; use rustc_span::symbol::kw; diff --git a/src/tools/clippy/clippy_lints/src/operators/cmp_owned.rs b/src/tools/clippy/clippy_lints/src/operators/cmp_owned.rs index 24aeb82a37f..d3de9699fe9 100644 --- a/src/tools/clippy/clippy_lints/src/operators/cmp_owned.rs +++ b/src/tools/clippy/clippy_lints/src/operators/cmp_owned.rs @@ -49,10 +49,10 @@ fn check_op(cx: &LateContext<'_>, expr: &Expr<'_>, other: &Expr<'_>, left: bool) (arg, arg.span) }, ExprKind::Call(path, [arg]) - if path_def_id(cx, path).map_or(false, |id| { - if match_def_path(cx, id, &paths::FROM_STR_METHOD) { + if path_def_id(cx, path).map_or(false, |did| { + if match_def_path(cx, did, &paths::FROM_STR_METHOD) { true - } else if cx.tcx.lang_items().from_fn() == Some(id) { + } else if cx.tcx.is_diagnostic_item(sym::from_fn, did) { !is_copy(cx, typeck.expr_ty(expr)) } else { false diff --git a/src/tools/clippy/clippy_lints/src/redundant_slicing.rs b/src/tools/clippy/clippy_lints/src/redundant_slicing.rs index 398329e455b..2fdd775ad48 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_slicing.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_slicing.rs @@ -134,7 +134,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantSlicing { } else if let Some(target_id) = cx.tcx.lang_items().deref_target() { if let Ok(deref_ty) = cx.tcx.try_normalize_erasing_regions( cx.param_env, - cx.tcx.mk_projection(target_id, cx.tcx.intern_substs(&[GenericArg::from(indexed_ty)])), + cx.tcx.mk_projection(target_id, cx.tcx.mk_substs(&[GenericArg::from(indexed_ty)])), ) { if deref_ty == expr_ty { let snip = snippet_with_context(cx, indexed.span, ctxt, "..", &mut app).0; diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ref.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ref.rs index 54ac04df1c1..6bdb9aa5a26 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ref.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ref.rs @@ -6,7 +6,7 @@ use clippy_utils::sugg; use rustc_errors::Applicability; use rustc_hir::{self as hir, Expr, GenericArg, Mutability, Path, TyKind}; use rustc_lint::LateContext; -use rustc_middle::ty::{self, Ty, TypeVisitable}; +use rustc_middle::ty::{self, Ty, TypeVisitableExt}; /// Checks for `transmute_ptr_to_ref` lint. /// Returns `true` if it's triggered, otherwise returns `false`. diff --git a/src/tools/clippy/clippy_lints/src/transmute/useless_transmute.rs b/src/tools/clippy/clippy_lints/src/transmute/useless_transmute.rs index 871c3fadbba..56207fe767c 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/useless_transmute.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/useless_transmute.rs @@ -4,7 +4,7 @@ use clippy_utils::sugg; use rustc_errors::Applicability; use rustc_hir::Expr; use rustc_lint::LateContext; -use rustc_middle::ty::{self, Ty, TypeVisitable}; +use rustc_middle::ty::{self, Ty, TypeVisitableExt}; /// Checks for `useless_transmute` lint. /// Returns `true` if it's triggered, otherwise returns `false`. diff --git a/src/tools/clippy/clippy_lints/src/types/redundant_allocation.rs b/src/tools/clippy/clippy_lints/src/types/redundant_allocation.rs index f9b9a66b5fa..f7adc9d3555 100644 --- a/src/tools/clippy/clippy_lints/src/types/redundant_allocation.rs +++ b/src/tools/clippy/clippy_lints/src/types/redundant_allocation.rs @@ -5,7 +5,7 @@ use rustc_errors::Applicability; use rustc_hir::{self as hir, def_id::DefId, QPath, TyKind}; use rustc_hir_analysis::hir_ty_to_ty; use rustc_lint::LateContext; -use rustc_middle::ty::TypeVisitable; +use rustc_middle::ty::TypeVisitableExt; use rustc_span::symbol::sym; use super::{utils, REDUNDANT_ALLOCATION}; diff --git a/src/tools/clippy/clippy_lints/src/types/vec_box.rs b/src/tools/clippy/clippy_lints/src/types/vec_box.rs index 7a3c7cd8a99..d3062f3d2e3 100644 --- a/src/tools/clippy/clippy_lints/src/types/vec_box.rs +++ b/src/tools/clippy/clippy_lints/src/types/vec_box.rs @@ -7,7 +7,7 @@ use rustc_hir::{self as hir, def_id::DefId, GenericArg, QPath, TyKind}; use rustc_hir_analysis::hir_ty_to_ty; use rustc_lint::LateContext; use rustc_middle::ty::layout::LayoutOf; -use rustc_middle::ty::TypeVisitable; +use rustc_middle::ty::TypeVisitableExt; use rustc_span::symbol::sym; use super::VEC_BOX; diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_owned_empty_strings.rs b/src/tools/clippy/clippy_lints/src/unnecessary_owned_empty_strings.rs index 9f207d32fcf..6e802794f5a 100644 --- a/src/tools/clippy/clippy_lints/src/unnecessary_owned_empty_strings.rs +++ b/src/tools/clippy/clippy_lints/src/unnecessary_owned_empty_strings.rs @@ -7,6 +7,7 @@ use rustc_hir::{BorrowKind, Expr, ExprKind, LangItem, Mutability}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty; use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_span::symbol::sym; declare_clippy_lint! { /// ### What it does @@ -54,7 +55,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryOwnedEmptyStrings { ); } else { if_chain! { - if Some(fun_def_id) == cx.tcx.lang_items().from_fn(); + if cx.tcx.is_diagnostic_item(sym::from_fn, fun_def_id); if let [.., last_arg] = args; if let ExprKind::Lit(spanned) = &last_arg.kind; if let LitKind::Str(symbol, _) = spanned.node; diff --git a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs index 7355260ae4a..06d248204c1 100644 --- a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs +++ b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs @@ -12,9 +12,9 @@ use rustc_errors::Applicability; use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::DUMMY_SP; - use std::cell::Cell; use std::mem; +use thin_vec::{thin_vec, ThinVec}; declare_clippy_lint! { /// ### What it does @@ -214,7 +214,7 @@ macro_rules! always_pat { /// Focus on `focus_idx` in `alternatives`, /// attempting to extend it with elements of the same constructor `C` /// in `alternatives[focus_idx + 1..]`. -fn transform_with_focus_on_idx(alternatives: &mut Vec<P<Pat>>, focus_idx: usize) -> bool { +fn transform_with_focus_on_idx(alternatives: &mut ThinVec<P<Pat>>, focus_idx: usize) -> bool { // Extract the kind; we'll need to make some changes in it. let mut focus_kind = mem::replace(&mut alternatives[focus_idx].kind, PatKind::Wild); // We'll focus on `alternatives[focus_idx]`, @@ -296,7 +296,7 @@ fn extend_with_struct_pat( fps1: &mut [ast::PatField], rest1: bool, start: usize, - alternatives: &mut Vec<P<Pat>>, + alternatives: &mut ThinVec<P<Pat>>, ) -> bool { (0..fps1.len()).any(|idx| { let pos_in_2 = Cell::new(None); // The element `k`. @@ -336,9 +336,9 @@ fn extend_with_struct_pat( fn extend_with_matching_product( targets: &mut [P<Pat>], start: usize, - alternatives: &mut Vec<P<Pat>>, + alternatives: &mut ThinVec<P<Pat>>, predicate: impl Fn(&PatKind, &[P<Pat>], usize) -> bool, - extract: impl Fn(PatKind) -> Vec<P<Pat>>, + extract: impl Fn(PatKind) -> ThinVec<P<Pat>>, ) -> bool { (0..targets.len()).any(|idx| { let tail_or = drain_matching( @@ -365,14 +365,14 @@ fn take_pat(from: &mut Pat) -> Pat { /// Extend `target` as an or-pattern with the alternatives /// in `tail_or` if there are any and return if there were. -fn extend_with_tail_or(target: &mut Pat, tail_or: Vec<P<Pat>>) -> bool { - fn extend(target: &mut Pat, mut tail_or: Vec<P<Pat>>) { +fn extend_with_tail_or(target: &mut Pat, tail_or: ThinVec<P<Pat>>) -> bool { + fn extend(target: &mut Pat, mut tail_or: ThinVec<P<Pat>>) { match target { // On an existing or-pattern in the target, append to it. Pat { kind: Or(ps), .. } => ps.append(&mut tail_or), // Otherwise convert the target to an or-pattern. target => { - let mut init_or = vec![P(take_pat(target))]; + let mut init_or = thin_vec![P(take_pat(target))]; init_or.append(&mut tail_or); target.kind = Or(init_or); }, @@ -391,26 +391,42 @@ fn extend_with_tail_or(target: &mut Pat, tail_or: Vec<P<Pat>>) -> bool { // Only elements beginning with `start` are considered for extraction. fn drain_matching( start: usize, - alternatives: &mut Vec<P<Pat>>, + alternatives: &mut ThinVec<P<Pat>>, predicate: impl Fn(&PatKind) -> bool, extract: impl Fn(PatKind) -> P<Pat>, -) -> Vec<P<Pat>> { - let mut tail_or = vec![]; +) -> ThinVec<P<Pat>> { + let mut tail_or = ThinVec::new(); let mut idx = 0; - for pat in alternatives.drain_filter(|p| { - // Check if we should extract, but only if `idx >= start`. + + // If `ThinVec` had the `drain_filter` method, this loop could be rewritten + // like so: + // + // for pat in alternatives.drain_filter(|p| { + // // Check if we should extract, but only if `idx >= start`. + // idx += 1; + // idx > start && predicate(&p.kind) + // }) { + // tail_or.push(extract(pat.into_inner().kind)); + // } + let mut i = 0; + while i < alternatives.len() { idx += 1; - idx > start && predicate(&p.kind) - }) { - tail_or.push(extract(pat.into_inner().kind)); + // Check if we should extract, but only if `idx >= start`. + if idx > start && predicate(&alternatives[i].kind) { + let pat = alternatives.remove(i); + tail_or.push(extract(pat.into_inner().kind)); + } else { + i += 1; + } } + tail_or } fn extend_with_matching( target: &mut Pat, start: usize, - alternatives: &mut Vec<P<Pat>>, + alternatives: &mut ThinVec<P<Pat>>, predicate: impl Fn(&PatKind) -> bool, extract: impl Fn(PatKind) -> P<Pat>, ) -> bool { diff --git a/src/tools/clippy/clippy_lints/src/useless_conversion.rs b/src/tools/clippy/clippy_lints/src/useless_conversion.rs index a95e7b61374..fede625f72a 100644 --- a/src/tools/clippy/clippy_lints/src/useless_conversion.rs +++ b/src/tools/clippy/clippy_lints/src/useless_conversion.rs @@ -161,7 +161,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion { } if_chain! { - if Some(def_id) == cx.tcx.lang_items().from_fn(); + if cx.tcx.is_diagnostic_item(sym::from_fn, def_id); if same_type_and_consts(a, b); then { diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs index bd7daf0773c..c37e5bb6716 100644 --- a/src/tools/clippy/clippy_lints/src/utils/author.rs +++ b/src/tools/clippy/clippy_lints/src/utils/author.rs @@ -588,7 +588,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { }, } }, - ExprKind::Err => kind!("Err"), + ExprKind::Err(_) => kind!("Err"), ExprKind::DropTemps(expr) => { bind!(self, expr); kind!("DropTemps({expr})"); diff --git a/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs b/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs index 6cf2a955fd5..93e4b023c5c 100644 --- a/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs +++ b/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs @@ -5,7 +5,7 @@ use rustc_hir::{self as hir, HirId, ItemKind, Node}; use rustc_hir_analysis::hir_ty_to_ty; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::layout::LayoutOf as _; -use rustc_middle::ty::{Adt, Ty, TypeVisitable}; +use rustc_middle::ty::{Adt, Ty, TypeVisitableExt}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::sym; diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs index 9d0263e93be..d82098523e3 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs @@ -144,7 +144,8 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool { (_, Paren(r)) => eq_expr(l, r), (Err, Err) => true, (Box(l), Box(r)) | (Try(l), Try(r)) | (Await(l), Await(r)) => eq_expr(l, r), - (Array(l), Array(r)) | (Tup(l), Tup(r)) => over(l, r, |l, r| eq_expr(l, r)), + (Array(l), Array(r)) => over(l, r, |l, r| eq_expr(l, r)), + (Tup(l), Tup(r)) => over(l, r, |l, r| eq_expr(l, r)), (Repeat(le, ls), Repeat(re, rs)) => eq_expr(le, re) && eq_expr(&ls.value, &rs.value), (Call(lc, la), Call(rc, ra)) => eq_expr(lc, rc) && over(la, ra, |l, r| eq_expr(l, r)), ( diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index 8b00ce2cc25..bb8890dcaf9 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -237,7 +237,7 @@ pub fn constant<'tcx>( typeck_results, param_env: lcx.param_env, needed_resolution: false, - substs: lcx.tcx.intern_substs(&[]), + substs: ty::List::empty(), }; cx.expr(e).map(|cst| (cst, cx.needed_resolution)) } @@ -306,7 +306,7 @@ pub fn constant_context<'a, 'tcx>( typeck_results, param_env: lcx.param_env, needed_resolution: false, - substs: lcx.tcx.intern_substs(&[]), + substs: ty::List::empty(), } } diff --git a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs index 6ff7728374f..ee2f816f181 100644 --- a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs +++ b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs @@ -193,7 +193,7 @@ fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessS | ExprKind::Ret(_) | ExprKind::InlineAsm(_) | ExprKind::Yield(..) - | ExprKind::Err => { + | ExprKind::Err(_) => { self.eagerness = ForceNoChange; return; }, diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index 2bbe1a19b62..0603755f8a9 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -714,7 +714,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { } self.hash_pat(pat); }, - ExprKind::Err => {}, + ExprKind::Err(_) => {}, ExprKind::Lit(ref l) => { l.node.hash(&mut self.s); }, @@ -986,7 +986,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { TyKind::Typeof(anon_const) => { self.hash_body(anon_const.body); }, - TyKind::Err | TyKind::Infer | TyKind::Never => {}, + TyKind::Err(_) | TyKind::Infer | TyKind::Never => {}, } } diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index b2edd1bbfef..f02f8ecb43d 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -104,7 +104,7 @@ use rustc_middle::ty::fast_reject::SimplifiedType::{ PtrSimplifiedType, SliceSimplifiedType, StrSimplifiedType, UintSimplifiedType, }; use rustc_middle::ty::{ - layout::IntegerExt, BorrowKind, ClosureKind, DefIdTree, Ty, TyCtxt, TypeAndMut, TypeVisitable, UpvarCapture, + layout::IntegerExt, BorrowKind, ClosureKind, DefIdTree, Ty, TyCtxt, TypeAndMut, TypeVisitableExt, UpvarCapture, }; use rustc_middle::ty::{FloatTy, IntTy, UintTy}; use rustc_span::hygiene::{ExpnKind, MacroKind}; diff --git a/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs b/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs index e9dc7351b58..920ce8e655b 100644 --- a/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs +++ b/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs @@ -4,7 +4,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_index::bit_set::{BitSet, HybridBitSet}; use rustc_lint::LateContext; use rustc_middle::mir::{self, visit::Visitor as _, Mutability}; -use rustc_middle::ty::{self, visit::ir::TypeVisitor, TyCtxt}; +use rustc_middle::ty::{self, visit::TypeVisitor, TyCtxt}; use rustc_mir_dataflow::{impls::MaybeStorageLive, Analysis, ResultsCursor}; use std::borrow::Cow; use std::ops::ControlFlow; diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs index 78fb2e0eb7e..11ca81cfe6c 100644 --- a/src/tools/clippy/clippy_utils/src/sugg.rs +++ b/src/tools/clippy/clippy_utils/src/sugg.rs @@ -157,7 +157,7 @@ impl<'a> Sugg<'a> { | hir::ExprKind::Ret(..) | hir::ExprKind::Struct(..) | hir::ExprKind::Tup(..) - | hir::ExprKind::Err => Sugg::NonParen(get_snippet(expr.span)), + | hir::ExprKind::Err(_) => Sugg::NonParen(get_snippet(expr.span)), hir::ExprKind::DropTemps(inner) => Self::hir_from_snippet(inner, get_snippet), hir::ExprKind::Assign(lhs, rhs, _) => { Sugg::BinOp(AssocOp::Assign, get_snippet(lhs.span), get_snippet(rhs.span)) diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index 2ed301fcc22..f8ec4bb5493 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -17,8 +17,8 @@ use rustc_lint::LateContext; use rustc_middle::mir::interpret::{ConstValue, Scalar}; use rustc_middle::ty::{ self, AdtDef, AliasTy, AssocKind, Binder, BoundRegion, DefIdTree, FnSig, IntTy, List, ParamEnv, Predicate, - PredicateKind, Region, RegionKind, SubstsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, ir::TypeVisitor, UintTy, - VariantDef, VariantDiscr, + PredicateKind, Region, RegionKind, SubstsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, UintTy, + VariantDef, VariantDiscr, TypeVisitableExt, }; use rustc_middle::ty::{GenericArg, GenericArgKind}; use rustc_span::symbol::Ident; @@ -237,7 +237,7 @@ pub fn implements_trait_with_env<'tcx>( kind: TypeVariableOriginKind::MiscVariable, span: DUMMY_SP, }; - let ty_params = tcx.mk_substs( + let ty_params = tcx.mk_substs_from_iter( ty_params .into_iter() .map(|arg| arg.unwrap_or_else(|| infcx.next_ty_var(orig).into())), @@ -847,7 +847,7 @@ pub fn for_each_top_level_late_bound_region<B>( ControlFlow::Continue(()) } } - fn visit_binder<T: TypeVisitable<'tcx>>(&mut self, t: &Binder<'tcx, T>) -> ControlFlow<Self::BreakTy> { + fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(&mut self, t: &Binder<'tcx, T>) -> ControlFlow<Self::BreakTy> { self.index += 1; let res = t.super_visit_with(self); self.index -= 1; @@ -1065,7 +1065,7 @@ pub fn make_projection<'tcx>( tcx, container_id, assoc_ty, - tcx.mk_substs(substs.into_iter().map(Into::into)), + tcx.mk_substs_from_iter(substs.into_iter().map(Into::into)), ) } diff --git a/src/tools/clippy/clippy_utils/src/visitors.rs b/src/tools/clippy/clippy_utils/src/visitors.rs index 00073bcd82a..d27a20bd4df 100644 --- a/src/tools/clippy/clippy_utils/src/visitors.rs +++ b/src/tools/clippy/clippy_utils/src/visitors.rs @@ -665,7 +665,7 @@ pub fn for_each_unconsumed_temporary<'tcx, B>( | ExprKind::Path(_) | ExprKind::Continue(_) | ExprKind::InlineAsm(_) - | ExprKind::Err => (), + | ExprKind::Err(_) => (), } ControlFlow::Continue(()) } diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs index e45835efe74..9ac849aecf1 100644 --- a/src/tools/clippy/src/driver.rs +++ b/src/tools/clippy/src/driver.rs @@ -209,7 +209,10 @@ fn report_clippy_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) { // Separate the output with an empty line eprintln!(); - let fallback_bundle = rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false); + let fallback_bundle = rustc_errors::fallback_fluent_bundle( + rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), + false + ); let emitter = Box::new(rustc_errors::emitter::EmitterWriter::stderr( rustc_errors::ColorConfig::Auto, None, diff --git a/src/tools/clippy/tests/ui/missing_doc_impl.stderr b/src/tools/clippy/tests/ui/missing_doc_impl.stderr index f22fa19dbca..b410f56e167 100644 --- a/src/tools/clippy/tests/ui/missing_doc_impl.stderr +++ b/src/tools/clippy/tests/ui/missing_doc_impl.stderr @@ -51,13 +51,13 @@ LL | | fn foo_with_impl(&self) {} LL | | } | |_^ -error: missing documentation for an associated function +error: missing documentation for a method --> $DIR/missing_doc_impl.rs:44:5 | LL | fn foo(&self); | ^^^^^^^^^^^^^^ -error: missing documentation for an associated function +error: missing documentation for a method --> $DIR/missing_doc_impl.rs:45:5 | LL | fn foo_with_impl(&self) {} diff --git a/src/tools/compiletest/Cargo.toml b/src/tools/compiletest/Cargo.toml index deed6fbd439..0db043a4fca 100644 --- a/src/tools/compiletest/Cargo.toml +++ b/src/tools/compiletest/Cargo.toml @@ -16,7 +16,7 @@ regex = "1.0" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" rustfix = "0.6.0" -lazy_static = "1.0" +once_cell = "1.16.0" walkdir = "2" glob = "0.3.0" lazycell = "1.3.0" @@ -25,5 +25,5 @@ lazycell = "1.3.0" libc = "0.2" [target.'cfg(windows)'.dependencies] -miow = "0.3" +miow = "0.5" winapi = { version = "0.3", features = ["winerror"] } diff --git a/src/tools/compiletest/src/errors.rs b/src/tools/compiletest/src/errors.rs index 054235ec16d..c33e66e02ac 100644 --- a/src/tools/compiletest/src/errors.rs +++ b/src/tools/compiletest/src/errors.rs @@ -7,7 +7,7 @@ use std::io::BufReader; use std::path::Path; use std::str::FromStr; -use lazy_static::lazy_static; +use once_cell::sync::Lazy; use regex::Regex; use tracing::*; @@ -117,10 +117,8 @@ fn parse_expected( // //~^^^^^ // //[cfg1]~ // //[cfg1,cfg2]~^^ - lazy_static! { - static ref RE: Regex = - Regex::new(r"//(?:\[(?P<cfgs>[\w,]+)])?~(?P<adjust>\||\^*)").unwrap(); - } + static RE: Lazy<Regex> = + Lazy::new(|| Regex::new(r"//(?:\[(?P<cfgs>[\w,]+)])?~(?P<adjust>\||\^*)").unwrap()); let captures = RE.captures(line)?; diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index c648b2f12f1..1760c29ec66 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -588,7 +588,8 @@ fn modified_tests(config: &Config, dir: &Path) -> Result<Vec<PathBuf>, String> { let full_paths = { let mut full_paths: Vec<PathBuf> = all_paths .into_iter() - .map(|f| fs::canonicalize(&f).unwrap().with_extension("").with_extension("rs")) + .map(|f| PathBuf::from(f).with_extension("").with_extension("rs")) + .filter_map(|f| if Path::new(&f).exists() { f.canonicalize().ok() } else { None }) .collect(); full_paths.dedup(); full_paths.sort_unstable(); diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 51c9a27c83d..7824ef81d7a 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -32,7 +32,7 @@ use std::process::{Child, Command, ExitStatus, Output, Stdio}; use std::str; use glob::glob; -use lazy_static::lazy_static; +use once_cell::sync::Lazy; use tracing::*; use crate::extract_gdb_version; @@ -52,9 +52,8 @@ fn disable_error_reporting<F: FnOnce() -> R, R>(f: F) -> R { use winapi::um::errhandlingapi::SetErrorMode; use winapi::um::winbase::SEM_NOGPFAULTERRORBOX; - lazy_static! { - static ref LOCK: Mutex<()> = Mutex::new(()); - } + static LOCK: Mutex<()> = Mutex::new(()); + // Error mode is a global variable, so lock it so only one thread will change it let _lock = LOCK.lock().unwrap(); @@ -2848,11 +2847,10 @@ impl<'test> TestCx<'test> { // the form <crate-name1>.<crate-disambiguator1>-in-<crate-name2>.<crate-disambiguator2>, // remove all crate-disambiguators. fn remove_crate_disambiguator_from_cgu(cgu: &str) -> String { - lazy_static! { - static ref RE: Regex = - Regex::new(r"^[^\.]+(?P<d1>\.[[:alnum:]]+)(-in-[^\.]+(?P<d2>\.[[:alnum:]]+))?") - .unwrap(); - } + static RE: Lazy<Regex> = Lazy::new(|| { + Regex::new(r"^[^\.]+(?P<d1>\.[[:alnum:]]+)(-in-[^\.]+(?P<d2>\.[[:alnum:]]+))?") + .unwrap() + }); let captures = RE.captures(cgu).unwrap_or_else(|| panic!("invalid cgu name encountered: {}", cgu)); @@ -3170,12 +3168,12 @@ impl<'test> TestCx<'test> { // 'uploaded "$TEST_BUILD_DIR/<test_executable>, waiting for result"' // is printed to stdout by the client and then captured in the ProcRes, // so it needs to be removed when comparing the run-pass test execution output - lazy_static! { - static ref REMOTE_TEST_RE: Regex = Regex::new( + static REMOTE_TEST_RE: Lazy<Regex> = Lazy::new(|| { + Regex::new( "^uploaded \"\\$TEST_BUILD_DIR(/[[:alnum:]_\\-.]+)+\", waiting for result\n" ) - .unwrap(); - } + .unwrap() + }); REMOTE_TEST_RE .replace( &self.normalize_output(&proc_res.stdout, &self.props.normalize_stdout), @@ -3620,10 +3618,8 @@ impl<'test> TestCx<'test> { // with placeholders as we do not want tests needing updated when compiler source code // changes. // eg. $SRC_DIR/libcore/mem.rs:323:14 becomes $SRC_DIR/libcore/mem.rs:LL:COL - lazy_static! { - static ref SRC_DIR_RE: Regex = - Regex::new("SRC_DIR(.+):\\d+:\\d+(: \\d+:\\d+)?").unwrap(); - } + static SRC_DIR_RE: Lazy<Regex> = + Lazy::new(|| Regex::new("SRC_DIR(.+):\\d+:\\d+(: \\d+:\\d+)?").unwrap()); normalized = SRC_DIR_RE.replace_all(&normalized, "SRC_DIR$1:LL:COL").into_owned(); @@ -3634,19 +3630,17 @@ impl<'test> TestCx<'test> { // since they duplicate actual errors and make the output hard to read. // This mirrors the regex in src/tools/tidy/src/style.rs, please update // both if either are changed. - lazy_static! { - static ref ANNOTATION_RE: Regex = Regex::new("\\s*//(\\[.*\\])?~.*").unwrap(); - } + static ANNOTATION_RE: Lazy<Regex> = + Lazy::new(|| Regex::new("\\s*//(\\[.*\\])?~.*").unwrap()); normalized = ANNOTATION_RE.replace_all(&normalized, "").into_owned(); // This code normalizes various hashes in v0 symbol mangling that is // emitted in the ui and mir-opt tests. - lazy_static! { - static ref V0_CRATE_HASH_PREFIX_RE: Regex = - Regex::new(r"_R.*?Cs[0-9a-zA-Z]+_").unwrap(); - static ref V0_CRATE_HASH_RE: Regex = Regex::new(r"Cs[0-9a-zA-Z]+_").unwrap(); - } + static V0_CRATE_HASH_PREFIX_RE: Lazy<Regex> = + Lazy::new(|| Regex::new(r"_R.*?Cs[0-9a-zA-Z]+_").unwrap()); + static V0_CRATE_HASH_RE: Lazy<Regex> = + Lazy::new(|| Regex::new(r"Cs[0-9a-zA-Z]+_").unwrap()); const V0_CRATE_HASH_PLACEHOLDER: &str = r"CsCRATE_HASH_"; if V0_CRATE_HASH_PREFIX_RE.is_match(&normalized) { @@ -3655,10 +3649,9 @@ impl<'test> TestCx<'test> { V0_CRATE_HASH_RE.replace_all(&normalized, V0_CRATE_HASH_PLACEHOLDER).into_owned(); } - lazy_static! { - static ref V0_BACK_REF_PREFIX_RE: Regex = Regex::new(r"\(_R.*?B[0-9a-zA-Z]_").unwrap(); - static ref V0_BACK_REF_RE: Regex = Regex::new(r"B[0-9a-zA-Z]_").unwrap(); - } + static V0_BACK_REF_PREFIX_RE: Lazy<Regex> = + Lazy::new(|| Regex::new(r"\(_R.*?B[0-9a-zA-Z]_").unwrap()); + static V0_BACK_REF_RE: Lazy<Regex> = Lazy::new(|| Regex::new(r"B[0-9a-zA-Z]_").unwrap()); const V0_BACK_REF_PLACEHOLDER: &str = r"B<REF>_"; if V0_BACK_REF_PREFIX_RE.is_match(&normalized) { @@ -3681,21 +3674,23 @@ impl<'test> TestCx<'test> { /// Replaces backslashes in paths with forward slashes, and replaces CRLF line endings /// with LF. fn normalize_platform_differences(output: &str) -> String { - lazy_static! { - /// Used to find Windows paths. - /// - /// It's not possible to detect paths in the error messages generally, but this is a - /// decent enough heuristic. - static ref PATH_BACKSLASH_RE: Regex = Regex::new(r#"(?x) + /// Used to find Windows paths. + /// + /// It's not possible to detect paths in the error messages generally, but this is a + /// decent enough heuristic. + static PATH_BACKSLASH_RE: Lazy<Regex> = Lazy::new(|| { + Regex::new( + r#"(?x) (?: # Match paths that don't include spaces. (?:\\[\pL\pN\.\-_']+)+\.\pL+ | # If the path starts with a well-known root, then allow spaces. \$(?:DIR|SRC_DIR|TEST_BUILD_DIR|BUILD_DIR|LIB_DIR)(?:\\[\pL\pN\.\-_' ]+)+ - )"# - ).unwrap(); - } + )"#, + ) + .unwrap() + }); let output = output.replace(r"\\", r"\"); diff --git a/src/tools/error_index_generator/Cargo.toml b/src/tools/error_index_generator/Cargo.toml index f4dac6e947e..76c2e330b21 100644 --- a/src/tools/error_index_generator/Cargo.toml +++ b/src/tools/error_index_generator/Cargo.toml @@ -5,6 +5,7 @@ edition = "2021" [dependencies] mdbook = { version = "0.4", default-features = false, features = ["search"] } +rustc_error_codes = { version = "0.0.0", path = "../../../compiler/rustc_error_codes" } [[bin]] name = "error_index_generator" diff --git a/src/tools/error_index_generator/main.rs b/src/tools/error_index_generator/main.rs index 98eda97e236..f984275b164 100644 --- a/src/tools/error_index_generator/main.rs +++ b/src/tools/error_index_generator/main.rs @@ -2,9 +2,6 @@ extern crate rustc_driver; -// We use the function we generate from `register_diagnostics!`. -use crate::error_codes::error_codes; - use std::env; use std::error::Error; use std::fs::{self, File}; @@ -17,22 +14,6 @@ use std::str::FromStr; use mdbook::book::{parse_summary, BookItem, Chapter}; use mdbook::{Config, MDBook}; -macro_rules! register_diagnostics { - ($($error_code:ident: $message:expr,)+ ; $($undocumented:ident,)* ) => { - pub fn error_codes() -> Vec<(&'static str, Option<&'static str>)> { - let mut errors: Vec<(&str, Option<&str>)> = vec![ - $((stringify!($error_code), Some($message)),)+ - $((stringify!($undocumented), None),)+ - ]; - errors.sort(); - errors - } - } -} - -#[path = "../../../compiler/rustc_error_codes/src/error_codes.rs"] -mod error_codes; - enum OutputFormat { HTML, Markdown, @@ -55,11 +36,8 @@ fn render_markdown(output_path: &Path) -> Result<(), Box<dyn Error>> { write!(output_file, "# Rust Compiler Error Index\n")?; - for (err_code, description) in error_codes().iter() { - match description { - Some(ref desc) => write!(output_file, "## {}\n{}\n", err_code, desc)?, - None => {} - } + for (err_code, description) in rustc_error_codes::DIAGNOSTICS.iter() { + write!(output_file, "## {}\n{}\n", err_code, description)? } Ok(()) @@ -105,27 +83,23 @@ This page lists all the error codes emitted by the Rust compiler. " ); - let err_codes = error_codes(); + let err_codes = rustc_error_codes::DIAGNOSTICS; let mut chapters = Vec::with_capacity(err_codes.len()); for (err_code, explanation) in err_codes.iter() { - if let Some(explanation) = explanation { - introduction.push_str(&format!(" * [{0}](./{0}.html)\n", err_code)); - - let content = add_rust_attribute_on_codeblock(explanation); - chapters.push(BookItem::Chapter(Chapter { - name: err_code.to_string(), - content: format!("# Error code {}\n\n{}\n", err_code, content), - number: None, - sub_items: Vec::new(), - // We generate it into the `error_codes` folder. - path: Some(PathBuf::from(&format!("{}.html", err_code))), - source_path: None, - parent_names: Vec::new(), - })); - } else { - introduction.push_str(&format!(" * {}\n", err_code)); - } + introduction.push_str(&format!(" * [{0}](./{0}.html)\n", err_code)); + + let content = add_rust_attribute_on_codeblock(explanation); + chapters.push(BookItem::Chapter(Chapter { + name: err_code.to_string(), + content: format!("# Error code {}\n\n{}\n", err_code, content), + number: None, + sub_items: Vec::new(), + // We generate it into the `error_codes` folder. + path: Some(PathBuf::from(&format!("{}.html", err_code))), + source_path: None, + parent_names: Vec::new(), + })); } let mut config = Config::from_str(include_str!("book_config.toml"))?; diff --git a/src/tools/jsondoclint/src/validator.rs b/src/tools/jsondoclint/src/validator.rs index c6f55410e44..a1f675a3b40 100644 --- a/src/tools/jsondoclint/src/validator.rs +++ b/src/tools/jsondoclint/src/validator.rs @@ -71,6 +71,19 @@ impl<'a> Validator<'a> { } } + fn check_items(&mut self, id: &Id, items: &[Id]) { + let mut visited_ids = HashSet::with_capacity(items.len()); + + for item in items { + if !visited_ids.insert(item) { + self.fail( + id, + ErrorKind::Custom(format!("Duplicated entry in `items` field: `{item:?}`")), + ); + } + } + } + fn check_item(&mut self, id: &'a Id) { if let Some(item) = &self.krate.index.get(id) { item.links.values().for_each(|id| self.add_any_id(id)); @@ -83,9 +96,9 @@ impl<'a> Validator<'a> { ItemEnum::Enum(x) => self.check_enum(x), ItemEnum::Variant(x) => self.check_variant(x, id), ItemEnum::Function(x) => self.check_function(x), - ItemEnum::Trait(x) => self.check_trait(x), + ItemEnum::Trait(x) => self.check_trait(x, id), ItemEnum::TraitAlias(x) => self.check_trait_alias(x), - ItemEnum::Impl(x) => self.check_impl(x), + ItemEnum::Impl(x) => self.check_impl(x, id), ItemEnum::Typedef(x) => self.check_typedef(x), ItemEnum::OpaqueTy(x) => self.check_opaque_ty(x), ItemEnum::Constant(x) => self.check_constant(x), @@ -94,7 +107,7 @@ impl<'a> Validator<'a> { ItemEnum::Macro(x) => self.check_macro(x), ItemEnum::ProcMacro(x) => self.check_proc_macro(x), ItemEnum::Primitive(x) => self.check_primitive_type(x), - ItemEnum::Module(x) => self.check_module(x), + ItemEnum::Module(x) => self.check_module(x, id), // FIXME: Why don't these have their own structs? ItemEnum::ExternCrate { .. } => {} ItemEnum::AssocConst { type_, default: _ } => self.check_type(type_), @@ -112,7 +125,8 @@ impl<'a> Validator<'a> { } // Core checkers - fn check_module(&mut self, module: &'a Module) { + fn check_module(&mut self, module: &'a Module, id: &Id) { + self.check_items(id, &module.items); module.items.iter().for_each(|i| self.add_mod_item_id(i)); } @@ -181,7 +195,8 @@ impl<'a> Validator<'a> { self.check_fn_decl(&x.decl); } - fn check_trait(&mut self, x: &'a Trait) { + fn check_trait(&mut self, x: &'a Trait, id: &Id) { + self.check_items(id, &x.items); self.check_generics(&x.generics); x.items.iter().for_each(|i| self.add_trait_item_id(i)); x.bounds.iter().for_each(|i| self.check_generic_bound(i)); @@ -193,7 +208,8 @@ impl<'a> Validator<'a> { x.params.iter().for_each(|i| self.check_generic_bound(i)); } - fn check_impl(&mut self, x: &'a Impl) { + fn check_impl(&mut self, x: &'a Impl, id: &Id) { + self.check_items(id, &x.items); self.check_generics(&x.generics); if let Some(path) = &x.trait_ { self.check_path(path, PathKind::Trait); diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 461add9f508..53ec1ba0821 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -f715e430aac0de131e2ad21804013ea405722a66 +c4e0cd966062ca67daed20775f4e8a60c28e57df diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs index ebb71b57ae3..8443e907938 100644 --- a/src/tools/miri/src/eval.rs +++ b/src/tools/miri/src/eval.rs @@ -363,7 +363,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>( tcx, ty::ParamEnv::reveal_all(), start_id, - tcx.intern_substs(&[ty::subst::GenericArg::from(main_ret_ty)]), + tcx.mk_substs(&[ty::subst::GenericArg::from(main_ret_ty)]), ) .unwrap() .unwrap(); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs index c82c274524a..f21b4f84c4c 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs @@ -173,7 +173,7 @@ pub fn layout_of_ty(db: &dyn HirDatabase, ty: &Ty, krate: CrateId) -> Result<Lay // let pointee = tcx.normalize_erasing_regions(param_env, pointee); // if pointee.is_sized(tcx.at(DUMMY_SP), param_env) { - // return Ok(tcx.intern_layout(LayoutS::scalar(cx, data_ptr))); + // return Ok(tcx.mk_layout(LayoutS::scalar(cx, data_ptr))); // } let unsized_part = struct_tail_erasing_lifetimes(db, pointee.clone()); diff --git a/src/tools/rustfmt/src/chains.rs b/src/tools/rustfmt/src/chains.rs index 39b8d687809..cbe523c6c3c 100644 --- a/src/tools/rustfmt/src/chains.rs +++ b/src/tools/rustfmt/src/chains.rs @@ -74,6 +74,8 @@ use crate::utils::{ rewrite_ident, trimmed_last_line_width, wrap_str, }; +use thin_vec::ThinVec; + /// Provides the original input contents from the span /// of a chain element with trailing spaces trimmed. fn format_overflow_style(span: Span, context: &RewriteContext<'_>) -> Option<String> { @@ -168,7 +170,7 @@ enum ChainItemKind { MethodCall( ast::PathSegment, Vec<ast::GenericArg>, - Vec<ptr::P<ast::Expr>>, + ThinVec<ptr::P<ast::Expr>>, ), StructField(symbol::Ident), TupleField(symbol::Ident, bool), diff --git a/src/tools/rustfmt/src/closures.rs b/src/tools/rustfmt/src/closures.rs index 8fd0fcf8f5c..340113866c4 100644 --- a/src/tools/rustfmt/src/closures.rs +++ b/src/tools/rustfmt/src/closures.rs @@ -1,5 +1,6 @@ use rustc_ast::{ast, ptr}; use rustc_span::Span; +use thin_vec::thin_vec; use crate::attr::get_attrs_from_stmt; use crate::config::lists::*; @@ -150,7 +151,7 @@ fn rewrite_closure_with_block( } let block = ast::Block { - stmts: vec![ast::Stmt { + stmts: thin_vec![ast::Stmt { id: ast::NodeId::root(), kind: ast::StmtKind::Expr(ptr::P(body.clone())), span: body.span, diff --git a/src/tools/rustfmt/src/lib.rs b/src/tools/rustfmt/src/lib.rs index 0c27bcacfb8..b27405efdb7 100644 --- a/src/tools/rustfmt/src/lib.rs +++ b/src/tools/rustfmt/src/lib.rs @@ -23,6 +23,7 @@ extern crate rustc_expand; extern crate rustc_parse; extern crate rustc_session; extern crate rustc_span; +extern crate thin_vec; // Necessary to pull in object code as the rest of the rustc crates are shipped only as rmeta // files. diff --git a/src/tools/rustfmt/src/modules.rs b/src/tools/rustfmt/src/modules.rs index 7a0d1736c59..af9a154a6ae 100644 --- a/src/tools/rustfmt/src/modules.rs +++ b/src/tools/rustfmt/src/modules.rs @@ -6,6 +6,7 @@ use rustc_ast::ast; use rustc_ast::visit::Visitor; use rustc_span::symbol::{self, sym, Symbol}; use rustc_span::Span; +use thin_vec::ThinVec; use thiserror::Error; use crate::attr::MetaVisitor; @@ -25,7 +26,7 @@ type FileModMap<'ast> = BTreeMap<FileName, Module<'ast>>; #[derive(Debug, Clone)] pub(crate) struct Module<'a> { ast_mod_kind: Option<Cow<'a, ast::ModKind>>, - pub(crate) items: Cow<'a, Vec<rustc_ast::ptr::P<ast::Item>>>, + pub(crate) items: Cow<'a, ThinVec<rustc_ast::ptr::P<ast::Item>>>, inner_attr: ast::AttrVec, pub(crate) span: Span, } @@ -34,7 +35,7 @@ impl<'a> Module<'a> { pub(crate) fn new( mod_span: Span, ast_mod_kind: Option<Cow<'a, ast::ModKind>>, - mod_items: Cow<'a, Vec<rustc_ast::ptr::P<ast::Item>>>, + mod_items: Cow<'a, ThinVec<rustc_ast::ptr::P<ast::Item>>>, mod_attrs: Cow<'a, ast::AttrVec>, ) -> Self { let inner_attr = mod_attrs @@ -157,7 +158,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> { Module::new( module_item.item.span, Some(Cow::Owned(sub_mod_kind.clone())), - Cow::Owned(vec![]), + Cow::Owned(ThinVec::new()), Cow::Owned(ast::AttrVec::new()), ), )?; @@ -169,7 +170,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> { /// Visit modules defined inside macro calls. fn visit_mod_outside_ast( &mut self, - items: Vec<rustc_ast::ptr::P<ast::Item>>, + items: ThinVec<rustc_ast::ptr::P<ast::Item>>, ) -> Result<(), ModuleResolutionError> { for item in items { if is_cfg_if(&item) { @@ -184,7 +185,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> { Module::new( span, Some(Cow::Owned(sub_mod_kind.clone())), - Cow::Owned(vec![]), + Cow::Owned(ThinVec::new()), Cow::Owned(ast::AttrVec::new()), ), )?; @@ -210,7 +211,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> { Module::new( span, Some(Cow::Borrowed(sub_mod_kind)), - Cow::Owned(vec![]), + Cow::Owned(ThinVec::new()), Cow::Borrowed(&item.attrs), ), )?; diff --git a/src/tools/rustfmt/src/parse/parser.rs b/src/tools/rustfmt/src/parse/parser.rs index e0bd065518b..7ab042506bd 100644 --- a/src/tools/rustfmt/src/parse/parser.rs +++ b/src/tools/rustfmt/src/parse/parser.rs @@ -6,6 +6,7 @@ use rustc_ast::{ast, ptr}; use rustc_errors::Diagnostic; use rustc_parse::{new_parser_from_file, parser::Parser as RawParser}; use rustc_span::{sym, Span}; +use thin_vec::ThinVec; use crate::attr::first_attr_value_str_by_name; use crate::parse::session::ParseSess; @@ -109,7 +110,7 @@ impl<'a> Parser<'a> { sess: &'a ParseSess, path: &Path, span: Span, - ) -> Result<(ast::AttrVec, Vec<ptr::P<ast::Item>>, Span), ParserError> { + ) -> Result<(ast::AttrVec, ThinVec<ptr::P<ast::Item>>, Span), ParserError> { let result = catch_unwind(AssertUnwindSafe(|| { let mut parser = new_parser_from_file(sess.inner(), path, Some(span)); match parser.parse_mod(&TokenKind::Eof) { diff --git a/src/tools/rustfmt/src/parse/session.rs b/src/tools/rustfmt/src/parse/session.rs index 9014026b0aa..a64963db6a7 100644 --- a/src/tools/rustfmt/src/parse/session.rs +++ b/src/tools/rustfmt/src/parse/session.rs @@ -123,8 +123,10 @@ fn default_handler( let emitter = if hide_parse_errors { silent_emitter() } else { - let fallback_bundle = - rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false); + let fallback_bundle = rustc_errors::fallback_fluent_bundle( + rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), + false, + ); Box::new(EmitterWriter::stderr( color_cfg, Some(source_map.clone()), diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 4c93f8a16b6..bddfdcfaf19 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -120,6 +120,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "dissimilar", "dlmalloc", "either", + "elsa", "ena", "expect-test", "fallible-iterator", // dependency of `thorin` diff --git a/src/tools/tidy/src/error_codes.rs b/src/tools/tidy/src/error_codes.rs index dd2fd1911f2..c60caa0d49c 100644 --- a/src/tools/tidy/src/error_codes.rs +++ b/src/tools/tidy/src/error_codes.rs @@ -31,7 +31,7 @@ const IGNORE_DOCTEST_CHECK: &[&str] = &["E0464", "E0570", "E0601", "E0602", "E06 // Error codes that don't yet have a UI test. This list will eventually be removed. const IGNORE_UI_TEST_CHECK: &[&str] = - &["E0461", "E0465", "E0476", "E0514", "E0554", "E0640", "E0717", "E0729"]; + &["E0461", "E0465", "E0514", "E0554", "E0640", "E0717", "E0729"]; macro_rules! verbose_print { ($verbose:expr, $($fmt:tt)*) => { @@ -45,7 +45,7 @@ pub fn check(root_path: &Path, search_paths: &[&Path], verbose: bool, bad: &mut let mut errors = Vec::new(); // Stage 1: create list - let error_codes = extract_error_codes(root_path, &mut errors, verbose); + let error_codes = extract_error_codes(root_path, &mut errors); println!("Found {} error codes", error_codes.len()); println!("Highest error code: `{}`", error_codes.iter().max().unwrap()); @@ -65,18 +65,17 @@ pub fn check(root_path: &Path, search_paths: &[&Path], verbose: bool, bad: &mut } /// Stage 1: Parses a list of error codes from `error_codes.rs`. -fn extract_error_codes(root_path: &Path, errors: &mut Vec<String>, verbose: bool) -> Vec<String> { +fn extract_error_codes(root_path: &Path, errors: &mut Vec<String>) -> Vec<String> { let path = root_path.join(Path::new(ERROR_CODES_PATH)); let file = fs::read_to_string(&path).unwrap_or_else(|e| panic!("failed to read `{path:?}`: {e}")); let mut error_codes = Vec::new(); - let mut reached_undocumented_codes = false; for line in file.lines() { let line = line.trim(); - if !reached_undocumented_codes && line.starts_with('E') { + if line.starts_with('E') { let split_line = line.split_once(':'); // Extract the error code from the line, emitting a fatal error if it is not in a correct format. @@ -111,23 +110,6 @@ fn extract_error_codes(root_path: &Path, errors: &mut Vec<String>, verbose: bool } error_codes.push(err_code); - } else if reached_undocumented_codes && line.starts_with('E') { - let err_code = match line.split_once(',') { - None => line, - Some((err_code, _)) => err_code, - } - .to_string(); - - verbose_print!(verbose, "warning: Error code `{}` is undocumented.", err_code); - - if error_codes.contains(&err_code) { - errors.push(format!("Found duplicate error code: `{}`", err_code)); - } - - error_codes.push(err_code); - } else if line == ";" { - // Once we reach the undocumented error codes, adapt to different syntax. - reached_undocumented_codes = true; } } |
