diff options
Diffstat (limited to 'src')
354 files changed, 5621 insertions, 3022 deletions
diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock index d2f3c7f36ca..a47f3af60cb 100644 --- a/src/bootstrap/Cargo.lock +++ b/src/bootstrap/Cargo.lock @@ -59,6 +59,7 @@ dependencies = [ "termcolor", "toml", "tracing", + "tracing-chrome", "tracing-subscriber", "tracing-tree", "walkdir", @@ -728,6 +729,17 @@ dependencies = [ ] [[package]] +name = "tracing-chrome" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf0a738ed5d6450a9fb96e86a23ad808de2b727fd1394585da5cdd6788ffe724" +dependencies = [ + "serde_json", + "tracing-core", + "tracing-subscriber", +] + +[[package]] name = "tracing-core" version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index d7afcc7f27d..ed51862390d 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -7,7 +7,7 @@ default-run = "bootstrap" [features] build-metrics = ["sysinfo"] -tracing = ["dep:tracing", "dep:tracing-subscriber", "dep:tracing-tree"] +tracing = ["dep:tracing", "dep:tracing-chrome", "dep:tracing-subscriber", "dep:tracing-tree"] [lib] path = "src/lib.rs" @@ -67,6 +67,7 @@ sysinfo = { version = "0.33.0", default-features = false, optional = true, featu # Dependencies needed by the `tracing` feature tracing = { version = "0.1", optional = true, features = ["attributes"] } +tracing-chrome = { version = "0.7", optional = true } tracing-subscriber = { version = "0.3", optional = true, features = ["env-filter", "fmt", "registry", "std"] } tracing-tree = { version = "0.4.0", optional = true } diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index a86c20d46bd..ac971a64d7c 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -44,10 +44,14 @@ o("optimize-tests", "rust.optimize-tests", "build tests with optimizations") o("verbose-tests", "rust.verbose-tests", "enable verbose output when running tests") o( "ccache", - "llvm.ccache", - "invoke gcc/clang via ccache to reuse object files between builds", + "build.ccache", + "invoke gcc/clang/rustc via ccache to reuse object files between builds", +) +o( + "sccache", + None, + "invoke gcc/clang/rustc via sccache to reuse object files between builds", ) -o("sccache", None, "invoke gcc/clang via sccache to reuse object files between builds") o("local-rust", None, "use an installed rustc rather than downloading a snapshot") v("local-rust-root", None, "set prefix for local rust binary") o( @@ -510,7 +514,7 @@ def apply_args(known_args, option_checking, config): build_triple = build(known_args) if option.name == "sccache": - set("llvm.ccache", "sccache", config) + set("build.ccache", "sccache", config) elif option.name == "local-rust": for path in os.environ["PATH"].split(os.pathsep): if os.path.exists(path + "/rustc"): diff --git a/src/bootstrap/download-ci-llvm-stamp b/src/bootstrap/download-ci-llvm-stamp index 42cecbf5df9..d2c0d380fb4 100644 --- a/src/bootstrap/download-ci-llvm-stamp +++ b/src/bootstrap/download-ci-llvm-stamp @@ -1,4 +1,4 @@ Change this file to make users of the `download-ci-llvm` configuration download a new version of LLVM from CI, even if the LLVM submodule hasn’t changed. -Last change is for: https://github.com/rust-lang/rust/pull/129788 +Last change is for: https://github.com/rust-lang/rust/pull/134740 diff --git a/src/bootstrap/mk/Makefile.in b/src/bootstrap/mk/Makefile.in index 7e6a39a236e..88aa70d4f2f 100644 --- a/src/bootstrap/mk/Makefile.in +++ b/src/bootstrap/mk/Makefile.in @@ -99,16 +99,18 @@ prepare: # Set of tests that represent around half of the time of the test suite. # Used to split tests across multiple CI runners. -STAGE_2_TEST_SET1 := test --stage 2 --skip=compiler --skip=src -STAGE_2_TEST_SET2 := test --stage 2 --skip=tests --skip=coverage-map --skip=coverage-run --skip=library --skip=tidyselftest +SKIP_COMPILER := --skip=compiler +SKIP_SRC := --skip=src +TEST_SET1 := $(SKIP_COMPILER) $(SKIP_SRC) +TEST_SET2 := --skip=tests --skip=coverage-map --skip=coverage-run --skip=library --skip=tidyselftest ## MSVC native builders # this intentionally doesn't use `$(BOOTSTRAP)` so we can test the shebang on Windows ci-msvc-py: - $(Q)$(CFG_SRC_DIR)/x.py $(STAGE_2_TEST_SET1) + $(Q)$(CFG_SRC_DIR)/x.py test --stage 2 $(TEST_SET1) ci-msvc-ps1: - $(Q)$(CFG_SRC_DIR)/x.ps1 $(STAGE_2_TEST_SET2) + $(Q)$(CFG_SRC_DIR)/x.ps1 test --stage 2 $(TEST_SET2) ci-msvc: ci-msvc-py ci-msvc-ps1 ## MingW native builders @@ -116,10 +118,14 @@ ci-msvc: ci-msvc-py ci-msvc-ps1 # Set of tests that should represent half of the time of the test suite. # Used to split tests across multiple CI runners. # Test both x and bootstrap entrypoints. +ci-mingw-x-1: + $(Q)$(CFG_SRC_DIR)/x test --stage 2 $(SKIP_COMPILER) $(TEST_SET2) +ci-mingw-x-2: + $(Q)$(CFG_SRC_DIR)/x test --stage 2 $(SKIP_SRC) $(TEST_SET2) ci-mingw-x: - $(Q)$(CFG_SRC_DIR)/x $(STAGE_2_TEST_SET1) + $(Q)$(CFG_SRC_DIR)/x test --stage 2 $(TEST_SET1) ci-mingw-bootstrap: - $(Q)$(BOOTSTRAP) $(STAGE_2_TEST_SET2) + $(Q)$(BOOTSTRAP) test --stage 2 $(TEST_SET2) ci-mingw: ci-mingw-x ci-mingw-bootstrap .PHONY: dist diff --git a/src/bootstrap/src/bin/main.rs b/src/bootstrap/src/bin/main.rs index 441674936c6..38b380e3db8 100644 --- a/src/bootstrap/src/bin/main.rs +++ b/src/bootstrap/src/bin/main.rs @@ -21,7 +21,7 @@ use tracing::instrument; #[cfg_attr(feature = "tracing", instrument(level = "trace", name = "main"))] fn main() { #[cfg(feature = "tracing")] - setup_tracing(); + let _guard = setup_tracing(); let args = env::args().skip(1).collect::<Vec<_>>(); @@ -210,7 +210,7 @@ fn check_version(config: &Config) -> Option<String> { // - `tracing`'s `#[instrument(..)]` macro will need to be gated like `#![cfg_attr(feature = // "tracing", instrument(..))]`. #[cfg(feature = "tracing")] -fn setup_tracing() { +fn setup_tracing() -> impl Drop { use tracing_subscriber::EnvFilter; use tracing_subscriber::layer::SubscriberExt; @@ -218,7 +218,17 @@ fn setup_tracing() { // cf. <https://docs.rs/tracing-tree/latest/tracing_tree/struct.HierarchicalLayer.html>. let layer = tracing_tree::HierarchicalLayer::default().with_targets(true).with_indent_amount(2); - let registry = tracing_subscriber::registry().with(filter).with(layer); + let mut chrome_layer = tracing_chrome::ChromeLayerBuilder::new().include_args(true); + + // Writes the Chrome profile to trace-<unix-timestamp>.json if enabled + if !env::var("BOOTSTRAP_PROFILE").is_ok_and(|v| v == "1") { + chrome_layer = chrome_layer.writer(io::sink()); + } + + let (chrome_layer, _guard) = chrome_layer.build(); + + let registry = tracing_subscriber::registry().with(filter).with(layer).with(chrome_layer); tracing::subscriber::set_global_default(registry).unwrap(); + _guard } diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index cd3558ac6a4..c62c36390ea 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -16,6 +16,8 @@ use std::process::Stdio; use std::{env, fs, str}; use serde_derive::Deserialize; +#[cfg(feature = "tracing")] +use tracing::{instrument, span}; use crate::core::build_steps::tool::SourceType; use crate::core::build_steps::{dist, llvm}; @@ -30,7 +32,7 @@ use crate::utils::exec::command; use crate::utils::helpers::{ exe, get_clang_cl_resource_dir, is_debug_info, is_dylib, symlink_dir, t, up_to_date, }; -use crate::{CLang, Compiler, DependencyType, GitRepo, LLVM_TOOLS, Mode}; +use crate::{CLang, Compiler, DependencyType, GitRepo, LLVM_TOOLS, Mode, debug, trace}; #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct Std { @@ -95,9 +97,10 @@ impl Step for Std { const DEFAULT: bool = true; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.crate_or_deps("sysroot").path("library").alias("core") + run.crate_or_deps("sysroot").path("library") } + #[cfg_attr(feature = "tracing", instrument(level = "trace", name = "Std::make_run", skip_all))] fn make_run(run: RunConfig<'_>) { let crates = std_crates_for_run_make(&run); let builder = run.builder; @@ -109,6 +112,14 @@ impl Step for Std { && builder.download_rustc() && builder.config.last_modified_commit(&["library"], "download-rustc", true).is_none(); + trace!("is managed git repo: {}", builder.rust_info().is_managed_git_subrepository()); + trace!("download_rustc: {}", builder.download_rustc()); + trace!( + "last modified commit: {:?}", + builder.config.last_modified_commit(&["library"], "download-rustc", true) + ); + trace!(force_recompile); + run.builder.ensure(Std { compiler: run.builder.compiler(run.builder.top_stage, run.build_triple()), target: run.target, @@ -124,13 +135,26 @@ impl Step for Std { /// This will build the standard library for a particular stage of the build /// using the `compiler` targeting the `target` architecture. The artifacts /// created will also be linked into the sysroot directory. + #[cfg_attr( + feature = "tracing", + instrument( + level = "debug", + name = "Std::run", + skip_all, + fields( + target = ?self.target, + compiler = ?self.compiler, + force_recompile = self.force_recompile + ), + ), + )] fn run(self, builder: &Builder<'_>) { let target = self.target; let compiler = self.compiler; // When using `download-rustc`, we already have artifacts for the host available. Don't // recompile them. - if builder.download_rustc() && target == builder.build.build + if builder.download_rustc() && builder.is_builder_target(target) // NOTE: the beta compiler may generate different artifacts than the downloaded compiler, so // its artifacts can't be reused. && compiler.stage != 0 @@ -148,6 +172,9 @@ impl Step for Std { if builder.config.keep_stage.contains(&compiler.stage) || builder.config.keep_stage_std.contains(&compiler.stage) { + trace!(keep_stage = ?builder.config.keep_stage); + trace!(keep_stage_std = ?builder.config.keep_stage_std); + builder.info("WARNING: Using a potentially old libstd. This may not behave well."); builder.ensure(StartupObjects { compiler, target }); @@ -163,7 +190,15 @@ impl Step for Std { let mut target_deps = builder.ensure(StartupObjects { compiler, target }); let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target); + trace!(?compiler_to_use); + if compiler_to_use != compiler { + trace!( + ?compiler_to_use, + ?compiler, + "compiler != compiler_to_use, handling cross-compile scenario" + ); + builder.ensure(Std::new(compiler_to_use, target)); let msg = if compiler_to_use.host == target { format!( @@ -186,12 +221,21 @@ impl Step for Std { return; } + trace!( + ?compiler_to_use, + ?compiler, + "compiler == compiler_to_use, handling not-cross-compile scenario" + ); + target_deps.extend(self.copy_extra_objects(builder, &compiler, target)); // The LLD wrappers and `rust-lld` are self-contained linking components that can be // necessary to link the stdlib on some targets. We'll also need to copy these binaries to // the `stage0-sysroot` to ensure the linker is found when bootstrapping on such a target. - if compiler.stage == 0 && compiler.host == builder.config.build { + if compiler.stage == 0 && builder.is_builder_target(compiler.host) { + trace!( + "(build == host) copying linking components to `stage0-sysroot` for bootstrapping" + ); // We want to copy the host `bin` folder within the `rustlib` folder in the sysroot. let src_sysroot_bin = builder .rustc_snapshot_sysroot() @@ -210,6 +254,7 @@ impl Step for Std { // with -Zalways-encode-mir. This frees us from the need to have a target linker, and the // fact that this is a check build integrates nicely with run_cargo. let mut cargo = if self.is_for_mir_opt_tests { + trace!("building special sysroot for mir-opt tests"); let mut cargo = builder::Cargo::new_for_mir_opt_tests( builder, compiler, @@ -222,6 +267,7 @@ impl Step for Std { cargo.arg("--manifest-path").arg(builder.src.join("library/sysroot/Cargo.toml")); cargo } else { + trace!("building regular sysroot"); let mut cargo = builder::Cargo::new( builder, compiler, @@ -443,8 +489,49 @@ fn compiler_rt_for_profiler(builder: &Builder<'_>) -> PathBuf { /// Configure cargo to compile the standard library, adding appropriate env vars /// and such. pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, cargo: &mut Cargo) { - if let Some(target) = env::var_os("MACOSX_STD_DEPLOYMENT_TARGET") { - cargo.env("MACOSX_DEPLOYMENT_TARGET", target); + // rustc already ensures that it builds with the minimum deployment + // target, so ideally we shouldn't need to do anything here. + // + // However, `cc` currently defaults to a higher version for backwards + // compatibility, which means that compiler-rt, which is built via + // compiler-builtins' build script, gets built with a higher deployment + // target. This in turn causes warnings while linking, and is generally + // a compatibility hazard. + // + // So, at least until https://github.com/rust-lang/cc-rs/issues/1171, or + // perhaps https://github.com/rust-lang/cargo/issues/13115 is resolved, we + // explicitly set the deployment target environment variables to avoid + // this issue. + // + // This place also serves as an extension point if we ever wanted to raise + // rustc's default deployment target while keeping the prebuilt `std` at + // a lower version, so it's kinda nice to have in any case. + if target.contains("apple") && !builder.config.dry_run() { + // Query rustc for the deployment target, and the associated env var. + // The env var is one of the standard `*_DEPLOYMENT_TARGET` vars, i.e. + // `MACOSX_DEPLOYMENT_TARGET`, `IPHONEOS_DEPLOYMENT_TARGET`, etc. + let mut cmd = command(builder.rustc(cargo.compiler())); + cmd.arg("--target").arg(target.rustc_target_arg()); + cmd.arg("--print=deployment-target"); + let output = cmd.run_capture_stdout(builder).stdout(); + + let (env_var, value) = output.split_once('=').unwrap(); + // Unconditionally set the env var (if it was set in the environment + // already, rustc should've picked that up). + cargo.env(env_var.trim(), value.trim()); + + // Allow CI to override the deployment target for `std` on macOS. + // + // This is useful because we might want the host tooling LLVM, `rustc` + // and Cargo to have a different deployment target than `std` itself + // (currently, these two versions are the same, but in the past, we + // supported macOS 10.7 for user code and macOS 10.8 in host tooling). + // + // It is not necessary on the other platforms, since only macOS has + // support for host tooling. + if let Some(target) = env::var_os("MACOSX_STD_DEPLOYMENT_TARGET") { + cargo.env("MACOSX_DEPLOYMENT_TARGET", target); + } } // Paths needed by `library/profiler_builtins/build.rs`. @@ -624,6 +711,19 @@ impl Step for StdLink { /// Note that this assumes that `compiler` has already generated the libstd /// libraries for `target`, and this method will find them in the relevant /// output directory. + #[cfg_attr( + feature = "tracing", + instrument( + level = "trace", + name = "StdLink::run", + skip_all, + fields( + compiler = ?self.compiler, + target_compiler = ?self.target_compiler, + target = ?self.target + ), + ), + )] fn run(self, builder: &Builder<'_>) { let compiler = self.compiler; let target_compiler = self.target_compiler; @@ -781,6 +881,15 @@ impl Step for StartupObjects { /// They don't require any library support as they're just plain old object /// files, so we just use the nightly snapshot compiler to always build them (as /// no other compilers are guaranteed to be available). + #[cfg_attr( + feature = "tracing", + instrument( + level = "trace", + name = "StartupObjects::run", + skip_all, + fields(compiler = ?self.compiler, target = ?self.target), + ), + )] fn run(self, builder: &Builder<'_>) -> Vec<(PathBuf, DependencyType)> { let for_compiler = self.compiler; let target = self.target; @@ -895,6 +1004,15 @@ impl Step for Rustc { /// This will build the compiler for a particular stage of the build using /// the `compiler` targeting the `target` architecture. The artifacts /// created will also be linked into the sysroot directory. + #[cfg_attr( + feature = "tracing", + instrument( + level = "debug", + name = "Rustc::run", + skip_all, + fields(previous_compiler = ?self.compiler, target = ?self.target), + ), + )] fn run(self, builder: &Builder<'_>) -> u32 { let compiler = self.compiler; let target = self.target; @@ -902,6 +1020,8 @@ impl Step for Rustc { // NOTE: the ABI of the beta compiler is different from the ABI of the downloaded compiler, // so its artifacts can't be reused. if builder.download_rustc() && compiler.stage != 0 { + trace!(stage = compiler.stage, "`download_rustc` requested"); + let sysroot = builder.ensure(Sysroot { compiler, force_recompile: false }); cp_rustc_component_to_ci_sysroot( builder, @@ -914,6 +1034,8 @@ impl Step for Rustc { builder.ensure(Std::new(compiler, target)); if builder.config.keep_stage.contains(&compiler.stage) { + trace!(stage = compiler.stage, "`keep-stage` requested"); + builder.info("WARNING: Using a potentially old librustc. This may not behave well."); builder.info("WARNING: Use `--keep-stage-std` if you want to rebuild the compiler when it changes"); builder.ensure(RustcLink::from_rustc(self, compiler)); @@ -1049,12 +1171,13 @@ pub fn rustc_cargo( // <https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/Internal.20lint.20for.20raw.20.60print!.60.20and.20.60println!.60.3F>. cargo.rustflag("-Zon-broken-pipe=kill"); - // We temporarily disable linking here as part of some refactoring. - // This way, people can manually use -Z llvm-plugins and -C passes=enzyme for now. - // In a follow-up PR, we will re-enable linking here and load the pass for them. - //if builder.config.llvm_enzyme { - // cargo.rustflag("-l").rustflag("Enzyme-19"); - //} + // We want to link against registerEnzyme and in the future we want to use additional + // functionality from Enzyme core. For that we need to link against Enzyme. + if builder.config.llvm_enzyme { + let llvm_config = builder.llvm_config(builder.config.build).unwrap(); + let llvm_version_major = llvm::get_llvm_version_major(builder, &llvm_config); + cargo.rustflag("-l").rustflag(&format!("Enzyme-{llvm_version_major}")); + } // Building with protected visibility reduces the number of dynamic relocations needed, giving // us a faster startup time. However GNU ld < 2.40 will error if we try to link a shared object @@ -1064,9 +1187,7 @@ pub fn rustc_cargo( cargo.rustflag("-Zdefault-visibility=protected"); } - // We currently don't support cross-crate LTO in stage0. This also isn't hugely necessary - // and may just be a time sink. - if compiler.stage != 0 { + if is_lto_stage(compiler) { match builder.config.rust_lto { RustcLto::Thin | RustcLto::Fat => { // Since using LTO for optimizing dylibs is currently experimental, @@ -1234,6 +1355,9 @@ fn rustc_llvm_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetSelect if builder.is_rust_llvm(target) { cargo.env("LLVM_RUSTLLVM", "1"); } + if builder.config.llvm_enzyme { + cargo.env("LLVM_ENZYME", "1"); + } let llvm::LlvmResult { llvm_config, .. } = builder.ensure(llvm::Llvm { target }); cargo.env("LLVM_CONFIG", &llvm_config); @@ -1331,6 +1455,19 @@ impl Step for RustcLink { } /// Same as `std_link`, only for librustc + #[cfg_attr( + feature = "tracing", + instrument( + level = "trace", + name = "RustcLink::run", + skip_all, + fields( + compiler = ?self.compiler, + previous_stage_compiler = ?self.previous_stage_compiler, + target = ?self.target, + ), + ), + )] fn run(self, builder: &Builder<'_>) { let compiler = self.compiler; let previous_stage_compiler = self.previous_stage_compiler; @@ -1419,6 +1556,19 @@ impl Step for CodegenBackend { } } + #[cfg_attr( + feature = "tracing", + instrument( + level = "debug", + name = "CodegenBackend::run", + skip_all, + fields( + compiler = ?self.compiler, + target = ?self.target, + backend = ?self.target, + ), + ), + )] fn run(self, builder: &Builder<'_>) { let compiler = self.compiler; let target = self.target; @@ -1427,6 +1577,7 @@ impl Step for CodegenBackend { builder.ensure(Rustc::new(compiler, target)); if builder.config.keep_stage.contains(&compiler.stage) { + trace!("`keep-stage` requested"); builder.info( "WARNING: Using a potentially old codegen backend. \ This may not behave well.", @@ -1544,7 +1695,8 @@ pub fn compiler_file( return PathBuf::new(); } let mut cmd = command(compiler); - cmd.args(builder.cflags(target, GitRepo::Rustc, c)); + cmd.args(builder.cc_handled_clags(target, c)); + cmd.args(builder.cc_unhandled_cflags(target, GitRepo::Rustc, c)); cmd.arg(format!("-print-file-name={file}")); let out = cmd.run_capture_stdout(builder).stdout(); PathBuf::from(out.trim()) @@ -1573,6 +1725,15 @@ impl Step for Sysroot { /// Returns the sysroot that `compiler` is supposed to use. /// For the stage0 compiler, this is stage0-sysroot (because of the initial std build). /// For all other stages, it's the same stage directory that the compiler lives in. + #[cfg_attr( + feature = "tracing", + instrument( + level = "debug", + name = "Sysroot::run", + skip_all, + fields(compiler = ?self.compiler), + ), + )] fn run(self, builder: &Builder<'_>) -> PathBuf { let compiler = self.compiler; let host_dir = builder.out.join(compiler.host); @@ -1589,6 +1750,7 @@ impl Step for Sysroot { } }; let sysroot = sysroot_dir(compiler.stage); + trace!(stage = ?compiler.stage, ?sysroot); builder .verbose(|| println!("Removing sysroot {} to avoid caching bugs", sysroot.display())); @@ -1743,10 +1905,20 @@ impl Step for Assemble { /// This will assemble a compiler in `build/$host/stage$stage`. The compiler /// must have been previously produced by the `stage - 1` builder.build /// compiler. + #[cfg_attr( + feature = "tracing", + instrument( + level = "debug", + name = "Assemble::run", + skip_all, + fields(target_compiler = ?self.target_compiler), + ), + )] fn run(self, builder: &Builder<'_>) -> Compiler { let target_compiler = self.target_compiler; if target_compiler.stage == 0 { + trace!("stage 0 build compiler is always available, simply returning"); assert_eq!( builder.config.build, target_compiler.host, "Cannot obtain compiler for non-native build triple at stage 0" @@ -1762,9 +1934,13 @@ impl Step for Assemble { t!(fs::create_dir_all(&libdir_bin)); if builder.config.llvm_enabled(target_compiler.host) { + trace!("target_compiler.host" = ?target_compiler.host, "LLVM enabled"); + let llvm::LlvmResult { llvm_config, .. } = builder.ensure(llvm::Llvm { target: target_compiler.host }); if !builder.config.dry_run() && builder.config.llvm_tools_enabled { + trace!("LLVM tools enabled"); + let llvm_bin_dir = command(llvm_config).arg("--bindir").run_capture_stdout(builder).stdout(); let llvm_bin_dir = Path::new(llvm_bin_dir.trim()); @@ -1774,7 +1950,13 @@ impl Step for Assemble { // rustup, and lets developers use a locally built toolchain to // build projects that expect llvm tools to be present in the sysroot // (e.g. the `bootimage` crate). + + #[cfg(feature = "tracing")] + let _llvm_tools_span = + span!(tracing::Level::TRACE, "installing llvm tools to sysroot", ?libdir_bin) + .entered(); for tool in LLVM_TOOLS { + trace!("installing `{tool}`"); let tool_exe = exe(tool, target_compiler.host); let src_path = llvm_bin_dir.join(&tool_exe); // When using `download-ci-llvm`, some of the tools @@ -1794,6 +1976,7 @@ impl Step for Assemble { let maybe_install_llvm_bitcode_linker = |compiler| { if builder.config.llvm_bitcode_linker_enabled { + trace!("llvm-bitcode-linker enabled, installing"); let src_path = builder.ensure(crate::core::build_steps::tool::LlvmBitcodeLinker { compiler, target: target_compiler.host, @@ -1806,6 +1989,8 @@ impl Step for Assemble { // If we're downloading a compiler from CI, we can use the same compiler for all stages other than 0. if builder.download_rustc() { + trace!("`download-rustc` requested, reusing CI compiler for stage > 0"); + builder.ensure(Std::new(target_compiler, target_compiler.host)); let sysroot = builder.ensure(Sysroot { compiler: target_compiler, force_recompile: false }); @@ -1835,16 +2020,17 @@ impl Step for Assemble { // // FIXME: It may be faster if we build just a stage 1 compiler and then // use that to bootstrap this compiler forward. + debug!( + "ensuring build compiler is available: compiler(stage = {}, host = {:?})", + target_compiler.stage - 1, + builder.config.build, + ); let mut build_compiler = builder.compiler(target_compiler.stage - 1, builder.config.build); // Build enzyme - let enzyme_install = if builder.config.llvm_enzyme { - Some(builder.ensure(llvm::Enzyme { target: build_compiler.host })) - } else { - None - }; - - if let Some(enzyme_install) = enzyme_install { + if builder.config.llvm_enzyme { + debug!("`llvm_enzyme` requested"); + let enzyme_install = builder.ensure(llvm::Enzyme { target: build_compiler.host }); let lib_ext = std::env::consts::DLL_EXTENSION; let src_lib = enzyme_install.join("build/Enzyme/libEnzyme-19").with_extension(lib_ext); let libdir = builder.sysroot_target_libdir(build_compiler, build_compiler.host); @@ -1861,13 +2047,27 @@ impl Step for Assemble { // link to these. (FIXME: Is that correct? It seems to be correct most // of the time but I think we do link to these for stage2/bin compilers // when not performing a full bootstrap). + debug!( + ?build_compiler, + "target_compiler.host" = ?target_compiler.host, + "building compiler libraries to link to" + ); let actual_stage = builder.ensure(Rustc::new(build_compiler, target_compiler.host)); // Current build_compiler.stage might be uplifted instead of being built; so update it // to not fail while linking the artifacts. + debug!( + "(old) build_compiler.stage" = build_compiler.stage, + "(adjusted) build_compiler.stage" = actual_stage, + "temporarily adjusting `build_compiler.stage` to account for uplifted libraries" + ); build_compiler.stage = actual_stage; + #[cfg(feature = "tracing")] + let _codegen_backend_span = + span!(tracing::Level::DEBUG, "building requested codegen backends").entered(); for backend in builder.config.codegen_backends(target_compiler.host) { if backend == "llvm" { + debug!("llvm codegen backend is already built as part of rustc"); continue; // Already built as part of rustc } @@ -1877,6 +2077,8 @@ impl Step for Assemble { backend: backend.clone(), }); } + #[cfg(feature = "tracing")] + drop(_codegen_backend_span); let stage = target_compiler.stage; let host = target_compiler.host; @@ -1936,6 +2138,7 @@ impl Step for Assemble { } } + debug!("copying codegen backends to sysroot"); copy_codegen_backends_to_sysroot(builder, build_compiler, target_compiler); if builder.config.lld_enabled { @@ -1946,6 +2149,11 @@ impl Step for Assemble { } if builder.config.llvm_enabled(target_compiler.host) && builder.config.llvm_tools_enabled { + debug!( + "llvm and llvm tools enabled; copying `llvm-objcopy` as `rust-objcopy` to \ + workaround faulty homebrew `strip`s" + ); + // `llvm-strip` is used by rustc, which is actually just a symlink to `llvm-objcopy`, so // copy and rename `llvm-objcopy`. // @@ -1978,6 +2186,11 @@ impl Step for Assemble { // Ensure that `libLLVM.so` ends up in the newly build compiler directory, // so that it can be found when the newly built `rustc` is run. + debug!( + "target_compiler.host" = ?target_compiler.host, + ?sysroot, + "ensuring availability of `libLLVM.so` in compiler directory" + ); dist::maybe_install_llvm_runtime(builder, target_compiler.host, &sysroot); dist::maybe_install_llvm_target(builder, target_compiler.host, &sysroot); @@ -1987,6 +2200,7 @@ impl Step for Assemble { let bindir = sysroot.join("bin"); t!(fs::create_dir_all(bindir)); let compiler = builder.rustc(target_compiler); + debug!(src = ?rustc, dst = ?compiler, "linking compiler binary itself"); builder.copy_link(&rustc, &compiler); target_compiler @@ -2191,6 +2405,10 @@ pub fn stream_cargo( cb: &mut dyn FnMut(CargoMessage<'_>), ) -> bool { let mut cmd = cargo.into_cmd(); + + #[cfg(feature = "tracing")] + let _run_span = crate::trace_cmd!(cmd); + let cargo = cmd.as_command_mut(); // Instruct Cargo to give us json messages on stdout, critically leaving // stderr as piped so we can get those pretty colors. @@ -2267,7 +2485,8 @@ pub fn strip_debug(builder: &Builder<'_>, target: TargetSelection, path: &Path) // FIXME: to make things simpler for now, limit this to the host and target where we know // `strip -g` is both available and will fix the issue, i.e. on a x64 linux host that is not // cross-compiling. Expand this to other appropriate targets in the future. - if target != "x86_64-unknown-linux-gnu" || target != builder.config.build || !path.exists() { + if target != "x86_64-unknown-linux-gnu" || !builder.is_builder_target(target) || !path.exists() + { return; } @@ -2290,3 +2509,8 @@ pub fn strip_debug(builder: &Builder<'_>, target: TargetSelection, path: &Path) // everything else (standard library, future stages...) to be rebuilt. t!(file.set_modified(previous_mtime)); } + +/// We only use LTO for stage 2+, to speed up build time of intermediate stages. +pub fn is_lto_stage(build_compiler: &Compiler) -> bool { + build_compiler.stage != 0 +} diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 18f920b85ee..509ee9e1acf 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -16,6 +16,8 @@ use std::{env, fs}; use object::BinaryFormat; use object::read::archive::ArchiveFile; +#[cfg(feature = "tracing")] +use tracing::instrument; use crate::core::build_steps::doc::DocumentationFormat; use crate::core::build_steps::tool::{self, Tool}; @@ -30,7 +32,7 @@ use crate::utils::helpers::{ exe, is_dylib, move_file, t, target_supports_cranelift_backend, timeit, }; use crate::utils::tarball::{GeneratedTarball, OverlayKind, Tarball}; -use crate::{Compiler, DependencyType, LLVM_TOOLS, Mode}; +use crate::{Compiler, DependencyType, LLVM_TOOLS, Mode, trace}; pub fn pkgname(builder: &Builder<'_>, component: &str) -> String { format!("{}-{}", component, builder.rust_package_vers()) @@ -582,7 +584,7 @@ impl Step for DebuggerScripts { fn skip_host_target_lib(builder: &Builder<'_>, compiler: Compiler) -> bool { // The only true set of target libraries came from the build triple, so // let's reduce redundant work by only producing archives from that host. - if compiler.host != builder.config.build { + if !builder.is_builder_target(compiler.host) { builder.info("\tskipping, not a build host"); true } else { @@ -637,7 +639,7 @@ fn copy_target_libs( for (path, dependency_type) in builder.read_stamp_file(stamp) { if dependency_type == DependencyType::TargetSelfContained { builder.copy_link(&path, &self_contained_dst.join(path.file_name().unwrap())); - } else if dependency_type == DependencyType::Target || builder.config.build == target { + } else if dependency_type == DependencyType::Target || builder.is_builder_target(target) { builder.copy_link(&path, &dst.join(path.file_name().unwrap())); } } @@ -786,7 +788,7 @@ impl Step for Analysis { fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> { let compiler = self.compiler; let target = self.target; - if compiler.host != builder.config.build { + if !builder.is_builder_target(compiler.host) { return None; } @@ -2029,6 +2031,15 @@ fn install_llvm_file( /// Maybe add LLVM object files to the given destination lib-dir. Allows either static or dynamic linking. /// /// Returns whether the files were actually copied. +#[cfg_attr( + feature = "tracing", + instrument( + level = "trace", + name = "maybe_install_llvm", + skip_all, + fields(target = ?target, dst_libdir = ?dst_libdir, install_symlink = install_symlink), + ), +)] fn maybe_install_llvm( builder: &Builder<'_>, target: TargetSelection, @@ -2052,6 +2063,7 @@ fn maybe_install_llvm( // If the LLVM is coming from ourselves (just from CI) though, we // still want to install it, as it otherwise won't be available. if builder.is_system_llvm(target) { + trace!("system LLVM requested, no install"); return false; } @@ -2070,6 +2082,7 @@ fn maybe_install_llvm( } else if let llvm::LlvmBuildStatus::AlreadyBuilt(llvm::LlvmResult { llvm_config, .. }) = llvm::prebuilt_llvm_config(builder, target, true) { + trace!("LLVM already built, installing LLVM files"); let mut cmd = command(llvm_config); cmd.arg("--libfiles"); builder.verbose(|| println!("running {cmd:?}")); @@ -2092,6 +2105,19 @@ fn maybe_install_llvm( } /// Maybe add libLLVM.so to the target lib-dir for linking. +#[cfg_attr( + feature = "tracing", + instrument( + level = "trace", + name = "maybe_install_llvm_target", + skip_all, + fields( + llvm_link_shared = ?builder.llvm_link_shared(), + target = ?target, + sysroot = ?sysroot, + ), + ), +)] pub fn maybe_install_llvm_target(builder: &Builder<'_>, target: TargetSelection, sysroot: &Path) { let dst_libdir = sysroot.join("lib/rustlib").join(target).join("lib"); // We do not need to copy LLVM files into the sysroot if it is not @@ -2103,6 +2129,19 @@ pub fn maybe_install_llvm_target(builder: &Builder<'_>, target: TargetSelection, } /// Maybe add libLLVM.so to the runtime lib-dir for rustc itself. +#[cfg_attr( + feature = "tracing", + instrument( + level = "trace", + name = "maybe_install_llvm_runtime", + skip_all, + fields( + llvm_link_shared = ?builder.llvm_link_shared(), + target = ?target, + sysroot = ?sysroot, + ), + ), +)] pub fn maybe_install_llvm_runtime(builder: &Builder<'_>, target: TargetSelection, sysroot: &Path) { let dst_libdir = sysroot.join(builder.sysroot_libdir_relative(Compiler { stage: 1, host: target })); diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index dedcc139ae1..23bb47dcc58 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -572,10 +572,7 @@ impl Step for Std { fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { let builder = run.builder; - run.crate_or_deps("sysroot") - .path("library") - .alias("core") - .default_condition(builder.config.docs) + run.crate_or_deps("sysroot").path("library").default_condition(builder.config.docs) } fn make_run(run: RunConfig<'_>) { diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index 25e5e9e6eb9..3025f955660 100644 --- a/src/bootstrap/src/core/build_steps/llvm.rs +++ b/src/bootstrap/src/core/build_steps/llvm.rs @@ -16,6 +16,8 @@ use std::{env, fs}; use build_helper::ci::CiEnv; use build_helper::git::get_closest_merge_commit; +#[cfg(feature = "tracing")] +use tracing::instrument; use crate::core::builder::{Builder, RunConfig, ShouldRun, Step}; use crate::core::config::{Config, TargetSelection}; @@ -24,7 +26,7 @@ use crate::utils::exec::command; use crate::utils::helpers::{ self, exe, get_clang_cl_resource_dir, t, unhashed_basename, up_to_date, }; -use crate::{CLang, GitRepo, Kind}; +use crate::{CLang, GitRepo, Kind, trace}; #[derive(Clone)] pub struct LlvmResult { @@ -54,6 +56,14 @@ impl LlvmBuildStatus { LlvmBuildStatus::ShouldBuild(_) => true, } } + + #[cfg(test)] + pub fn llvm_result(&self) -> &LlvmResult { + match self { + LlvmBuildStatus::AlreadyBuilt(res) => res, + LlvmBuildStatus::ShouldBuild(meta) => &meta.res, + } + } } /// Linker flags to pass to LLVM's CMake invocation. @@ -120,9 +130,19 @@ pub fn prebuilt_llvm_config( let root = "src/llvm-project/llvm"; let out_dir = builder.llvm_out(target); - let mut llvm_config_ret_dir = builder.llvm_out(builder.config.build); - llvm_config_ret_dir.push("bin"); - let build_llvm_config = llvm_config_ret_dir.join(exe("llvm-config", builder.config.build)); + let build_llvm_config = if let Some(build_llvm_config) = builder + .config + .target_config + .get(&builder.config.build) + .and_then(|config| config.llvm_config.clone()) + { + build_llvm_config + } else { + let mut llvm_config_ret_dir = builder.llvm_out(builder.config.build); + llvm_config_ret_dir.push("bin"); + llvm_config_ret_dir.join(exe("llvm-config", builder.config.build)) + }; + let llvm_cmake_dir = out_dir.join("lib/cmake/llvm"); let res = LlvmResult { llvm_config: build_llvm_config, llvm_cmake_dir }; @@ -335,7 +355,7 @@ impl Step for Llvm { let llvm_targets = match &builder.config.llvm_targets { Some(s) => s, None => { - "AArch64;ARM;BPF;Hexagon;LoongArch;MSP430;Mips;NVPTX;PowerPC;RISCV;\ + "AArch64;AMDGPU;ARM;BPF;Hexagon;LoongArch;MSP430;Mips;NVPTX;PowerPC;RISCV;\ Sparc;SystemZ;WebAssembly;X86" } }; @@ -498,7 +518,7 @@ impl Step for Llvm { } // https://llvm.org/docs/HowToCrossCompileLLVM.html - if target != builder.config.build { + if !builder.is_builder_target(target) { let LlvmResult { llvm_config, .. } = builder.ensure(Llvm { target: builder.config.build }); if !builder.config.dry_run() { @@ -553,10 +573,7 @@ impl Step for Llvm { // Helper to find the name of LLVM's shared library on darwin and linux. let find_llvm_lib_name = |extension| { - let version = - command(&res.llvm_config).arg("--version").run_capture_stdout(builder).stdout(); - let major = version.split('.').next().unwrap(); - + let major = get_llvm_version_major(builder, &res.llvm_config); match &llvm_version_suffix { Some(version_suffix) => format!("libLLVM-{major}{version_suffix}.{extension}"), None => format!("libLLVM-{major}.{extension}"), @@ -606,12 +623,22 @@ impl Step for Llvm { } } +pub fn get_llvm_version(builder: &Builder<'_>, llvm_config: &Path) -> String { + command(llvm_config).arg("--version").run_capture_stdout(builder).stdout().trim().to_owned() +} + +pub fn get_llvm_version_major(builder: &Builder<'_>, llvm_config: &Path) -> u8 { + let version = get_llvm_version(builder, llvm_config); + let major_str = version.split_once('.').expect("Failed to parse LLVM version").0; + major_str.parse().unwrap() +} + fn check_llvm_version(builder: &Builder<'_>, llvm_config: &Path) { if builder.config.dry_run() { return; } - let version = command(llvm_config).arg("--version").run_capture_stdout(builder).stdout(); + let version = get_llvm_version(builder, llvm_config); let mut parts = version.split('.').take(2).filter_map(|s| s.parse::<u32>().ok()); if let (Some(major), Some(_minor)) = (parts.next(), parts.next()) { if major >= 18 { @@ -643,7 +670,7 @@ fn configure_cmake( } cfg.target(&target.triple).host(&builder.config.build.triple); - if target != builder.config.build { + if !builder.is_builder_target(target) { cfg.define("CMAKE_CROSSCOMPILING", "True"); if target.contains("netbsd") { @@ -761,9 +788,15 @@ fn configure_cmake( } cfg.build_arg("-j").build_arg(builder.jobs().to_string()); + // FIXME(madsmtm): Allow `cmake-rs` to select flags by itself by passing + // our flags via `.cflag`/`.cxxflag` instead. + // + // Needs `suppressed_compiler_flag_prefixes` to be gone, and hence + // https://github.com/llvm/llvm-project/issues/88780 to be fixed. let mut cflags: OsString = builder - .cflags(target, GitRepo::Llvm, CLang::C) + .cc_handled_clags(target, CLang::C) .into_iter() + .chain(builder.cc_unhandled_cflags(target, GitRepo::Llvm, CLang::C)) .filter(|flag| { !suppressed_compiler_flag_prefixes .iter() @@ -782,8 +815,9 @@ fn configure_cmake( } cfg.define("CMAKE_C_FLAGS", cflags); let mut cxxflags: OsString = builder - .cflags(target, GitRepo::Llvm, CLang::Cxx) + .cc_handled_clags(target, CLang::Cxx) .into_iter() + .chain(builder.cc_unhandled_cflags(target, GitRepo::Llvm, CLang::Cxx)) .filter(|flag| { !suppressed_compiler_flag_prefixes .iter() @@ -902,6 +936,15 @@ impl Step for Enzyme { } /// Compile Enzyme for `target`. + #[cfg_attr( + feature = "tracing", + instrument( + level = "debug", + name = "Enzyme::run", + skip_all, + fields(target = ?self.target), + ), + )] fn run(self, builder: &Builder<'_>) -> PathBuf { builder.require_submodule( "src/tools/enzyme", @@ -927,7 +970,9 @@ impl Step for Enzyme { let out_dir = builder.enzyme_out(target); let stamp = BuildStamp::new(&out_dir).with_prefix("enzyme").add_stamp(smart_stamp_hash); + trace!("checking build stamp to see if we need to rebuild enzyme artifacts"); if stamp.is_up_to_date() { + trace!(?out_dir, "enzyme build artifacts are up to date"); if stamp.stamp().is_empty() { builder.info( "Could not determine the Enzyme submodule commit hash. \ @@ -941,6 +986,7 @@ impl Step for Enzyme { return out_dir; } + trace!(?target, "(re)building enzyme artifacts"); builder.info(&format!("Building Enzyme for {}", target)); t!(stamp.remove()); let _time = helpers::timeit(builder); @@ -962,12 +1008,14 @@ impl Step for Enzyme { (true, false) => "Release", (true, true) => "RelWithDebInfo", }; + trace!(?profile); cfg.out_dir(&out_dir) .profile(profile) .env("LLVM_CONFIG_REAL", &llvm_config) .define("LLVM_ENABLE_ASSERTIONS", "ON") .define("ENZYME_EXTERNAL_SHARED_LIB", "ON") + .define("ENZYME_RUNPASS", "ON") .define("LLVM_DIR", builder.llvm_out(target)); cfg.build(); @@ -1085,7 +1133,7 @@ impl Step for Lld { .define("LLVM_CMAKE_DIR", llvm_cmake_dir) .define("LLVM_INCLUDE_TESTS", "OFF"); - if target != builder.config.build { + if !builder.is_builder_target(target) { // Use the host llvm-tblgen binary. cfg.define( "LLVM_TABLEGEN_EXE", diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 825e5452f0e..b3f4a7bad99 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -12,6 +12,7 @@ use clap_complete::shells; use crate::core::build_steps::compile::run_cargo; use crate::core::build_steps::doc::DocumentationFormat; +use crate::core::build_steps::llvm::get_llvm_version; use crate::core::build_steps::synthetic_targets::MirOptPanicAbortSyntheticTarget; use crate::core::build_steps::tool::{self, SourceType, Tool}; use crate::core::build_steps::toolstate::ToolState; @@ -1648,16 +1649,17 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the // bootstrap compiler. // NOTE: Only stage 1 is special cased because we need the rustc_private artifacts to match the // running compiler in stage 2 when plugins run. - let stage_id = if suite == "ui-fulldeps" && compiler.stage == 1 { - // At stage 0 (stage - 1) we are using the beta compiler. Using `self.target` can lead finding - // an incorrect compiler path on cross-targets, as the stage 0 beta compiler is always equal - // to `build.build` in the configuration. + let (stage, stage_id) = if suite == "ui-fulldeps" && compiler.stage == 1 { + // At stage 0 (stage - 1) we are using the beta compiler. Using `self.target` can lead + // finding an incorrect compiler path on cross-targets, as the stage 0 beta compiler is + // always equal to `build.build` in the configuration. let build = builder.build.build; - compiler = builder.compiler(compiler.stage - 1, build); - format!("stage{}-{}", compiler.stage + 1, build) + let test_stage = compiler.stage + 1; + (test_stage, format!("stage{}-{}", test_stage, build)) } else { - format!("stage{}-{}", compiler.stage, target) + let stage = compiler.stage; + (stage, format!("stage{}-{}", stage, target)) }; if suite.ends_with("fulldeps") { @@ -1699,6 +1701,9 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the // compiletest currently has... a lot of arguments, so let's just pass all // of them! + cmd.arg("--stage").arg(stage.to_string()); + cmd.arg("--stage-id").arg(stage_id); + cmd.arg("--compile-lib-path").arg(builder.rustc_libdir(compiler)); cmd.arg("--run-lib-path").arg(builder.sysroot_target_libdir(compiler, target)); cmd.arg("--rustc-path").arg(builder.rustc(compiler)); @@ -1767,8 +1772,9 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the } else { builder.sysroot(compiler).to_path_buf() }; + cmd.arg("--sysroot-base").arg(sysroot); - cmd.arg("--stage-id").arg(stage_id); + cmd.arg("--suite").arg(suite); cmd.arg("--mode").arg(mode); cmd.arg("--target").arg(target.rustc_target_arg()); @@ -1840,6 +1846,14 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the } } + // FIXME(136096): on macOS, we get linker warnings about duplicate `-lm` flags. + // NOTE: `stage > 1` here because `test --stage 1 ui-fulldeps` is a hack that compiles + // with stage 0, but links the tests against stage 1. + // cfg(bootstrap) - remove only the `stage > 1` check, leave everything else. + if suite == "ui-fulldeps" && compiler.stage > 1 && target.ends_with("darwin") { + flags.push("-Alinker_messages".into()); + } + let mut hostflags = flags.clone(); hostflags.push(format!("-Lnative={}", builder.test_helpers_out(compiler.host).display())); hostflags.extend(linker_flags(builder, compiler.host, LldThreads::No)); @@ -1847,12 +1861,6 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the let mut targetflags = flags; targetflags.push(format!("-Lnative={}", builder.test_helpers_out(target).display())); - // FIXME: on macOS, we get linker warnings about duplicate `-lm` flags. We should investigate why this happens. - if suite == "ui-fulldeps" && target.ends_with("darwin") { - hostflags.push("-Alinker_messages".into()); - targetflags.push("-Alinker_messages".into()); - } - for flag in hostflags { cmd.arg("--host-rustcflags").arg(flag); } @@ -1940,8 +1948,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the let llvm::LlvmResult { llvm_config, .. } = builder.ensure(llvm::Llvm { target: builder.config.build }); if !builder.config.dry_run() { - let llvm_version = - command(&llvm_config).arg("--version").run_capture_stdout(builder).stdout(); + let llvm_version = get_llvm_version(builder, &llvm_config); let llvm_components = command(&llvm_config).arg("--components").run_capture_stdout(builder).stdout(); // Remove trailing newline from llvm-config output. @@ -1964,13 +1971,12 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the if !builder.config.dry_run() && suite.ends_with("fulldeps") { let llvm_libdir = command(&llvm_config).arg("--libdir").run_capture_stdout(builder).stdout(); - let mut rustflags = env::var("RUSTFLAGS").unwrap_or_default(); - if target.is_msvc() { - rustflags.push_str(&format!("-Clink-arg=-LIBPATH:{llvm_libdir}")); + let link_llvm = if target.is_msvc() { + format!("-Clink-arg=-LIBPATH:{llvm_libdir}") } else { - rustflags.push_str(&format!("-Clink-arg=-L{llvm_libdir}")); - } - cmd.env("RUSTFLAGS", rustflags); + format!("-Clink-arg=-L{llvm_libdir}") + }; + cmd.arg("--host-rustcflags").arg(link_llvm); } if !builder.config.dry_run() && matches!(mode, "run-make" | "coverage-run") { @@ -2006,14 +2012,18 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the // Only pass correct values for these flags for the `run-make` suite as it // requires that a C++ compiler was configured which isn't always the case. if !builder.config.dry_run() && mode == "run-make" { + let mut cflags = builder.cc_handled_clags(target, CLang::C); + cflags.extend(builder.cc_unhandled_cflags(target, GitRepo::Rustc, CLang::C)); + let mut cxxflags = builder.cc_handled_clags(target, CLang::Cxx); + cxxflags.extend(builder.cc_unhandled_cflags(target, GitRepo::Rustc, CLang::Cxx)); cmd.arg("--cc") .arg(builder.cc(target)) .arg("--cxx") .arg(builder.cxx(target).unwrap()) .arg("--cflags") - .arg(builder.cflags(target, GitRepo::Rustc, CLang::C).join(" ")) + .arg(cflags.join(" ")) .arg("--cxxflags") - .arg(builder.cflags(target, GitRepo::Rustc, CLang::Cxx).join(" ")); + .arg(cxxflags.join(" ")); copts_passed = true; if let Some(ar) = builder.ar(target) { cmd.arg("--ar").arg(ar); @@ -2733,7 +2743,7 @@ impl Step for Crate { cargo } else { // Also prepare a sysroot for the target. - if builder.config.build != target { + if !builder.is_builder_target(target) { builder.ensure(compile::Std::new(compiler, target).force_recompile(true)); builder.ensure(RemoteCopyLibs { compiler, target }); } diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 793fa24991b..a54db9d7815 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -1,6 +1,10 @@ use std::path::PathBuf; use std::{env, fs}; +#[cfg(feature = "tracing")] +use tracing::instrument; + +use crate::core::build_steps::compile::is_lto_stage; use crate::core::build_steps::toolstate::ToolState; use crate::core::build_steps::{compile, llvm}; use crate::core::builder; @@ -303,6 +307,14 @@ macro_rules! bootstrap_tool { }); } + #[cfg_attr( + feature = "tracing", + instrument( + level = "debug", + name = $tool_name, + skip_all, + ), + )] fn run(self, builder: &Builder<'_>) -> PathBuf { $( for submodule in $submodules { @@ -659,14 +671,16 @@ impl Step for Rustdoc { ); // rustdoc is performance sensitive, so apply LTO to it. - let lto = match builder.config.rust_lto { - RustcLto::Off => Some("off"), - RustcLto::Thin => Some("thin"), - RustcLto::Fat => Some("fat"), - RustcLto::ThinLocal => None, - }; - if let Some(lto) = lto { - cargo.env(cargo_profile_var("LTO", &builder.config), lto); + if is_lto_stage(&build_compiler) { + let lto = match builder.config.rust_lto { + RustcLto::Off => Some("off"), + RustcLto::Thin => Some("thin"), + RustcLto::Fat => Some("fat"), + RustcLto::ThinLocal => None, + }; + if let Some(lto) = lto { + cargo.env(cargo_profile_var("LTO", &builder.config), lto); + } } let _guard = builder.msg_tool( @@ -755,6 +769,15 @@ impl Step for LldWrapper { run.never() } + #[cfg_attr( + feature = "tracing", + instrument( + level = "debug", + name = "LldWrapper::run", + skip_all, + fields(build_compiler = ?self.build_compiler, target_compiler = ?self.target_compiler), + ), + )] fn run(self, builder: &Builder<'_>) { if builder.config.dry_run() { return; @@ -911,6 +934,10 @@ impl Step for LlvmBitcodeLinker { }); } + #[cfg_attr( + feature = "tracing", + instrument(level = "debug", name = "LlvmBitcodeLinker::run", skip_all) + )] fn run(self, builder: &Builder<'_>) -> PathBuf { let bin_name = "llvm-bitcode-linker"; diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index 2ecab262413..59680af0062 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -245,7 +245,11 @@ impl Cargo { // flesh out rpath support more fully in the future. self.rustflags.arg("-Zosx-rpath-install-name"); Some(format!("-Wl,-rpath,@loader_path/../{libdir}")) - } else if !target.is_windows() && !target.contains("aix") && !target.contains("xous") { + } else if !target.is_windows() + && !target.contains("cygwin") + && !target.contains("aix") + && !target.contains("xous") + { self.rustflags.arg("-Clink-args=-Wl,-z,origin"); Some(format!("-Wl,-rpath,$ORIGIN/../{libdir}")) } else { @@ -323,8 +327,15 @@ impl Cargo { let cc = ccacheify(&builder.cc(target)); self.command.env(format!("CC_{triple_underscored}"), &cc); - let cflags = builder.cflags(target, GitRepo::Rustc, CLang::C).join(" "); - self.command.env(format!("CFLAGS_{triple_underscored}"), &cflags); + // Extend `CXXFLAGS_$TARGET` with our extra flags. + let env = format!("CFLAGS_{triple_underscored}"); + let mut cflags = + builder.cc_unhandled_cflags(target, GitRepo::Rustc, CLang::C).join(" "); + if let Ok(var) = std::env::var(&env) { + cflags.push(' '); + cflags.push_str(&var); + } + self.command.env(env, &cflags); if let Some(ar) = builder.ar(target) { let ranlib = format!("{} s", ar.display()); @@ -335,10 +346,17 @@ impl Cargo { if let Ok(cxx) = builder.cxx(target) { let cxx = ccacheify(&cxx); - let cxxflags = builder.cflags(target, GitRepo::Rustc, CLang::Cxx).join(" "); - self.command - .env(format!("CXX_{triple_underscored}"), &cxx) - .env(format!("CXXFLAGS_{triple_underscored}"), cxxflags); + self.command.env(format!("CXX_{triple_underscored}"), &cxx); + + // Extend `CXXFLAGS_$TARGET` with our extra flags. + let env = format!("CXXFLAGS_{triple_underscored}"); + let mut cxxflags = + builder.cc_unhandled_cflags(target, GitRepo::Rustc, CLang::Cxx).join(" "); + if let Ok(var) = std::env::var(&env) { + cxxflags.push(' '); + cxxflags.push_str(&var); + } + self.command.env(&env, cxxflags); } } diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index 8e767a8dcc6..daef8fa3c8a 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -10,6 +10,8 @@ use std::time::{Duration, Instant}; use std::{env, fs}; use clap::ValueEnum; +#[cfg(feature = "tracing")] +use tracing::instrument; pub use self::cargo::{Cargo, cargo_profile_var}; pub use crate::Compiler; @@ -21,7 +23,7 @@ use crate::core::config::{DryRun, TargetSelection}; use crate::utils::cache::Cache; use crate::utils::exec::{BootstrapCommand, command}; use crate::utils::helpers::{self, LldThreads, add_dylib_path, exe, libdir, linker_args, t}; -use crate::{Build, Crate}; +use crate::{Build, Crate, trace}; mod cargo; @@ -127,10 +129,14 @@ impl RunConfig<'_> { pub fn cargo_crates_in_set(&self) -> Vec<String> { let mut crates = Vec::new(); for krate in &self.paths { - let path = krate.assert_single_path(); - let Some(crate_name) = self.builder.crate_paths.get(&path.path) else { - panic!("missing crate for path {}", path.path.display()) - }; + let path = &krate.assert_single_path().path; + + let crate_name = self + .builder + .crate_paths + .get(path) + .unwrap_or_else(|| panic!("missing crate for path {}", path.display())); + crates.push(crate_name.to_string()); } crates @@ -1214,6 +1220,19 @@ impl<'a> Builder<'a> { /// compiler will run on, *not* the target it will build code for). Explicitly does not take /// `Compiler` since all `Compiler` instances are meant to be obtained through this function, /// since it ensures that they are valid (i.e., built and assembled). + #[cfg_attr( + feature = "tracing", + instrument( + level = "trace", + name = "Builder::compiler", + target = "COMPILER", + skip_all, + fields( + stage = stage, + host = ?host, + ), + ), + )] pub fn compiler(&self, stage: u32, host: TargetSelection) -> Compiler { self.ensure(compile::Assemble { target_compiler: Compiler { stage, host } }) } @@ -1229,19 +1248,39 @@ impl<'a> Builder<'a> { /// sysroot. /// /// See `force_use_stage1` and `force_use_stage2` for documentation on what each argument is. + #[cfg_attr( + feature = "tracing", + instrument( + level = "trace", + name = "Builder::compiler_for", + target = "COMPILER_FOR", + skip_all, + fields( + stage = stage, + host = ?host, + target = ?target, + ), + ), + )] pub fn compiler_for( &self, stage: u32, host: TargetSelection, target: TargetSelection, ) -> Compiler { - if self.build.force_use_stage2(stage) { + #![allow(clippy::let_and_return)] + let resolved_compiler = if self.build.force_use_stage2(stage) { + trace!(target: "COMPILER_FOR", ?stage, "force_use_stage2"); self.compiler(2, self.config.build) } else if self.build.force_use_stage1(stage, target) { + trace!(target: "COMPILER_FOR", ?stage, "force_use_stage1"); self.compiler(1, self.config.build) } else { + trace!(target: "COMPILER_FOR", ?stage, ?host, "no force, fallback to `compiler()`"); self.compiler(stage, host) - } + }; + trace!(target: "COMPILER_FOR", ?resolved_compiler); + resolved_compiler } pub fn sysroot(&self, compiler: Compiler) -> PathBuf { @@ -1431,7 +1470,7 @@ impl<'a> Builder<'a> { /// /// Note that this returns `None` if LLVM is disabled, or if we're in a /// check build or dry-run, where there's no need to build all of LLVM. - fn llvm_config(&self, target: TargetSelection) -> Option<PathBuf> { + pub fn llvm_config(&self, target: TargetSelection) -> Option<PathBuf> { if self.config.llvm_enabled(target) && self.kind != Kind::Check && !self.config.dry_run() { let llvm::LlvmResult { llvm_config, .. } = self.ensure(llvm::Llvm { target }); if llvm_config.is_file() { diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 74e1ed5c637..445b5dfbeab 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -1,5 +1,7 @@ use std::thread; +use llvm::prebuilt_llvm_config; + use super::*; use crate::Flags; use crate::core::build_steps::doc::DocumentationFormat; @@ -954,3 +956,131 @@ fn test_test_coverage() { assert_eq!(modes, expected); } } + +#[test] +fn test_prebuilt_llvm_config_path_resolution() { + fn configure(config: &str) -> Config { + Config::parse_inner( + Flags::parse(&[ + "build".to_string(), + "--dry-run".to_string(), + "--config=/does/not/exist".to_string(), + ]), + |&_| toml::from_str(&config), + ) + } + + // Removes Windows disk prefix if present + fn drop_win_disk_prefix_if_present(path: PathBuf) -> PathBuf { + let path_str = path.to_str().unwrap(); + if let Some((_, without_prefix)) = path_str.split_once(":/") { + return PathBuf::from(format!("/{}", without_prefix)); + } + + path + } + + let config = configure( + r#" + [llvm] + download-ci-llvm = false + + [build] + build = "x86_64-unknown-linux-gnu" + host = ["arm-unknown-linux-gnueabihf"] + target = ["arm-unknown-linux-gnueabihf"] + + [target.x86_64-unknown-linux-gnu] + llvm-config = "/some/path/to/llvm-config" + + [target.arm-unknown-linux-gnueabihf] + cc = "arm-linux-gnueabihf-gcc" + cxx = "arm-linux-gnueabihf-g++" + "#, + ); + + let build = Build::new(config); + let builder = Builder::new(&build); + + let expected = PathBuf::from("/some/path/to/llvm-config"); + + let actual = prebuilt_llvm_config( + &builder, + TargetSelection::from_user("arm-unknown-linux-gnueabihf"), + false, + ) + .llvm_result() + .llvm_config + .clone(); + let actual = drop_win_disk_prefix_if_present(actual); + assert_eq!(expected, actual); + + let actual = prebuilt_llvm_config(&builder, builder.config.build, false) + .llvm_result() + .llvm_config + .clone(); + let actual = drop_win_disk_prefix_if_present(actual); + assert_eq!(expected, actual); + assert_eq!(expected, actual); + + let config = configure( + r#" + [llvm] + download-ci-llvm = false + "#, + ); + + let build = Build::new(config.clone()); + let builder = Builder::new(&build); + + let actual = prebuilt_llvm_config(&builder, builder.config.build, false) + .llvm_result() + .llvm_config + .clone(); + let expected = builder + .out + .join(builder.config.build) + .join("llvm/bin") + .join(exe("llvm-config", builder.config.build)); + assert_eq!(expected, actual); + + let config = configure( + r#" + [llvm] + download-ci-llvm = true + "#, + ); + + // CI-LLVM isn't always available; check if it's enabled before testing. + if config.llvm_from_ci { + let build = Build::new(config.clone()); + let builder = Builder::new(&build); + + let actual = prebuilt_llvm_config(&builder, builder.config.build, false) + .llvm_result() + .llvm_config + .clone(); + let expected = builder + .out + .join(builder.config.build) + .join("ci-llvm/bin") + .join(exe("llvm-config", builder.config.build)); + assert_eq!(expected, actual); + } +} + +#[test] +fn test_is_builder_target() { + let target1 = TargetSelection::from_user(TEST_TRIPLE_1); + let target2 = TargetSelection::from_user(TEST_TRIPLE_2); + + for (target1, target2) in [(target1, target2), (target2, target1)] { + let mut config = configure("build", &[], &[]); + config.build = target1; + let build = Build::new(config); + let builder = Builder::new(&build); + + assert!(builder.is_builder_target(target1)); + assert!(!builder.is_builder_target(target2)); + } +} diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index d3ed7ecddd3..d27a8b155df 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -935,6 +935,7 @@ define_config! { optimized_compiler_builtins: Option<bool> = "optimized-compiler-builtins", jobs: Option<u32> = "jobs", compiletest_diff_tool: Option<String> = "compiletest-diff-tool", + ccache: Option<StringOrBool> = "ccache", } } @@ -961,6 +962,7 @@ define_config! { tests: Option<bool> = "tests", enzyme: Option<bool> = "enzyme", plugins: Option<bool> = "plugins", + // FIXME: Remove this field at Q2 2025, it has been replaced by build.ccache ccache: Option<StringOrBool> = "ccache", static_libstdcpp: Option<bool> = "static-libstdcpp", libzstd: Option<bool> = "libzstd", @@ -1622,6 +1624,7 @@ impl Config { optimized_compiler_builtins, jobs, compiletest_diff_tool, + mut ccache, } = toml.build.unwrap_or_default(); config.jobs = Some(threads_from_config(flags.jobs.unwrap_or(jobs.unwrap_or(0)))); @@ -2006,7 +2009,7 @@ impl Config { tests, enzyme, plugins, - ccache, + ccache: llvm_ccache, static_libstdcpp, libzstd, ninja, @@ -2029,13 +2032,11 @@ impl Config { download_ci_llvm, build_config, } = llvm; - match ccache { - Some(StringOrBool::String(ref s)) => config.ccache = Some(s.to_string()), - Some(StringOrBool::Bool(true)) => { - config.ccache = Some("ccache".to_string()); - } - Some(StringOrBool::Bool(false)) | None => {} + if llvm_ccache.is_some() { + eprintln!("Warning: llvm.ccache is deprecated. Use build.ccache instead."); } + + ccache = ccache.or(llvm_ccache); set(&mut config.ninja_in_file, ninja); llvm_tests = tests; llvm_enzyme = enzyme; @@ -2189,6 +2190,14 @@ impl Config { } } + match ccache { + Some(StringOrBool::String(ref s)) => config.ccache = Some(s.to_string()), + Some(StringOrBool::Bool(true)) => { + config.ccache = Some("ccache".to_string()); + } + Some(StringOrBool::Bool(false)) | None => {} + } + if config.llvm_from_ci { let triple = &config.build.triple; let ci_llvm_bin = config.ci_llvm_root().join("bin"); @@ -2738,6 +2747,15 @@ impl Config { /// tarball). Typically [`crate::Build::require_submodule`] should be /// used instead to provide a nice error to the user if the submodule is /// missing. + #[cfg_attr( + feature = "tracing", + instrument( + level = "trace", + name = "Config::update_submodule", + skip_all, + fields(relative_path = ?relative_path), + ), + )] pub(crate) fn update_submodule(&self, relative_path: &str) { if !self.submodules() { return; diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index 6c8cda18548..241b7386d18 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -329,7 +329,7 @@ than building it. if target.contains("musl") && !target.contains("unikraft") { // If this is a native target (host is also musl) and no musl-root is given, // fall back to the system toolchain in /usr before giving up - if build.musl_root(*target).is_none() && build.config.build == *target { + if build.musl_root(*target).is_none() && build.is_builder_target(*target) { let target = build.config.target_config.entry(*target).or_default(); target.musl_root = Some("/usr".into()); } diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index bc146eda1d5..62ddc7d682e 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -249,6 +249,7 @@ impl Mode { } } +#[derive(Debug, Hash, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub enum CLang { C, Cxx, @@ -468,6 +469,15 @@ impl Build { /// /// The given `err_hint` will be shown to the user if the submodule is not /// checked out and submodule management is disabled. + #[cfg_attr( + feature = "tracing", + instrument( + level = "trace", + name = "Build::require_submodule", + skip_all, + fields(submodule = submodule), + ), + )] pub fn require_submodule(&self, submodule: &str, err_hint: Option<&str>) { // When testing bootstrap itself, it is much faster to ignore // submodules. Almost all Steps work fine without their submodules. @@ -738,7 +748,7 @@ impl Build { /// Note that if LLVM is configured externally then the directory returned /// will likely be empty. fn llvm_out(&self, target: TargetSelection) -> PathBuf { - if self.config.llvm_from_ci && self.config.build == target { + if self.config.llvm_from_ci && self.is_builder_target(target) { self.config.ci_llvm_root() } else { self.out.join(target).join("llvm") @@ -788,7 +798,7 @@ impl Build { fn is_system_llvm(&self, target: TargetSelection) -> bool { match self.config.target_config.get(&target) { Some(Target { llvm_config: Some(_), .. }) => { - let ci_llvm = self.config.llvm_from_ci && target == self.config.build; + let ci_llvm = self.config.llvm_from_ci && self.is_builder_target(target); !ci_llvm } // We're building from the in-tree src/llvm-project sources. @@ -904,6 +914,9 @@ impl Build { return CommandOutput::default(); } + #[cfg(feature = "tracing")] + let _run_span = trace_cmd!(command); + let created_at = command.get_created_location(); let executed_at = std::panic::Location::caller(); @@ -1178,9 +1191,9 @@ Executed at: {executed_at}"#, self.cc.borrow()[&target].path().into() } - /// Returns a list of flags to pass to the C compiler for the target - /// specified. - fn cflags(&self, target: TargetSelection, which: GitRepo, c: CLang) -> Vec<String> { + /// Returns C flags that `cc-rs` thinks should be enabled for the + /// specified target by default. + fn cc_handled_clags(&self, target: TargetSelection, c: CLang) -> Vec<String> { if self.config.dry_run() { return Vec::new(); } @@ -1189,14 +1202,23 @@ Executed at: {executed_at}"#, CLang::Cxx => self.cxx.borrow()[&target].clone(), }; - // Filter out -O and /O (the optimization flags) that we picked up from - // cc-rs because the build scripts will determine that for themselves. - let mut base = base - .args() + // Filter out -O and /O (the optimization flags) that we picked up + // from cc-rs, that's up to the caller to figure out. + base.args() .iter() .map(|s| s.to_string_lossy().into_owned()) .filter(|s| !s.starts_with("-O") && !s.starts_with("/O")) - .collect::<Vec<String>>(); + .collect::<Vec<String>>() + } + + /// Returns extra C flags that `cc-rs` doesn't handle. + fn cc_unhandled_cflags( + &self, + target: TargetSelection, + which: GitRepo, + c: CLang, + ) -> Vec<String> { + let mut base = Vec::new(); // If we're compiling C++ on macOS then we add a flag indicating that // we want libc++ (more filled out than libstdc++), ensuring that @@ -1264,7 +1286,7 @@ Executed at: {executed_at}"#, // need to use CXX compiler as linker to resolve the exception functions // that are only existed in CXX libraries Some(self.cxx.borrow()[&target].path().into()) - } else if target != self.config.build + } else if !self.is_builder_target(target) && helpers::use_host_linker(target) && !target.is_msvc() { @@ -1915,6 +1937,11 @@ to download LLVM rather than building it. stream.reset().unwrap(); result } + + /// Checks if the given target is the same as the builder target. + fn is_builder_target(&self, target: TargetSelection) -> bool { + self.config.build == target + } } #[cfg(unix)] diff --git a/src/bootstrap/src/utils/cache.rs b/src/bootstrap/src/utils/cache.rs index 29342cc5a2c..1c8cc4025df 100644 --- a/src/bootstrap/src/utils/cache.rs +++ b/src/bootstrap/src/utils/cache.rs @@ -1,3 +1,17 @@ +//! This module helps you efficiently store and retrieve values using interning. +//! +//! Interning is a neat trick that keeps only one copy of identical values, saving memory +//! and making comparisons super fast. Here, we provide the `Interned<T>` struct and the `Internable` trait +//! to make interning easy for different data types. +//! +//! The `Interner` struct handles caching for common types like `String`, `PathBuf`, and `Vec<String>`, +//! while the `Cache` struct acts as a write-once storage for linking computation steps with their results. +//! +//! # Thread Safety +//! +//! We use `Mutex` to make sure interning and retrieval are thread-safe. But keep in mind—once a value is +//! interned, it sticks around for the entire lifetime of the program. + use std::any::{Any, TypeId}; use std::borrow::Borrow; use std::cell::RefCell; @@ -12,6 +26,9 @@ use std::{fmt, mem}; use crate::core::builder::Step; +/// Represents an interned value of type `T`, allowing for efficient comparisons and retrieval. +/// +/// This struct stores a unique index referencing the interned value within an internal cache. pub struct Interned<T>(usize, PhantomData<*const T>); impl<T: Internable + Default> Default for Interned<T> { @@ -111,6 +128,10 @@ impl<T: Internable + Ord> Ord for Interned<T> { } } +/// A structure for managing the interning of values of type `T`. +/// +/// `TyIntern<T>` maintains a mapping between values and their interned representations, +/// ensuring that duplicate values are not stored multiple times. struct TyIntern<T: Clone + Eq> { items: Vec<T>, set: HashMap<T, Interned<T>>, @@ -123,6 +144,9 @@ impl<T: Hash + Clone + Eq> Default for TyIntern<T> { } impl<T: Hash + Clone + Eq> TyIntern<T> { + /// Interns a borrowed value, ensuring it is stored uniquely. + /// + /// If the value has been previously interned, the same `Interned<T>` instance is returned. fn intern_borrow<B>(&mut self, item: &B) -> Interned<T> where B: Eq + Hash + ToOwned<Owned = T> + ?Sized, @@ -138,6 +162,9 @@ impl<T: Hash + Clone + Eq> TyIntern<T> { interned } + /// Interns an owned value, storing it uniquely. + /// + /// If the value has been previously interned, the existing `Interned<T>` is returned. fn intern(&mut self, item: T) -> Interned<T> { if let Some(i) = self.set.get(&item) { return *i; @@ -148,11 +175,16 @@ impl<T: Hash + Clone + Eq> TyIntern<T> { interned } + /// Retrieves a reference to the interned value associated with the given `Interned<T>` instance. fn get(&self, i: Interned<T>) -> &T { &self.items[i.0] } } +/// A global interner for managing interned values of common types. +/// +/// This structure maintains caches for `String`, `PathBuf`, and `Vec<String>`, ensuring efficient storage +/// and retrieval of frequently used values. #[derive(Default)] pub struct Interner { strs: Mutex<TyIntern<String>>, @@ -160,6 +192,10 @@ pub struct Interner { lists: Mutex<TyIntern<Vec<String>>>, } +/// Defines the behavior required for a type to be internable. +/// +/// Types implementing this trait must provide access to a static cache and define an `intern` method +/// that ensures values are stored uniquely. trait Internable: Clone + Eq + Hash + 'static { fn intern_cache() -> &'static Mutex<TyIntern<Self>>; @@ -187,11 +223,15 @@ impl Internable for Vec<String> { } impl Interner { + /// Interns a string reference, ensuring it is stored uniquely. + /// + /// If the string has been previously interned, the same `Interned<String>` instance is returned. pub fn intern_str(&self, s: &str) -> Interned<String> { self.strs.lock().unwrap().intern_borrow(s) } } +/// A global instance of `Interner` that caches common interned values. pub static INTERNER: LazyLock<Interner> = LazyLock::new(Interner::default); /// This is essentially a `HashMap` which allows storing any type in its input and @@ -209,10 +249,12 @@ pub struct Cache( ); impl Cache { + /// Creates a new empty cache. pub fn new() -> Cache { Cache(RefCell::new(HashMap::new())) } + /// Stores the result of a computation step in the cache. pub fn put<S: Step>(&self, step: S, value: S::Output) { let mut cache = self.0.borrow_mut(); let type_id = TypeId::of::<S>(); @@ -225,6 +267,7 @@ impl Cache { stepcache.insert(step, value); } + /// Retrieves a cached result for the given step, if available. pub fn get<S: Step>(&self, step: &S) -> Option<S::Output> { let mut cache = self.0.borrow_mut(); let type_id = TypeId::of::<S>(); @@ -255,3 +298,6 @@ impl Cache { self.0.borrow().contains_key(&TypeId::of::<S>()) } } + +#[cfg(test)] +mod tests; diff --git a/src/bootstrap/src/utils/cache/tests.rs b/src/bootstrap/src/utils/cache/tests.rs new file mode 100644 index 00000000000..28f5563a589 --- /dev/null +++ b/src/bootstrap/src/utils/cache/tests.rs @@ -0,0 +1,52 @@ +use std::path::PathBuf; + +use crate::utils::cache::{INTERNER, Internable, TyIntern}; + +#[test] +fn test_string_interning() { + let s1 = INTERNER.intern_str("Hello"); + let s2 = INTERNER.intern_str("Hello"); + let s3 = INTERNER.intern_str("world"); + + assert_eq!(s1, s2, "Same strings should be interned to the same instance"); + assert_ne!(s1, s3, "Different strings should have different interned values"); +} + +#[test] +fn test_path_interning() { + let p1 = PathBuf::from("/tmp/file").intern(); + let p2 = PathBuf::from("/tmp/file").intern(); + let p3 = PathBuf::from("/tmp/other").intern(); + + assert_eq!(p1, p2); + assert_ne!(p1, p3); +} + +#[test] +fn test_vec_interning() { + let v1 = vec!["a".to_string(), "b".to_string()].intern(); + let v2 = vec!["a".to_string(), "b".to_string()].intern(); + let v3 = vec!["c".to_string()].intern(); + + assert_eq!(v1, v2); + assert_ne!(v1, v3); +} + +#[test] +fn test_interned_equality() { + let s1 = INTERNER.intern_str("test"); + let s2 = INTERNER.intern_str("test"); + + assert_eq!(s1, s2); + assert_eq!(s1, "test"); +} + +#[test] +fn test_ty_intern_intern_borrow() { + let mut interner = TyIntern::default(); + let s1 = interner.intern_borrow("borrowed"); + let s2 = interner.intern("borrowed".to_string()); + + assert_eq!(s1, s2); + assert_eq!(interner.get(s1), "borrowed"); +} diff --git a/src/bootstrap/src/utils/cc_detect.rs b/src/bootstrap/src/utils/cc_detect.rs index 4aec554b432..1e84a7deff1 100644 --- a/src/bootstrap/src/utils/cc_detect.rs +++ b/src/bootstrap/src/utils/cc_detect.rs @@ -29,11 +29,9 @@ use crate::core::config::TargetSelection; use crate::utils::exec::{BootstrapCommand, command}; use crate::{Build, CLang, GitRepo}; -// The `cc` crate doesn't provide a way to obtain a path to the detected archiver, -// so use some simplified logic here. First we respect the environment variable `AR`, then -// try to infer the archiver path from the C compiler path. -// In the future this logic should be replaced by calling into the `cc` crate. -fn cc2ar(cc: &Path, target: TargetSelection) -> Option<PathBuf> { +/// Finds archiver tool for the given target if possible. +/// FIXME(onur-ozkan): This logic should be replaced by calling into the `cc` crate. +fn cc2ar(cc: &Path, target: TargetSelection, default_ar: PathBuf) -> Option<PathBuf> { if let Some(ar) = env::var_os(format!("AR_{}", target.triple.replace('-', "_"))) { Some(PathBuf::from(ar)) } else if let Some(ar) = env::var_os("AR") { @@ -57,19 +55,11 @@ fn cc2ar(cc: &Path, target: TargetSelection) -> Option<PathBuf> { } else if target.contains("android") || target.contains("-wasi") { Some(cc.parent().unwrap().join(PathBuf::from("llvm-ar"))) } else { - let parent = cc.parent().unwrap(); - let file = cc.file_name().unwrap().to_str().unwrap(); - for suffix in &["gcc", "cc", "clang"] { - if let Some(idx) = file.rfind(suffix) { - let mut file = file[..idx].to_owned(); - file.push_str("ar"); - return Some(parent.join(&file)); - } - } - Some(parent.join(file)) + Some(default_ar) } } +/// Creates and configures a new [`cc::Build`] instance for the given target. fn new_cc_build(build: &Build, target: TargetSelection) -> cc::Build { let mut cfg = cc::Build::new(); cfg.cargo_metadata(false) @@ -96,6 +86,12 @@ fn new_cc_build(build: &Build, target: TargetSelection) -> cc::Build { cfg } +/// Probes for C and C++ compilers and configures the corresponding entries in the [`Build`] +/// structure. +/// +/// This function determines which targets need a C compiler (and, if needed, a C++ compiler) +/// by combining the primary build target, host targets, and any additional targets. For +/// each target, it calls [`find_target`] to configure the necessary compiler tools. pub fn find(build: &Build) { let targets: HashSet<_> = match build.config.cmd { // We don't need to check cross targets for these commands. @@ -124,6 +120,11 @@ pub fn find(build: &Build) { } } +/// Probes and configures the C and C++ compilers for a single target. +/// +/// This function uses both user-specified configuration (from `config.toml`) and auto-detection +/// logic to determine the correct C/C++ compilers for the target. It also determines the appropriate +/// archiver (`ar`) and sets up additional compilation flags (both handled and unhandled). pub fn find_target(build: &Build, target: TargetSelection) { let mut cfg = new_cc_build(build, target); let config = build.config.target_config.get(&target); @@ -138,11 +139,12 @@ pub fn find_target(build: &Build, target: TargetSelection) { let ar = if let ar @ Some(..) = config.and_then(|c| c.ar.clone()) { ar } else { - cc2ar(compiler.path(), target) + cc2ar(compiler.path(), target, PathBuf::from(cfg.get_archiver().get_program())) }; build.cc.borrow_mut().insert(target, compiler.clone()); - let cflags = build.cflags(target, GitRepo::Rustc, CLang::C); + let mut cflags = build.cc_handled_clags(target, CLang::C); + cflags.extend(build.cc_unhandled_cflags(target, GitRepo::Rustc, CLang::C)); // If we use llvm-libunwind, we will need a C++ compiler as well for all targets // We'll need one anyways if the target triple is also a host triple @@ -168,7 +170,8 @@ pub fn find_target(build: &Build, target: TargetSelection) { build.verbose(|| println!("CC_{} = {:?}", target.triple, build.cc(target))); build.verbose(|| println!("CFLAGS_{} = {cflags:?}", target.triple)); if let Ok(cxx) = build.cxx(target) { - let cxxflags = build.cflags(target, GitRepo::Rustc, CLang::Cxx); + let mut cxxflags = build.cc_handled_clags(target, CLang::Cxx); + cxxflags.extend(build.cc_unhandled_cflags(target, GitRepo::Rustc, CLang::Cxx)); build.verbose(|| println!("CXX_{} = {cxx:?}", target.triple)); build.verbose(|| println!("CXXFLAGS_{} = {cxxflags:?}", target.triple)); } @@ -182,6 +185,8 @@ pub fn find_target(build: &Build, target: TargetSelection) { } } +/// Determines the default compiler for a given target and language when not explicitly +/// configured in `config.toml`. fn default_compiler( cfg: &mut cc::Build, compiler: Language, @@ -258,6 +263,12 @@ fn default_compiler( } } +/// Constructs the path to the Android NDK compiler for the given target triple and language. +/// +/// This helper function transform the target triple by converting certain architecture names +/// (for example, translating "arm" to "arm7a"), appends the minimum API level (hardcoded as "21" +/// for NDK r26d), and then constructs the full path based on the provided NDK directory and host +/// platform. pub(crate) fn ndk_compiler(compiler: Language, triple: &str, ndk: &Path) -> PathBuf { let mut triple_iter = triple.split('-'); let triple_translated = if let Some(arch) = triple_iter.next() { @@ -287,7 +298,11 @@ pub(crate) fn ndk_compiler(compiler: Language, triple: &str, ndk: &Path) -> Path ndk.join("toolchains").join("llvm").join("prebuilt").join(host_tag).join("bin").join(compiler) } -/// The target programming language for a native compiler. +/// Representing the target programming language for a native compiler. +/// +/// This enum is used to indicate whether a particular compiler is intended for C or C++. +/// It also provides helper methods for obtaining the standard executable names for GCC and +/// clang-based compilers. #[derive(PartialEq)] pub(crate) enum Language { /// The compiler is targeting C. @@ -297,7 +312,7 @@ pub(crate) enum Language { } impl Language { - /// Obtains the name of a compiler in the GCC collection. + /// Returns the executable name for a GCC compiler corresponding to this language. fn gcc(self) -> &'static str { match self { Language::C => "gcc", @@ -305,7 +320,7 @@ impl Language { } } - /// Obtains the name of a compiler in the clang suite. + /// Returns the executable name for a clang-based compiler corresponding to this language. fn clang(self) -> &'static str { match self { Language::C => "clang", @@ -313,3 +328,6 @@ impl Language { } } } + +#[cfg(test)] +mod tests; diff --git a/src/bootstrap/src/utils/cc_detect/tests.rs b/src/bootstrap/src/utils/cc_detect/tests.rs new file mode 100644 index 00000000000..006dfe7e5d7 --- /dev/null +++ b/src/bootstrap/src/utils/cc_detect/tests.rs @@ -0,0 +1,254 @@ +use std::path::{Path, PathBuf}; +use std::{env, iter}; + +use super::*; +use crate::core::config::{Target, TargetSelection}; +use crate::{Build, Config, Flags}; + +#[test] +fn test_cc2ar_env_specific() { + let triple = "x86_64-unknown-linux-gnu"; + let key = "AR_x86_64_unknown_linux_gnu"; + env::set_var(key, "custom-ar"); + let target = TargetSelection::from_user(triple); + let cc = Path::new("/usr/bin/clang"); + let default_ar = PathBuf::from("default-ar"); + let result = cc2ar(cc, target, default_ar); + env::remove_var(key); + assert_eq!(result, Some(PathBuf::from("custom-ar"))); +} + +#[test] +fn test_cc2ar_musl() { + let triple = "x86_64-unknown-linux-musl"; + env::remove_var("AR_x86_64_unknown_linux_musl"); + env::remove_var("AR"); + let target = TargetSelection::from_user(triple); + let cc = Path::new("/usr/bin/clang"); + let default_ar = PathBuf::from("default-ar"); + let result = cc2ar(cc, target, default_ar); + assert_eq!(result, Some(PathBuf::from("ar"))); +} + +#[test] +fn test_cc2ar_openbsd() { + let triple = "x86_64-unknown-openbsd"; + env::remove_var("AR_x86_64_unknown_openbsd"); + env::remove_var("AR"); + let target = TargetSelection::from_user(triple); + let cc = Path::new("/usr/bin/cc"); + let default_ar = PathBuf::from("default-ar"); + let result = cc2ar(cc, target, default_ar); + assert_eq!(result, Some(PathBuf::from("ar"))); +} + +#[test] +fn test_cc2ar_vxworks() { + let triple = "armv7-wrs-vxworks"; + env::remove_var("AR_armv7_wrs_vxworks"); + env::remove_var("AR"); + let target = TargetSelection::from_user(triple); + let cc = Path::new("/usr/bin/clang"); + let default_ar = PathBuf::from("default-ar"); + let result = cc2ar(cc, target, default_ar); + assert_eq!(result, Some(PathBuf::from("wr-ar"))); +} + +#[test] +fn test_cc2ar_nto_i586() { + let triple = "i586-unknown-nto-something"; + env::remove_var("AR_i586_unknown_nto_something"); + env::remove_var("AR"); + let target = TargetSelection::from_user(triple); + let cc = Path::new("/usr/bin/clang"); + let default_ar = PathBuf::from("default-ar"); + let result = cc2ar(cc, target, default_ar); + assert_eq!(result, Some(PathBuf::from("ntox86-ar"))); +} + +#[test] +fn test_cc2ar_nto_aarch64() { + let triple = "aarch64-unknown-nto-something"; + env::remove_var("AR_aarch64_unknown_nto_something"); + env::remove_var("AR"); + let target = TargetSelection::from_user(triple); + let cc = Path::new("/usr/bin/clang"); + let default_ar = PathBuf::from("default-ar"); + let result = cc2ar(cc, target, default_ar); + assert_eq!(result, Some(PathBuf::from("ntoaarch64-ar"))); +} + +#[test] +fn test_cc2ar_nto_x86_64() { + let triple = "x86_64-unknown-nto-something"; + env::remove_var("AR_x86_64_unknown_nto_something"); + env::remove_var("AR"); + let target = TargetSelection::from_user(triple); + let cc = Path::new("/usr/bin/clang"); + let default_ar = PathBuf::from("default-ar"); + let result = cc2ar(cc, target, default_ar); + assert_eq!(result, Some(PathBuf::from("ntox86_64-ar"))); +} + +#[test] +#[should_panic(expected = "Unknown architecture, cannot determine archiver for Neutrino QNX")] +fn test_cc2ar_nto_unknown() { + let triple = "powerpc-unknown-nto-something"; + env::remove_var("AR_powerpc_unknown_nto_something"); + env::remove_var("AR"); + let target = TargetSelection::from_user(triple); + let cc = Path::new("/usr/bin/clang"); + let default_ar = PathBuf::from("default-ar"); + let _ = cc2ar(cc, target, default_ar); +} + +#[test] +fn test_ndk_compiler_c() { + let ndk_path = PathBuf::from("/ndk"); + let target_triple = "arm-unknown-linux-android"; + let expected_triple_translated = "armv7a-unknown-linux-android"; + let expected_compiler = format!("{}21-{}", expected_triple_translated, Language::C.clang()); + let host_tag = if cfg!(target_os = "macos") { + "darwin-x86_64" + } else if cfg!(target_os = "windows") { + "windows-x86_64" + } else { + "linux-x86_64" + }; + let expected_path = ndk_path + .join("toolchains") + .join("llvm") + .join("prebuilt") + .join(host_tag) + .join("bin") + .join(&expected_compiler); + let result = ndk_compiler(Language::C, target_triple, &ndk_path); + assert_eq!(result, expected_path); +} + +#[test] +fn test_ndk_compiler_cpp() { + let ndk_path = PathBuf::from("/ndk"); + let target_triple = "arm-unknown-linux-android"; + let expected_triple_translated = "armv7a-unknown-linux-android"; + let expected_compiler = + format!("{}21-{}", expected_triple_translated, Language::CPlusPlus.clang()); + let host_tag = if cfg!(target_os = "macos") { + "darwin-x86_64" + } else if cfg!(target_os = "windows") { + "windows-x86_64" + } else { + "linux-x86_64" + }; + let expected_path = ndk_path + .join("toolchains") + .join("llvm") + .join("prebuilt") + .join(host_tag) + .join("bin") + .join(&expected_compiler); + let result = ndk_compiler(Language::CPlusPlus, target_triple, &ndk_path); + assert_eq!(result, expected_path); +} + +#[test] +fn test_language_gcc() { + assert_eq!(Language::C.gcc(), "gcc"); + assert_eq!(Language::CPlusPlus.gcc(), "g++"); +} + +#[test] +fn test_language_clang() { + assert_eq!(Language::C.clang(), "clang"); + assert_eq!(Language::CPlusPlus.clang(), "clang++"); +} + +#[test] +fn test_new_cc_build() { + let build = Build::new(Config { ..Config::parse(Flags::parse(&["check".to_owned()])) }); + let target = TargetSelection::from_user("x86_64-unknown-linux-gnu"); + let cfg = new_cc_build(&build, target.clone()); + let compiler = cfg.get_compiler(); + assert!(!compiler.path().to_str().unwrap().is_empty(), "Compiler path should not be empty"); +} + +#[test] +fn test_default_compiler_wasi() { + let build = Build::new(Config { ..Config::parse(Flags::parse(&["check".to_owned()])) }); + let target = TargetSelection::from_user("wasm32-wasi"); + let wasi_sdk = PathBuf::from("/wasi-sdk"); + env::set_var("WASI_SDK_PATH", &wasi_sdk); + let mut cfg = cc::Build::new(); + if let Some(result) = default_compiler(&mut cfg, Language::C, target.clone(), &build) { + let expected = { + let compiler = format!("{}-clang", target.triple); + wasi_sdk.join("bin").join(compiler) + }; + assert_eq!(result, expected); + } else { + panic!( + "default_compiler should return a compiler path for wasi target when WASI_SDK_PATH is set" + ); + } + env::remove_var("WASI_SDK_PATH"); +} + +#[test] +fn test_default_compiler_fallback() { + let build = Build::new(Config { ..Config::parse(Flags::parse(&["check".to_owned()])) }); + let target = TargetSelection::from_user("x86_64-unknown-linux-gnu"); + let mut cfg = cc::Build::new(); + let result = default_compiler(&mut cfg, Language::C, target, &build); + assert!(result.is_none(), "default_compiler should return None for generic targets"); +} + +#[test] +fn test_find_target_with_config() { + let mut build = Build::new(Config { ..Config::parse(Flags::parse(&["check".to_owned()])) }); + let target = TargetSelection::from_user("x86_64-unknown-linux-gnu"); + let mut target_config = Target::default(); + target_config.cc = Some(PathBuf::from("dummy-cc")); + target_config.cxx = Some(PathBuf::from("dummy-cxx")); + target_config.ar = Some(PathBuf::from("dummy-ar")); + target_config.ranlib = Some(PathBuf::from("dummy-ranlib")); + build.config.target_config.insert(target.clone(), target_config); + find_target(&build, target.clone()); + let binding = build.cc.borrow(); + let cc_tool = binding.get(&target).unwrap(); + assert_eq!(cc_tool.path(), &PathBuf::from("dummy-cc")); + let binding = build.cxx.borrow(); + let cxx_tool = binding.get(&target).unwrap(); + assert_eq!(cxx_tool.path(), &PathBuf::from("dummy-cxx")); + let binding = build.ar.borrow(); + let ar = binding.get(&target).unwrap(); + assert_eq!(ar, &PathBuf::from("dummy-ar")); + let binding = build.ranlib.borrow(); + let ranlib = binding.get(&target).unwrap(); + assert_eq!(ranlib, &PathBuf::from("dummy-ranlib")); +} + +#[test] +fn test_find_target_without_config() { + let mut build = Build::new(Config { ..Config::parse(Flags::parse(&["check".to_owned()])) }); + let target = TargetSelection::from_user("x86_64-unknown-linux-gnu"); + build.config.target_config.clear(); + find_target(&build, target.clone()); + assert!(build.cc.borrow().contains_key(&target)); + if !target.triple.contains("vxworks") { + assert!(build.cxx.borrow().contains_key(&target)); + } + assert!(build.ar.borrow().contains_key(&target)); +} + +#[test] +fn test_find() { + let mut build = Build::new(Config { ..Config::parse(Flags::parse(&["check".to_owned()])) }); + let target1 = TargetSelection::from_user("x86_64-unknown-linux-gnu"); + let target2 = TargetSelection::from_user("arm-linux-androideabi"); + build.targets.push(target1.clone()); + build.hosts.push(target2.clone()); + find(&build); + for t in build.hosts.iter().chain(build.targets.iter()).chain(iter::once(&build.build)) { + assert!(build.cc.borrow().contains_key(t), "CC not set for target {}", t.triple); + } +} diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs index 6f62df28e49..9b23cf1843e 100644 --- a/src/bootstrap/src/utils/change_tracker.rs +++ b/src/bootstrap/src/utils/change_tracker.rs @@ -345,4 +345,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ severity: ChangeSeverity::Info, summary: "Rustdoc now respects the value of rust.lto.", }, + ChangeInfo { + change_id: 136941, + severity: ChangeSeverity::Info, + summary: "The llvm.ccache option has moved to build.ccache. llvm.ccache is now deprecated.", + }, ]; diff --git a/src/bootstrap/src/utils/exec.rs b/src/bootstrap/src/utils/exec.rs index 1902dcd3962..7eb9ab96c8a 100644 --- a/src/bootstrap/src/utils/exec.rs +++ b/src/bootstrap/src/utils/exec.rs @@ -329,3 +329,25 @@ impl Default for CommandOutput { } } } + +/// Helper trait to format both Command and BootstrapCommand as a short execution line, +/// without all the other details (e.g. environment variables). +#[allow(unused)] +pub trait FormatShortCmd { + fn format_short_cmd(&self) -> String; +} + +impl FormatShortCmd for BootstrapCommand { + fn format_short_cmd(&self) -> String { + self.command.format_short_cmd() + } +} + +impl FormatShortCmd for Command { + fn format_short_cmd(&self) -> String { + let program = Path::new(self.get_program()); + let mut line = vec![program.file_name().unwrap().to_str().unwrap()]; + line.extend(self.get_args().map(|arg| arg.to_str().unwrap())); + line.join(" ") + } +} diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs index a1b1748c85b..3fee397da09 100644 --- a/src/bootstrap/src/utils/helpers.rs +++ b/src/bootstrap/src/utils/helpers.rs @@ -265,6 +265,9 @@ pub fn make(host: &str) -> PathBuf { #[track_caller] pub fn output(cmd: &mut Command) -> String { + #[cfg(feature = "tracing")] + let _run_span = crate::trace_cmd!(cmd); + let output = match cmd.stderr(Stdio::inherit()).output() { Ok(status) => status, Err(e) => fail(&format!("failed to execute command: {cmd:?}\nERROR: {e}")), diff --git a/src/bootstrap/src/utils/tracing.rs b/src/bootstrap/src/utils/tracing.rs index e89decf9e55..99849341dc3 100644 --- a/src/bootstrap/src/utils/tracing.rs +++ b/src/bootstrap/src/utils/tracing.rs @@ -47,3 +47,20 @@ macro_rules! error { ::tracing::error!($($tokens)*) } } + +#[macro_export] +macro_rules! trace_cmd { + ($cmd:expr) => { + { + use $crate::utils::exec::FormatShortCmd; + + ::tracing::span!( + target: "COMMAND", + ::tracing::Level::TRACE, + "executing command", + cmd = $cmd.format_short_cmd(), + full_cmd = ?$cmd + ).entered() + } + }; +} diff --git a/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile index 71eb72686b0..e3f23149284 100644 --- a/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile @@ -3,8 +3,8 @@ FROM ubuntu:22.04 COPY scripts/cross-apt-packages.sh /scripts/ RUN sh /scripts/cross-apt-packages.sh -COPY scripts/crosstool-ng-git.sh /scripts/ -RUN sh /scripts/crosstool-ng-git.sh +COPY scripts/crosstool-ng.sh /scripts/ +RUN sh /scripts/crosstool-ng.sh COPY scripts/rustbuild-setup.sh /scripts/ RUN sh /scripts/rustbuild-setup.sh diff --git a/src/ci/docker/host-x86_64/dist-loongarch64-musl/Dockerfile b/src/ci/docker/host-x86_64/dist-loongarch64-musl/Dockerfile index 5081f25e567..2c33b5526ee 100644 --- a/src/ci/docker/host-x86_64/dist-loongarch64-musl/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-loongarch64-musl/Dockerfile @@ -3,8 +3,8 @@ FROM ubuntu:22.04 COPY scripts/cross-apt-packages.sh /scripts/ RUN sh /scripts/cross-apt-packages.sh -COPY scripts/crosstool-ng-git.sh /scripts/ -RUN sh /scripts/crosstool-ng-git.sh +COPY scripts/crosstool-ng.sh /scripts/ +RUN sh /scripts/crosstool-ng.sh COPY scripts/rustbuild-setup.sh /scripts/ RUN sh /scripts/rustbuild-setup.sh diff --git a/src/ci/docker/host-x86_64/dist-powerpc64le-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-powerpc64le-linux/Dockerfile index 9d3be51d037..cb20f43cff7 100644 --- a/src/ci/docker/host-x86_64/dist-powerpc64le-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-powerpc64le-linux/Dockerfile @@ -3,8 +3,8 @@ FROM ubuntu:22.04 COPY scripts/cross-apt-packages.sh /scripts/ RUN sh /scripts/cross-apt-packages.sh -COPY scripts/crosstool-ng-git.sh /scripts/ -RUN sh /scripts/crosstool-ng-git.sh +COPY scripts/crosstool-ng.sh /scripts/ +RUN sh /scripts/crosstool-ng.sh COPY scripts/rustbuild-setup.sh /scripts/ RUN sh /scripts/rustbuild-setup.sh diff --git a/src/ci/docker/scripts/crosstool-ng-git.sh b/src/ci/docker/scripts/crosstool-ng-git.sh deleted file mode 100644 index e86810ae613..00000000000 --- a/src/ci/docker/scripts/crosstool-ng-git.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh -set -ex - -URL=https://github.com/crosstool-ng/crosstool-ng -REV=ed12fa68402f58e171a6f79500f73f4781fdc9e5 - -mkdir crosstool-ng -cd crosstool-ng -git init -git fetch --depth=1 ${URL} ${REV} -git reset --hard FETCH_HEAD -./bootstrap -./configure --prefix=/usr/local -make -j$(nproc) -make install -cd .. -rm -rf crosstool-ng diff --git a/src/ci/docker/scripts/crosstool-ng.sh b/src/ci/docker/scripts/crosstool-ng.sh index c3ee19b8d2c..eee912b0d75 100644 --- a/src/ci/docker/scripts/crosstool-ng.sh +++ b/src/ci/docker/scripts/crosstool-ng.sh @@ -1,7 +1,7 @@ #!/bin/sh set -ex -CT_NG=1.26.0 +CT_NG=1.27.0 url="https://github.com/crosstool-ng/crosstool-ng/archive/crosstool-ng-$CT_NG.tar.gz" curl -Lf $url | tar xzf - diff --git a/src/ci/docker/scripts/musl.sh b/src/ci/docker/scripts/musl.sh index ece8e6c15c0..9878bec6fbe 100644 --- a/src/ci/docker/scripts/musl.sh +++ b/src/ci/docker/scripts/musl.sh @@ -30,6 +30,47 @@ MUSL=musl-1.2.3 # may have been downloaded in a previous run if [ ! -d $MUSL ]; then curl https://www.musl-libc.org/releases/$MUSL.tar.gz | tar xzf - + + # Apply patches for CVE-2025-26519. At the time of adding these patches no release containing them + # has been published by the musl project, so we just apply them directly on top of the version we + # were distributing already. The patches should be removed once we upgrade to musl >= 1.2.6. + # + # Advisory: https://www.openwall.com/lists/musl/2025/02/13/1 + # + # Patches applied: + # - https://www.openwall.com/lists/musl/2025/02/13/1/1 + # - https://www.openwall.com/lists/musl/2025/02/13/1/2 + # + # ignore-tidy-tab + # ignore-tidy-linelength + patch -p1 -d $MUSL <<EOF +--- a/src/locale/iconv.c ++++ b/src/locale/iconv.c +@@ -502,7 +502,7 @@ size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restri + if (c >= 93 || d >= 94) { + c += (0xa1-0x81); + d += 0xa1; +- if (c >= 93 || c>=0xc6-0x81 && d>0x52) ++ if (c > 0xc6-0x81 || c==0xc6-0x81 && d>0x52) + goto ilseq; + if (d-'A'<26) d = d-'A'; + else if (d-'a'<26) d = d-'a'+26; +EOF + patch -p1 -d $MUSL <<EOF +--- a/src/locale/iconv.c ++++ b/src/locale/iconv.c +@@ -545,6 +545,10 @@ size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restri + if (*outb < k) goto toobig; + memcpy(*out, tmp, k); + } else k = wctomb_utf8(*out, c); ++ /* This failure condition should be unreachable, but ++ * is included to prevent decoder bugs from translating ++ * into advancement outside the output buffer range. */ ++ if (k>4) goto ilseq; + *out += k; + *outb -= k; + break; +EOF fi cd $MUSL diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index 341d82599fd..64e64867de2 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -12,15 +12,15 @@ runners: # Large runner used mainly for its bigger disk capacity - &job-linux-4c-largedisk - os: ubuntu-22.04-4core-16gb + os: ubuntu-24.04-4core-16gb <<: *base-job - &job-linux-8c - os: ubuntu-22.04-8core-32gb + os: ubuntu-24.04-8core-32gb <<: *base-job - &job-linux-16c - os: ubuntu-22.04-16core-64gb + os: ubuntu-24.04-16core-64gb <<: *base-job - &job-macos-xl @@ -50,7 +50,7 @@ runners: - &job-aarch64-linux # Free some disk space to avoid running out of space during the build. free_disk: true - os: ubuntu-22.04-arm + os: ubuntu-24.04-arm - &job-aarch64-linux-8c os: ubuntu-22.04-arm64-8core-32gb @@ -59,6 +59,7 @@ envs: SCRIPT: ./x.py --stage 2 test --skip tests/ui --skip tests/rustdoc -- --exact RUST_CONFIGURE_ARGS: --build=x86_64-apple-darwin --enable-sanitizers --enable-profiler --set rust.jemalloc RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 + # Ensure that host tooling is tested on our minimum supported macOS version. MACOSX_DEPLOYMENT_TARGET: 10.12 MACOSX_STD_DEPLOYMENT_TARGET: 10.12 SELECT_XCODE: /Applications/Xcode_15.2.app @@ -167,10 +168,10 @@ auto: <<: *job-linux-4c - name: dist-loongarch64-linux - <<: *job-linux-4c-largedisk + <<: *job-linux-4c - name: dist-loongarch64-musl - <<: *job-linux-4c-largedisk + <<: *job-linux-4c - name: dist-ohos <<: *job-linux-4c @@ -293,9 +294,7 @@ auto: <<: *job-linux-4c - name: x86_64-gnu-debug - # This seems to be needed because a full stage 2 build + run-make tests - # overwhelms the storage capacity of the standard 4c runner. - <<: *job-linux-4c-largedisk + <<: *job-linux-4c - name: x86_64-gnu-distcheck <<: *job-linux-8c @@ -370,7 +369,9 @@ auto: SCRIPT: ./x.py dist bootstrap --include-default-paths --host=x86_64-apple-darwin --target=x86_64-apple-darwin RUST_CONFIGURE_ARGS: --enable-full-tools --enable-sanitizers --enable-profiler --set rust.jemalloc --set rust.lto=thin --set rust.codegen-units=1 RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 + # Ensure that host tooling is built to support our minimum support macOS version. MACOSX_DEPLOYMENT_TARGET: 10.12 + MACOSX_STD_DEPLOYMENT_TARGET: 10.12 SELECT_XCODE: /Applications/Xcode_15.2.app NO_LLVM_ASSERTIONS: 1 NO_DEBUG_ASSERTIONS: 1 @@ -386,7 +387,10 @@ auto: # https://github.com/rust-lang/rust/issues/129069 RUST_CONFIGURE_ARGS: --enable-sanitizers --enable-profiler --set rust.jemalloc --set target.aarch64-apple-ios-macabi.sanitizers=false --set target.x86_64-apple-ios-macabi.sanitizers=false RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 + # Ensure that host tooling is built to support our minimum support macOS version. + # FIXME(madsmtm): This might be redundant, as we're not building host tooling here (?) MACOSX_DEPLOYMENT_TARGET: 10.12 + MACOSX_STD_DEPLOYMENT_TARGET: 10.12 SELECT_XCODE: /Applications/Xcode_15.2.app NO_LLVM_ASSERTIONS: 1 NO_DEBUG_ASSERTIONS: 1 @@ -404,7 +408,6 @@ auto: <<: *env-x86_64-apple-tests <<: *job-macos-xl - # This target only needs to support 11.0 and up as nothing else supports the hardware - name: dist-aarch64-apple env: SCRIPT: ./x.py dist bootstrap --include-default-paths --host=aarch64-apple-darwin --target=aarch64-apple-darwin @@ -419,6 +422,8 @@ auto: RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 SELECT_XCODE: /Applications/Xcode_15.4.app USE_XCODE_CLANG: 1 + # Aarch64 tooling only needs to support macOS 11.0 and up as nothing else + # supports the hardware. MACOSX_DEPLOYMENT_TARGET: 11.0 MACOSX_STD_DEPLOYMENT_TARGET: 11.0 NO_LLVM_ASSERTIONS: 1 @@ -428,7 +433,6 @@ auto: CODEGEN_BACKENDS: llvm,cranelift <<: *job-macos-m1 - # This target only needs to support 11.0 and up as nothing else supports the hardware - name: aarch64-apple env: SCRIPT: ./x.py --stage 2 test --host=aarch64-apple-darwin --target=aarch64-apple-darwin @@ -439,6 +443,8 @@ auto: RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 SELECT_XCODE: /Applications/Xcode_15.4.app USE_XCODE_CLANG: 1 + # Aarch64 tooling only needs to support macOS 11.0 and up as nothing else + # supports the hardware, so only need to test it there. MACOSX_DEPLOYMENT_TARGET: 11.0 MACOSX_STD_DEPLOYMENT_TARGET: 11.0 NO_LLVM_ASSERTIONS: 1 @@ -450,28 +456,29 @@ auto: # Windows Builders # ###################### + # x86_64-msvc is split into two jobs to run tests in parallel. - name: x86_64-msvc-1 env: - RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-profiler + RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-sanitizers --enable-profiler SCRIPT: make ci-msvc-py <<: *job-windows-25 - name: x86_64-msvc-2 env: - RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-profiler + RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-sanitizers --enable-profiler SCRIPT: make ci-msvc-ps1 <<: *job-windows-25 # i686-msvc is split into two jobs to run tests in parallel. - name: i686-msvc-1 env: - RUST_CONFIGURE_ARGS: --build=i686-pc-windows-msvc + RUST_CONFIGURE_ARGS: --build=i686-pc-windows-msvc --enable-sanitizers SCRIPT: make ci-msvc-py <<: *job-windows - name: i686-msvc-2 env: - RUST_CONFIGURE_ARGS: --build=i686-pc-windows-msvc + RUST_CONFIGURE_ARGS: --build=i686-pc-windows-msvc --enable-sanitizers SCRIPT: make ci-msvc-ps1 <<: *job-windows @@ -521,13 +528,30 @@ auto: # came from the mingw-w64 SourceForge download site. Unfortunately # SourceForge is notoriously flaky, so we mirror it on our own infrastructure. - - name: i686-mingw + # i686-mingw is split into three jobs to run tests in parallel. + - name: i686-mingw-1 env: RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu - SCRIPT: make ci-mingw + SCRIPT: make ci-mingw-x-1 # There is no dist-i686-mingw-alt, so there is no prebuilt LLVM with assertions NO_DOWNLOAD_CI_LLVM: 1 - <<: *job-windows-25-8c + <<: *job-windows-25 + + - name: i686-mingw-2 + env: + RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu + SCRIPT: make ci-mingw-x-2 + # There is no dist-i686-mingw-alt, so there is no prebuilt LLVM with assertions + NO_DOWNLOAD_CI_LLVM: 1 + <<: *job-windows-25 + + - name: i686-mingw-3 + env: + RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu + SCRIPT: make ci-mingw-bootstrap + # There is no dist-i686-mingw-alt, so there is no prebuilt LLVM with assertions + NO_DOWNLOAD_CI_LLVM: 1 + <<: *job-windows-25 # x86_64-mingw is split into two jobs to run tests in parallel. - name: x86_64-mingw-1 diff --git a/src/ci/scripts/free-disk-space.sh b/src/ci/scripts/free-disk-space.sh index 8850e168145..055a6ac2211 100755 --- a/src/ci/scripts/free-disk-space.sh +++ b/src/ci/scripts/free-disk-space.sh @@ -69,31 +69,71 @@ printDF() { printSeparationLine "=" } -removeDir() { - dir=${1} - - local before - if [ ! -d "$dir" ]; then - echo "::warning::Directory $dir does not exist, skipping." - else - before=$(getAvailableSpace) - sudo rm -rf "$dir" - printSavedSpace "$before" "Removed $dir" - fi -} - -removeUnusedDirectories() { - local dirs_to_remove=( +removeUnusedFilesAndDirs() { + local to_remove=( + "/usr/local/aws-sam-cli" + "/usr/local/doc/cmake" + "/usr/local/julia"* "/usr/local/lib/android" - "/usr/share/dotnet" + "/usr/local/share/chromedriver-"* + "/usr/local/share/chromium" + "/usr/local/share/cmake-"* + "/usr/local/share/edge_driver" + "/usr/local/share/gecko_driver" + "/usr/local/share/icons" + "/usr/local/share/vim" + "/usr/local/share/emacs" + "/usr/local/share/powershell" + "/usr/local/share/vcpkg" + "/usr/share/apache-maven-"* + "/usr/share/gradle-"* + "/usr/share/java" + "/usr/share/kotlinc" + "/usr/share/miniconda" + "/usr/share/php" + "/usr/share/ri" + "/usr/share/swift" + + # binaries + "/usr/local/bin/azcopy" + "/usr/local/bin/bicep" + "/usr/local/bin/ccmake" + "/usr/local/bin/cmake-"* + "/usr/local/bin/cmake" + "/usr/local/bin/cpack" + "/usr/local/bin/ctest" + "/usr/local/bin/helm" + "/usr/local/bin/kind" + "/usr/local/bin/kustomize" + "/usr/local/bin/minikube" + "/usr/local/bin/packer" + "/usr/local/bin/phpunit" + "/usr/local/bin/pulumi-"* + "/usr/local/bin/pulumi" + "/usr/local/bin/stack" # Haskell runtime "/usr/local/.ghcup" + + # Azure + "/opt/az" + "/usr/share/az_"* + + # Environment variable set by GitHub Actions + "$AGENT_TOOLSDIRECTORY" ) - for dir in "${dirs_to_remove[@]}"; do - removeDir "$dir" + for element in "${to_remove[@]}"; do + if [ ! -e "$element" ]; then + # The file or directory doesn't exist. + # Maybe it was removed in a newer version of the runner or it's not present in a + # specific architecture (e.g. ARM). + echo "::warning::Directory or file $element does not exist, skipping." + fi done + + # Remove all files and directories at once to save time. + sudo rm -rf "${to_remove[@]}" } execAndMeasureSpaceChange() { @@ -115,7 +155,6 @@ cleanPackages() { '^dotnet-.*' '^llvm-.*' '^mongodb-.*' - '^mysql-.*' 'azure-cli' 'firefox' 'libgl1-mesa-dri' @@ -138,7 +177,9 @@ cleanPackages() { sudo apt-get clean || echo "::warning::The command [sudo apt-get clean] failed failed" } -# Remove Docker images +# Remove Docker images. +# Ubuntu 22 runners have docker images already installed. +# They aren't present in ubuntu 24 runners. cleanDocker() { echo "=> Removing the following docker images:" sudo docker image ls @@ -163,8 +204,7 @@ echo "" execAndMeasureSpaceChange cleanPackages "Unused packages" execAndMeasureSpaceChange cleanDocker "Docker images" execAndMeasureSpaceChange cleanSwap "Swap storage" - -removeUnusedDirectories +execAndMeasureSpaceChange removeUnusedFilesAndDirs "Unused files and directories" # Output saved space statistic echo "" diff --git a/src/ci/scripts/upload-artifacts.sh b/src/ci/scripts/upload-artifacts.sh index 0bc91f6ba71..975b4c52726 100755 --- a/src/ci/scripts/upload-artifacts.sh +++ b/src/ci/scripts/upload-artifacts.sh @@ -52,10 +52,15 @@ access_url="https://ci-artifacts.rust-lang.org/${deploy_dir}/$(ciCommit)" # to make them easily accessible. if [ -n "${GITHUB_STEP_SUMMARY}" ] then - echo "# CI artifacts" >> "${GITHUB_STEP_SUMMARY}" + archives=($(find "${upload_dir}" -maxdepth 1 -name "*.xz")) - for filename in "${upload_dir}"/*.xz; do - filename=$(basename "${filename}") - echo "- [${filename}](${access_url}/${filename})" >> "${GITHUB_STEP_SUMMARY}" - done + # Avoid generating an invalid "*.xz" file if there are no archives + if [ ${#archives[@]} -gt 0 ]; then + echo "# CI artifacts" >> "${GITHUB_STEP_SUMMARY}" + + for filename in "${upload_dir}"/*.xz; do + filename=$(basename "${filename}") + echo "- [${filename}](${access_url}/${filename})" >> "${GITHUB_STEP_SUMMARY}" + done + fi fi diff --git a/src/doc/book b/src/doc/book -Subproject e2fa4316c5a7c0d2499c5d6b799adcfad6ef7a4 +Subproject d4d2c18cbd20876b2130a546e790446a8444cb3 diff --git a/src/doc/edition-guide b/src/doc/edition-guide -Subproject f56aecc3b036dff16404b525a83b00f911b9bbe +Subproject 8dbdda7cae4fa030f09f8f5b63994d4d1dde74b diff --git a/src/doc/embedded-book b/src/doc/embedded-book -Subproject ddbf1b4e2858fedb71b7c42eb15c4576517dc12 +Subproject 0b8219ac23a3e09464e4e0166c768cf1c4bba0d diff --git a/src/doc/reference b/src/doc/reference -Subproject 4249fb411dd27f945e2881eb0378044b94cee06 +Subproject 6195dbd70fc6f0980c314b4d23875ac570d8253 diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example -Subproject 743766929f1e53e72fab74394ae259bbfb4a761 +Subproject 66543bbc5b7dbd4e679092c07ae06ba6c73fd91 diff --git a/src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml b/src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml index 615927d55e5..dc5395a19dd 100644 --- a/src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml +++ b/src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml @@ -3,8 +3,8 @@ name: rustc-pull on: workflow_dispatch: schedule: - # Run at 04:00 UTC every Monday - - cron: '0 4 * * 1' + # Run at 04:00 UTC every Monday and Thursday + - cron: '0 4 * * 1,4' jobs: pull: @@ -34,8 +34,25 @@ jobs: git config --global user.name 'The rustc-dev-guide Cronjob Bot' git config --global user.email 'github-actions@github.com' - name: Perform rustc-pull - run: cargo run --manifest-path josh-sync/Cargo.toml -- rustc-pull + id: rustc-pull + # Turn off -e to disable early exit + shell: bash {0} + run: | + cargo run --manifest-path josh-sync/Cargo.toml -- rustc-pull + exitcode=$? + + # If no pull was performed, we want to mark this job as successful, + # but we do not want to perform the follow-up steps. + if [ $exitcode -eq 0 ]; then + echo "pull_result=pull-finished" >> $GITHUB_OUTPUT + elif [ $exitcode -eq 2 ]; then + echo "pull_result=skipped" >> $GITHUB_OUTPUT + exitcode=0 + fi + + exit ${exitcode} - name: Push changes to a branch + if: ${{ steps.rustc-pull.outputs.pull_result == 'pull-finished' }} run: | # Update a sticky branch that is used only for rustc pulls BRANCH="rustc-pull" @@ -43,6 +60,9 @@ jobs: git push -u origin $BRANCH --force - name: Create pull request id: update-pr + if: ${{ steps.rustc-pull.outputs.pull_result == 'pull-finished' }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | # Check if an open pull request for an rustc pull update already exists # If it does, the previous push has just updated it @@ -54,26 +74,35 @@ jobs: echo "pr_url=$PR_URL" >> $GITHUB_OUTPUT else PR_URL=`gh pr list --author github-actions[bot] --state open -q 'map(select(.title=="Rustc pull update")) | .[0].url' --json url,title` + echo "Updating pull request ${PR_URL}" echo "pr_url=$PR_URL" >> $GITHUB_OUTPUT fi - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} send-zulip-message: needs: [pull] if: ${{ !cancelled() }} runs-on: ubuntu-latest steps: + - uses: actions/checkout@v4 - name: Compute message - id: message + id: create-message + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - if [ "${{ needs.pull.result }}" == "failure" ]; - then + if [ "${{ needs.pull.result }}" == "failure" ]; then WORKFLOW_URL="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" echo "message=Rustc pull sync failed. Check out the [workflow URL]($WORKFLOW_URL)." >> $GITHUB_OUTPUT else - echo "message=Rustc pull sync succeeded. Check out the [PR](${{ needs.pull.outputs.pr_url }})." >> $GITHUB_OUTPUT + CREATED_AT=`gh pr list --author github-actions[bot] --state open -q 'map(select(.title=="Rustc pull update")) | .[0].createdAt' --json createdAt,title` + PR_URL=`gh pr list --author github-actions[bot] --state open -q 'map(select(.title=="Rustc pull update")) | .[0].url' --json url,title` + week_ago=$(date +%F -d '7 days ago') + + # If there is an open PR that is at least a week old, post a message about it + if [[ -n $DATE_GH && $DATE_GH < $week_ago ]]; then + echo "message=A PR with a Rustc pull has been opened for more a week. Check out the [PR](${PR_URL})." >> $GITHUB_OUTPUT + fi fi - name: Send a Zulip message about updated PR + if: ${{ steps.create-message.outputs.message != '' }} uses: zulip/github-actions-zulip/send-message@e4c8f27c732ba9bd98ac6be0583096dea82feea5 with: api-key: ${{ secrets.ZULIP_API_TOKEN }} diff --git a/src/doc/rustc-dev-guide/examples/rustc-driver-interacting-with-the-ast.rs b/src/doc/rustc-dev-guide/examples/rustc-driver-interacting-with-the-ast.rs index 9fcb16b0fca..dc63e1aa511 100644 --- a/src/doc/rustc-dev-guide/examples/rustc-driver-interacting-with-the-ast.rs +++ b/src/doc/rustc-dev-guide/examples/rustc-driver-interacting-with-the-ast.rs @@ -75,7 +75,7 @@ impl rustc_driver::Callbacks for MyCallbacks { let item = hir_krate.item(id); // Use pattern-matching to find a specific node inside the main function. if let rustc_hir::ItemKind::Fn(_, _, body_id) = item.kind { - let expr = &tcx.hir().body(body_id).value; + let expr = &tcx.hir_body(body_id).value; if let rustc_hir::ExprKind::Block(block, _) = expr.kind { if let rustc_hir::StmtKind::Let(let_stmt) = block.stmts[0].kind { if let Some(expr) = let_stmt.init { diff --git a/src/doc/rustc-dev-guide/josh-sync/src/main.rs b/src/doc/rustc-dev-guide/josh-sync/src/main.rs index 84613ad8689..175f016f739 100644 --- a/src/doc/rustc-dev-guide/josh-sync/src/main.rs +++ b/src/doc/rustc-dev-guide/josh-sync/src/main.rs @@ -1,5 +1,5 @@ use clap::Parser; -use crate::sync::GitSync; +use crate::sync::{GitSync, RustcPullError}; mod sync; @@ -22,7 +22,18 @@ fn main() -> anyhow::Result<()> { let sync = GitSync::from_current_dir()?; match args { Args::RustcPull => { - sync.rustc_pull(None)?; + if let Err(error) = sync.rustc_pull(None) { + match error { + RustcPullError::NothingToPull => { + eprintln!("Nothing to pull"); + std::process::exit(2); + } + RustcPullError::PullFailed(error) => { + eprintln!("Pull failure: {error:?}"); + std::process::exit(1); + } + } + } } Args::RustcPush { github_username, branch } => { sync.rustc_push(github_username, branch)?; diff --git a/src/doc/rustc-dev-guide/josh-sync/src/sync.rs b/src/doc/rustc-dev-guide/josh-sync/src/sync.rs index eff80b1091d..cd64be63670 100644 --- a/src/doc/rustc-dev-guide/josh-sync/src/sync.rs +++ b/src/doc/rustc-dev-guide/josh-sync/src/sync.rs @@ -11,6 +11,19 @@ const JOSH_FILTER: &str = ":/src/doc/rustc-dev-guide"; const JOSH_PORT: u16 = 42042; const UPSTREAM_REPO: &str = "rust-lang/rust"; +pub enum RustcPullError { + /// No changes are available to be pulled. + NothingToPull, + /// A rustc-pull has failed, probably a git operation error has occurred. + PullFailed(anyhow::Error) +} + +impl<E> From<E> for RustcPullError where E: Into<anyhow::Error> { + fn from(error: E) -> Self { + Self::PullFailed(error.into()) + } +} + pub struct GitSync { dir: PathBuf, } @@ -24,7 +37,7 @@ impl GitSync { }) } - pub fn rustc_pull(&self, commit: Option<String>) -> anyhow::Result<()> { + pub fn rustc_pull(&self, commit: Option<String>) -> Result<(), RustcPullError> { let sh = Shell::new()?; sh.change_dir(&self.dir); let commit = commit.map(Ok).unwrap_or_else(|| { @@ -38,7 +51,7 @@ impl GitSync { })?; // Make sure the repo is clean. if cmd!(sh, "git status --untracked-files=no --porcelain").read()?.is_empty().not() { - bail!("working directory must be clean before performing rustc pull"); + return Err(anyhow::anyhow!("working directory must be clean before performing rustc pull").into()); } // Make sure josh is running. let josh = Self::start_josh()?; @@ -47,7 +60,7 @@ impl GitSync { let previous_base_commit = sh.read_file("rust-version")?.trim().to_string(); if previous_base_commit == commit { - return Err(anyhow::anyhow!("No changes since last pull")); + return Err(RustcPullError::NothingToPull); } // Update rust-version file. As a separate commit, since making it part of @@ -94,12 +107,13 @@ impl GitSync { cmd!(sh, "git reset --hard HEAD^") .run() .expect("FAILED to clean up after creating the preparation commit"); - return Err(anyhow::anyhow!("No merge was performed, nothing to pull. Rolled back the preparation commit.")); + eprintln!("No merge was performed, no changes to pull were found. Rolled back the preparation commit."); + return Err(RustcPullError::NothingToPull); } // Check that the number of roots did not increase. if num_roots()? != num_roots_before { - bail!("Josh created a new root commit. This is probably not the history you want."); + return Err(anyhow::anyhow!("Josh created a new root commit. This is probably not the history you want.").into()); } drop(josh); diff --git a/src/doc/rustc-dev-guide/rust-version b/src/doc/rustc-dev-guide/rust-version index 183d26b2938..78e9ecdf174 100644 --- a/src/doc/rustc-dev-guide/rust-version +++ b/src/doc/rustc-dev-guide/rust-version @@ -1 +1 @@ -66d6064f9eb888018775e08f84747ee6f39ba28e +124cc92199ffa924f6b4c7cc819a85b65e0c3984 diff --git a/src/doc/rustc-dev-guide/src/appendix/bibliography.md b/src/doc/rustc-dev-guide/src/appendix/bibliography.md index 8f6810cbcae..93426b645a6 100644 --- a/src/doc/rustc-dev-guide/src/appendix/bibliography.md +++ b/src/doc/rustc-dev-guide/src/appendix/bibliography.md @@ -82,7 +82,7 @@ Rust, as well as publications about Rust. * [Ownership is Theft: Experiences Building an Embedded OS in Rust - Amit Levy, et. al.](https://amitlevy.com/papers/tock-plos2015.pdf) * [You can't spell trust without Rust](https://faultlore.com/blah/papers/thesis.pdf). Aria Beingessner's master's thesis. * [Rust-Bio: a fast and safe bioinformatics library](https://rust-bio.github.io/). Johannes Köster -* [Safe, Correct, and Fast Low-Level Networking](https://octarineparrot.com/assets/msci_paper.pdf). Robert Clipsham's master's thesis. +* [Safe, Correct, and Fast Low-Level Networking](https://csperkins.org/research/thesis-msci-clipsham.pdf). Robert Clipsham's master's thesis. * [Formalizing Rust traits](https://open.library.ubc.ca/cIRcle/collections/ubctheses/24/items/1.0220521). Jonatan Milewski's master's thesis. * [Rust as a Language for High Performance GC Implementation](https://dl.acm.org/doi/pdf/10.1145/3241624.2926707) * [Simple Verification of Rust Programs via Functional Purification](https://github.com/Kha/electrolysis). Sebastian Ullrich's master's thesis. diff --git a/src/doc/rustc-dev-guide/src/building/bootstrapping/debugging-bootstrap.md b/src/doc/rustc-dev-guide/src/building/bootstrapping/debugging-bootstrap.md index 3f907e85dd6..04d8e91dcb4 100644 --- a/src/doc/rustc-dev-guide/src/building/bootstrapping/debugging-bootstrap.md +++ b/src/doc/rustc-dev-guide/src/building/bootstrapping/debugging-bootstrap.md @@ -76,6 +76,14 @@ $ BOOTSTRAP_TRACING=CONFIG_HANDLING=TRACE ./x build library --stage 1 [tracing-env-filter]: https://docs.rs/tracing-subscriber/0.3.19/tracing_subscriber/filter/struct.EnvFilter.html +##### FIXME(#96176): specific tracing for `compiler()` vs `compiler_for()` + +The additional targets `COMPILER` and `COMPILER_FOR` are used to help trace what +`builder.compiler()` and `builder.compiler_for()` does. They should be removed +if [#96176][cleanup-compiler-for] is resolved. + +[cleanup-compiler-for]: https://github.com/rust-lang/rust/issues/96176 + ### Using `tracing` in bootstrap Both `tracing::*` macros and the `tracing::instrument` proc-macro attribute need to be gated behind `tracing` feature. Examples: @@ -121,6 +129,14 @@ For `#[instrument]`, it's recommended to: - Explicitly pick an instrumentation name via `name = ".."` to distinguish between e.g. `run` of different steps. - Take care to not cause diverging behavior via tracing, e.g. building extra things only when tracing infra is enabled. +### Profiling bootstrap + +You can use the `COMMAND` tracing target to trace execution of most commands spawned by bootstrap. If you also use the `BOOTSTRAP_PROFILE=1` environment variable, bootstrap will generate a Chrome JSON trace file, which can be visualized in Chrome's `chrome://tracing` page or on https://ui.perfetto.dev. + +```bash +$ BOOTSTRAP_TRACING=COMMAND=trace BOOTSTRAP_PROFILE=1 ./x build library +``` + ### rust-analyzer integration? Unfortunately, because bootstrap is a `rust-analyzer.linkedProjects`, you can't ask r-a to check/build bootstrap itself with `tracing` feature enabled to get relevant completions, due to lack of support as described in <https://github.com/rust-lang/rust-analyzer/issues/8521>. diff --git a/src/doc/rustc-dev-guide/src/building/suggested.md b/src/doc/rustc-dev-guide/src/building/suggested.md index bf5ffbc00af..2c6c3fe1df8 100644 --- a/src/doc/rustc-dev-guide/src/building/suggested.md +++ b/src/doc/rustc-dev-guide/src/building/suggested.md @@ -135,24 +135,24 @@ and follow the same instructions as above. ### Emacs Emacs provides support for rust-analyzer with project-local configuration -through [Eglot](https://www.gnu.org/software/emacs/manual/html_node/eglot/). +through [Eglot](https://www.gnu.org/software/emacs/manual/html_node/eglot/). Steps for setting up Eglot with rust-analyzer can be [found -here](https://rust-analyzer.github.io/manual.html#eglot). +here](https://rust-analyzer.github.io/manual.html#eglot). Having set up Emacs & Eglot for Rust development in general, you can run `./x setup editor` and select `emacs`, which will prompt you to create `.dir-locals.el` with the recommended configuration for Eglot. -The recommended settings live at [`src/etc/rust_analyzer_eglot.el`]. +The recommended settings live at [`src/etc/rust_analyzer_eglot.el`]. For more information on project-specific Eglot configuration, consult [the manual](https://www.gnu.org/software/emacs/manual/html_node/eglot/Project_002dspecific-configuration.html). ### Helix -Helix comes with built-in LSP and rust-analyzer support. +Helix comes with built-in LSP and rust-analyzer support. It can be configured through `languages.toml`, as described -[here](https://docs.helix-editor.com/languages.html). +[here](https://docs.helix-editor.com/languages.html). You can run `./x setup editor` and select `helix`, which will prompt you to create `languages.toml` with the recommended configuration for Helix. The -recommended settings live at [`src/etc/rust_analyzer_helix.toml`]. +recommended settings live at [`src/etc/rust_analyzer_helix.toml`]. ## Check, check, and check again @@ -181,7 +181,7 @@ example, running `tidy` and `linkchecker` is useful when editing Markdown files, whereas UI tests are much less likely to be helpful. While `x suggest` is a useful tool, it does not guarantee perfect coverage (just as PR CI isn't a substitute for bors). See the [dedicated chapter](../tests/suggest-tests.md) for -more information and contribution instructions. +more information and contribution instructions. Please note that `x suggest` is in a beta state currently and the tests that it will suggest are limited. @@ -332,29 +332,22 @@ git worktree add -b my-feature ../rust2 master You can then use that rust2 folder as a separate workspace for modifying and building `rustc`! -## Using nix-shell +## Working with nix -If you're using nix, you can use the following nix-shell to work on Rust: +Several nix configurations are defined in `src/tools/nix-dev-shell`. -```nix -{ pkgs ? import <nixpkgs> {} }: -pkgs.mkShell { - name = "rustc"; - nativeBuildInputs = with pkgs; [ - binutils cmake ninja pkg-config python3 git curl cacert patchelf nix - ]; - buildInputs = with pkgs; [ - openssl glibc.out glibc.static - ]; - # Avoid creating text files for ICEs. - RUSTC_ICE = "0"; - # Provide `libstdc++.so.6` for the self-contained lld. - LD_LIBRARY_PATH = "${with pkgs; lib.makeLibraryPath [ - stdenv.cc.cc.lib - ]}"; -} +If you're using direnv, you can create a symbol link to `src/tools/nix-dev-shell/envrc-flake` or `src/tools/nix-dev-shell/envrc-shell` + +```bash +ln -s ./src/tools/nix-dev-shell/envrc-flake ./.envrc # Use flake +``` +or +```bash +ln -s ./src/tools/nix-dev-shell/envrc-shell ./.envrc # Use nix-shell ``` +### Note + Note that when using nix on a not-NixOS distribution, it may be necessary to set **`patch-binaries-for-nix = true` in `config.toml`**. Bootstrap tries to detect whether it's running in nix and enable patching automatically, but this diff --git a/src/doc/rustc-dev-guide/src/diagnostics.md b/src/doc/rustc-dev-guide/src/diagnostics.md index 8f389640d27..972309b5cd3 100644 --- a/src/doc/rustc-dev-guide/src/diagnostics.md +++ b/src/doc/rustc-dev-guide/src/diagnostics.md @@ -601,8 +601,8 @@ The trait implementation allows you to check certain syntactic constructs as the linter walks the AST. You can then choose to emit lints in a very similar way to compile errors. -You also declare the metadata of a particular lint via the `declare_lint!` -macro. [This macro](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint_defs/macro.declare_lint.html) includes the name, the default level, a short description, and some +You also declare the metadata of a particular lint via the [`declare_lint!`] +macro. This macro includes the name, the default level, a short description, and some more details. Note that the lint and the lint pass must be registered with the compiler. @@ -671,6 +671,8 @@ example-use-loop = denote infinite loops with `loop {"{"} ... {"}"}` .suggestion = use `loop` ``` +[`declare_lint!`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint_defs/macro.declare_lint.html + ### Edition-gated lints Sometimes we want to change the behavior of a lint in a new edition. To do this, diff --git a/src/doc/rustc-dev-guide/src/getting-started.md b/src/doc/rustc-dev-guide/src/getting-started.md index 4cb1d0b31eb..8bf14bef2a0 100644 --- a/src/doc/rustc-dev-guide/src/getting-started.md +++ b/src/doc/rustc-dev-guide/src/getting-started.md @@ -101,7 +101,6 @@ it's easy to pick up work without a large time commitment: - [Rustdoc Askama Migration](https://github.com/rust-lang/rust/issues/108868) - [Diagnostic Translation](https://github.com/rust-lang/rust/issues/100717) - [Move UI tests to subdirectories](https://github.com/rust-lang/rust/issues/73494) -- [Port run-make tests from Make to Rust](https://github.com/rust-lang/rust/issues/121876) If you find more recurring work, please feel free to add it here! diff --git a/src/doc/rustc-dev-guide/src/implementing_new_features.md b/src/doc/rustc-dev-guide/src/implementing_new_features.md index d87afeaedce..5b67ccd7f4c 100644 --- a/src/doc/rustc-dev-guide/src/implementing_new_features.md +++ b/src/doc/rustc-dev-guide/src/implementing_new_features.md @@ -9,7 +9,11 @@ smoothly. **NOTE: this section is for *language* features, not *library* features, which use [a different process].** +See also [the Rust Language Design Team's procedures][lang-propose] for +proposing changes to the language. + [a different process]: ./stability.md +[lang-propose]: https://lang-team.rust-lang.org/how_to/propose.html ## The @rfcbot FCP process diff --git a/src/doc/rustc-dev-guide/src/mir/index.md b/src/doc/rustc-dev-guide/src/mir/index.md index 778c583919b..f355875aa15 100644 --- a/src/doc/rustc-dev-guide/src/mir/index.md +++ b/src/doc/rustc-dev-guide/src/mir/index.md @@ -304,9 +304,9 @@ The most important rule for this representation is that every value must be uniquely represented. In other words: a specific value must only be representable in one specific way. For example: there is only one way to represent an array of two integers as a `ValTree`: -`ValTree::Branch(&[ValTree::Leaf(first_int), ValTree::Leaf(second_int)])`. +`Branch([Leaf(first_int), Leaf(second_int)])`. Even though theoretically a `[u32; 2]` could be encoded in a `u64` and thus just be a -`ValTree::Leaf(bits_of_two_u32)`, that is not a legal construction of `ValTree` +`Leaf(bits_of_two_u32)`, that is not a legal construction of `ValTree` (and is very complex to do, so it is unlikely anyone is tempted to do so). These rules also mean that some values are not representable. There can be no `union`s in type diff --git a/src/doc/rustc-dev-guide/src/parallel-rustc.md b/src/doc/rustc-dev-guide/src/parallel-rustc.md index 44c78a125f4..c5b70706a81 100644 --- a/src/doc/rustc-dev-guide/src/parallel-rustc.md +++ b/src/doc/rustc-dev-guide/src/parallel-rustc.md @@ -46,8 +46,6 @@ are implemented differently depending on whether `parallel-compiler` is true. | data structure | parallel | non-parallel | | -------------------------------- | --------------------------------------------------- | ------------ | -| Weak | std::sync::Weak | std::rc::Weak | -| Atomic{Bool}/{Usize}/{U32}/{U64} | std::sync::atomic::Atomic{Bool}/{Usize}/{U32}/{U64} | (std::cell::Cell<bool/usize/u32/u64>) | | OnceCell | std::sync::OnceLock | std::cell::OnceCell | | Lock\<T> | (parking_lot::Mutex\<T>) | (std::cell::RefCell) | | RwLock\<T> | (parking_lot::RwLock\<T>) | (std::cell::RefCell) | @@ -58,7 +56,6 @@ are implemented differently depending on whether `parallel-compiler` is true. | WriteGuard | parking_lot::RwLockWriteGuard | std::cell::RefMut | | MappedWriteGuard | parking_lot::MappedRwLockWriteGuard | std::cell::RefMut | | LockGuard | parking_lot::MutexGuard | std::cell::RefMut | -| MappedLockGuard | parking_lot::MappedMutexGuard | std::cell::RefMut | - These thread-safe data structures are interspersed during compilation which can cause lock contention resulting in degraded performance as the number of @@ -173,12 +170,10 @@ Here are some resources that can be used to learn more: - [This list of interior mutability in the compiler by nikomatsakis][imlist] [`rayon`]: https://crates.io/crates/rayon -[Arc]: https://doc.rust-lang.org/std/sync/struct.Arc.html [imlist]: https://github.com/nikomatsakis/rustc-parallelization/blob/master/interior-mutability-list.md [irlo0]: https://internals.rust-lang.org/t/parallelizing-rustc-using-rayon/6606 [irlo1]: https://internals.rust-lang.org/t/help-test-parallel-rustc/11503 [monomorphization]: backend/monomorph.md [parallel-rustdoc]: https://github.com/rust-lang/rust/issues/82741 -[Rc]: https://doc.rust-lang.org/std/rc/struct.Rc.html [rustc-rayon]: https://github.com/rust-lang/rustc-rayon [tracking]: https://github.com/rust-lang/rust/issues/48685 diff --git a/src/doc/rustc-dev-guide/src/param_env/param_env_acquisition.md b/src/doc/rustc-dev-guide/src/param_env/param_env_acquisition.md index 391e562910f..f6cff2d6c63 100644 --- a/src/doc/rustc-dev-guide/src/param_env/param_env_acquisition.md +++ b/src/doc/rustc-dev-guide/src/param_env/param_env_acquisition.md @@ -21,7 +21,7 @@ Creating an env from an arbitrary set of where clauses is usually unnecessary an Creating an empty environment via `ParamEnv::empty` is almost always wrong. There are very few places where we actually know that the environment should be empty. One of the only places where we do actually know this is after monomorphization, however the `ParamEnv` there should be constructed via `ParamEnv::reveal_all` instead as at this point we should be able to determine the hidden type of opaque types. Codegen/Post-mono is one of the only places that should be using `ParamEnv::reveal_all`. -An additional piece of complexity here is specifying the [`Reveal`][reveal] (see linked docs for explanation of what reveal does) used for the `ParamEnv`. When constructing a param env using the `param_env` query it will have `Reveal::UserFacing`, if `Reveal::All` is desired then the [`tcx.param_env_reveal_all_normalized`][env_reveal_all_normalized] query can be used instead. +An additional piece of complexity here is specifying the `Reveal` (see linked docs for explanation of what reveal does) used for the `ParamEnv`. When constructing a param env using the `param_env` query it will have `Reveal::UserFacing`, if `Reveal::All` is desired then the [`tcx.param_env_reveal_all_normalized`][env_reveal_all_normalized] query can be used instead. The `ParamEnv` type has a method [`ParamEnv::with_reveal_all_normalized`][with_reveal_all] which converts an existing `ParamEnv` into one with `Reveal::All` specified. Where possible the previously mentioned query should be preferred as it is more efficient. @@ -38,7 +38,6 @@ The `ParamEnv` type has a method [`ParamEnv::with_reveal_all_normalized`][with_r [with_reveal_all]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html#method.with_reveal_all_normalized [env_reveal_all]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html#method.reveal_all [env_empty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html#method.empty -[reveal]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/traits/enum.Reveal.html [pe]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html [param_env_query]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/fn_ctxt/struct.FnCtxt.html#structfield.param_env [method_pred_entailment]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/check/compare_impl_item/fn.compare_method_predicate_entailment.html diff --git a/src/doc/rustc-dev-guide/src/param_env/param_env_what_is_it.md b/src/doc/rustc-dev-guide/src/param_env/param_env_what_is_it.md index ca09518d99f..5c2f4d59405 100644 --- a/src/doc/rustc-dev-guide/src/param_env/param_env_what_is_it.md +++ b/src/doc/rustc-dev-guide/src/param_env/param_env_what_is_it.md @@ -3,7 +3,7 @@ The type system relies on information in the environment in order for it to function correctly. This information is stored in the [`ParamEnv`][pe] type and it is important to use the correct `ParamEnv` when interacting with the type system. -The information represented by `ParamEnv` is a list of in-scope where-clauses, and a [`Reveal`][reveal] (see linked docs for more information). A `ParamEnv` typically corresponds to a specific item's where clauses, some clauses are not explicitly written bounds and instead are implicitly added in [`predicates_of`][predicates_of] such as `ConstArgHasType` or some implied bounds. +The information represented by `ParamEnv` is a list of in-scope where-clauses, and a `Reveal` (see linked docs for more information). A `ParamEnv` typically corresponds to a specific item's where clauses, some clauses are not explicitly written bounds and instead are implicitly added in [`predicates_of`][predicates_of] such as `ConstArgHasType` or some implied bounds. A `ParamEnv` can also be created with arbitrary data that is not derived from a specific item such as in [`compare_method_predicate_entailment`][method_pred_entailment] which creates a hybrid `ParamEnv` consisting of the impl's where clauses and the trait definition's function's where clauses. In most cases `ParamEnv`s are initially created via the [`param_env` query][query] which returns a `ParamEnv` derived from the provided item's where clauses. @@ -57,4 +57,3 @@ It's very important to use the correct `ParamEnv` when interacting with the type [method_pred_entailment]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/check/compare_impl_item/fn.compare_method_predicate_entailment.html [pe]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html [query]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/context/struct.TyCtxt.html#method.param_env -[reveal]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/traits/enum.Reveal.html \ No newline at end of file diff --git a/src/doc/rustc-dev-guide/src/rustdoc-internals/search.md b/src/doc/rustc-dev-guide/src/rustdoc-internals/search.md index ddf8ec405f8..3506431118b 100644 --- a/src/doc/rustc-dev-guide/src/rustdoc-internals/search.md +++ b/src/doc/rustc-dev-guide/src/rustdoc-internals/search.md @@ -46,8 +46,8 @@ For space savings, it's also written without newlines or spaces. ] ``` -[`src/librustdoc/html/static/js/externs.js`] -defines an actual schema in a Closure `@typedef`. +[`src/librustdoc/html/static/js/rustdoc.d.ts`] +defines an actual schema in a TypeScript `type`. | Key | Name | Description | | --- | -------------------- | ------------ | @@ -68,7 +68,7 @@ with a free function called `function_name` and a struct called `Data`, with the type signature `Data, i32 -> str`, and an alias, `get_name`, that equivalently refers to `function_name`. -[`src/librustdoc/html/static/js/externs.js`]: https://github.com/rust-lang/rust/blob/79b710c13968a1a48d94431d024d2b1677940866/src/librustdoc/html/static/js/externs.js#L204-L258 +[`src/librustdoc/html/static/js/rustdoc.d.ts`]: https://github.com/rust-lang/rust/blob/2f92f050e83bf3312ce4ba73c31fe843ad3cbc60/src/librustdoc/html/static/js/rustdoc.d.ts#L344-L390 The search index needs to fit the needs of the `rustdoc` compiler, the `search.js` frontend, @@ -469,7 +469,7 @@ want the libs team to be able to add new items without causing unrelated tests to fail, but standalone tests will use it more often. The `ResultsTable` and `ParsedQuery` types are specified in -[`externs.js`](https://github.com/rust-lang/rust/blob/master/src/librustdoc/html/static/js/externs.js). +[`rustdoc.d.ts`](https://github.com/rust-lang/rust/blob/master/src/librustdoc/html/static/js/rustdoc.d.ts). For example, imagine we needed to fix a bug where a function named `constructor` couldn't be found. To do this, write two files: diff --git a/src/doc/rustc-dev-guide/src/tests/ci.md b/src/doc/rustc-dev-guide/src/tests/ci.md index 9dde407895e..a4b22392f19 100644 --- a/src/doc/rustc-dev-guide/src/tests/ci.md +++ b/src/doc/rustc-dev-guide/src/tests/ci.md @@ -322,7 +322,7 @@ Our CI workflow uses various caching mechanisms, mainly for two things: ### Docker images caching The Docker images we use to run most of the Linux-based builders take a *long* -time to fully build. To speed up the build, we cache it using [Docker registry +time to fully build. To speed up the build, we cache them using [Docker registry caching], with the intermediate artifacts being stored on [ghcr.io]. We also push the built Docker images to ghcr, so that they can be reused by other tools (rustup) or by developers running the Docker build locally (to speed up their @@ -334,6 +334,13 @@ override the cache for the others. Instead, we store the images under different tags, identifying them with a custom hash made from the contents of all the Dockerfiles and related scripts. +The CI calculates a hash key, so that the cache of a Docker image is +invalidated if one of the following changes: + +- Dockerfile +- Files copied into the Docker image in the Dockerfile +- The architecture of the GitHub runner (x86 or ARM) + [ghcr.io]: https://github.com/rust-lang-ci/rust/pkgs/container/rust-ci [Docker registry caching]: https://docs.docker.com/build/cache/backends/registry/ @@ -341,9 +348,18 @@ Dockerfiles and related scripts. We build some C/C++ stuff in various CI jobs, and we rely on [sccache] to cache the intermediate LLVM artifacts. Sccache is a distributed ccache developed by -Mozilla, which can use an object storage bucket as the storage backend. In our -case, the artefacts are uploaded to an S3 bucket that we control -(`rust-lang-ci-sccache2`). +Mozilla, which can use an object storage bucket as the storage backend. + +With sccache there's no need to calculate the hash key ourselves. Sccache +invalidates the cache automatically when it detects changes to relevant inputs, +such as the source code, the version of the compiler, and important environment +variables. +So we just pass the sccache wrapper on top of cargo and sccache does the rest. + +We store the persistent artifacts on the S3 bucket `rust-lang-ci-sccache2`. So +when the CI runs, if sccache sees that LLVM is being compiled with the same C/C++ +compiler and the LLVM source code is the same, sccache retrieves the individual +compiled translation units from S3. [sccache]: https://github.com/mozilla/sccache diff --git a/src/doc/rustc-dev-guide/src/tests/directives.md b/src/doc/rustc-dev-guide/src/tests/directives.md index 9e0f8f9c279..00bb2bc4dbb 100644 --- a/src/doc/rustc-dev-guide/src/tests/directives.md +++ b/src/doc/rustc-dev-guide/src/tests/directives.md @@ -154,6 +154,7 @@ Some examples of `X` in `ignore-X` or `only-X`: `ignore-coverage-map`, `ignore-coverage-run` - When testing a dist toolchain: `dist` - This needs to be enabled with `COMPILETEST_ENABLE_DIST_TESTS=1` +- The `rustc_abi` of the target: e.g. `rustc_abi-x86_64-sse2` The following directives will check rustc build settings and target settings: @@ -192,6 +193,8 @@ settings: specified atomic widths, e.g. the test with `//@ needs-target-has-atomic: 8, 16, ptr` will only run if it supports the comma-separated list of atomic widths. +- `needs-dynamic-linking` - ignores if target does not support dynamic linking + (which is orthogonal to it being unable to create `dylib` and `cdylib` crate types) The following directives will check LLVM support: diff --git a/src/doc/rustc-dev-guide/src/tests/docker.md b/src/doc/rustc-dev-guide/src/tests/docker.md index a0aa8bd3e77..2ca08d42130 100644 --- a/src/doc/rustc-dev-guide/src/tests/docker.md +++ b/src/doc/rustc-dev-guide/src/tests/docker.md @@ -1,36 +1,44 @@ # Testing with Docker -The Rust tree includes [Docker] image definitions for the platforms used on -GitHub Actions in [`src/ci/docker`]. -The script [`src/ci/docker/run.sh`] is used to build the Docker image, run it, -build Rust within the image, and run the tests. - -You can run these images on your local development machine. This can be -helpful to test environments different from your local system. First you will +The [`src/ci/docker`] directory includes [Docker] image definitions for Linux-based jobs executed on GitHub Actions (non-Linux jobs run outside Docker). You can run these jobs on your local development machine, which can be +helpful to test environments different from your local system. You will need to install Docker on a Linux, Windows, or macOS system (typically Linux will be much faster than Windows or macOS because the latter use virtual -machines to emulate a Linux environment). To enter interactive mode which will -start a bash shell in the container, run `src/ci/docker/run.sh --dev <IMAGE>` -where `<IMAGE>` is one of the directory names in `src/ci/docker` (for example -`x86_64-gnu` is a fairly standard Ubuntu environment). - -The docker script will mount your local Rust source tree in read-only mode, -and an `obj` directory in read-write mode. All of the compiler artifacts will -be stored in the `obj` directory. The shell will start out in the `obj` -directory. From there, you can run `../src/ci/run.sh` which will run the build -as defined by the image. - -Alternatively, you can run individual commands to do specific tasks. For -example, you can run `../x test tests/ui` to just run UI tests. -Note that there is some configuration in the [`src/ci/run.sh`] script that you -may need to recreate. Particularly, set `submodules = false` in your -`config.toml` so that it doesn't attempt to modify the read-only directory. +machines to emulate a Linux environment). + +Jobs running in CI are configured through a set of bash scripts, and it is not always trivial to reproduce their behavior locally. If you want to run a CI job locally in the simplest way possible, you can use a provided helper Python script that tries to replicate what happens on CI as closely as possible: + +```bash +python3 src/ci/github-actions/ci.py run-local <job-name> +# For example: +python3 src/ci/github-actions/ci.py run-local dist-x86_64-linux-alt +``` -Some additional notes about using the Docker images: +If the above script does not work for you, you would like to have more control of the Docker image execution, or you want to understand what exactly happens during Docker job execution, then continue reading below. +## The `run.sh` script +The [`src/ci/docker/run.sh`] script is used to build a specific Docker image, run it, +build Rust within the image, and either run tests or prepare a set of archives designed for distribution. The script will mount your local Rust source tree in read-only mode, and an `obj` directory in read-write mode. All the compiler artifacts will be stored in the `obj` directory. The shell will start out in the `obj`directory. From there, it will execute `../src/ci/run.sh` which starts the build as defined by the Docker image. + +You can run `src/ci/docker/run.sh <image-name>` directly. A few important notes regarding the `run.sh` script: +- When executed on CI, the script expects that all submodules are checked out. If some submodule that is accessed by the job is not available, the build will result in an error. You should thus make sure that you have all required submodules checked out locally. You can either do that manually through git, or set `submodules = true` in your `config.toml` and run a command such as `x build` to let bootstrap download the most important submodules (this might not be enough for the given CI job that you are trying to execute though). +- `<image-name>` corresponds to a single directory located in one of the `src/ci/docker/host-*` directories. Note that image name does not necessarily correspond to a job name, as some jobs execute the same image, but with different environment variables or Docker build arguments (this is a part of the complexity that makes it difficult to run CI jobs locally). +- If you are executing a "dist" job (job beginning with `dist-`), you should set the `DEPLOY=1` environment variable. +- If you are executing an "alternative dist" job (job beginning with `dist-` and ending with `-alt`), you should set the `DEPLOY_ALT=1` environment variable. - Some of the std tests require IPv6 support. Docker on Linux seems to have it disabled by default. Run the commands in [`enable-docker-ipv6.sh`] to enable IPv6 before creating the container. This only needs to be done once. + +### Interactive mode + +Sometimes, it can be useful to build a specific Docker image, and then run custom commands inside it, so that you can experiment with how the given system behaves. You can do that using an interactive mode, which will +start a bash shell in the container, using `src/ci/docker/run.sh --dev <image-name>`. + +When inside the Docker container, you can run individual commands to do specific tasks. For +example, you can run `../x test tests/ui` to just run UI tests. + +Some additional notes about using the interactive mode: + - The container will be deleted automatically when you exit the shell, however the build artifacts persist in the `obj` directory. If you are switching between different Docker images, the artifacts from previous environments @@ -45,15 +53,6 @@ Some additional notes about using the Docker images: containers. With the container name, run `docker exec -it <CONTAINER> /bin/bash` where `<CONTAINER>` is the container name like `4ba195e95cef`. -The approach described above is a relatively low-level interface for running the Docker images -directly. If you want to run a full CI Linux job locally with Docker, in a way that is as close to CI as possible, you can use the following command: - -```bash -python3 src/ci/github-actions/ci.py run-local <job-name> -# For example: -python3 src/ci/github-actions/ci.py run-local dist-x86_64-linux-alt -``` - [Docker]: https://www.docker.com/ [`src/ci/docker`]: https://github.com/rust-lang/rust/tree/master/src/ci/docker [`src/ci/docker/run.sh`]: https://github.com/rust-lang/rust/blob/master/src/ci/docker/run.sh diff --git a/src/doc/rustc-dev-guide/src/traits/implied-bounds.md b/src/doc/rustc-dev-guide/src/traits/implied-bounds.md index 05693dcd5a1..cdcb90d3e2e 100644 --- a/src/doc/rustc-dev-guide/src/traits/implied-bounds.md +++ b/src/doc/rustc-dev-guide/src/traits/implied-bounds.md @@ -40,7 +40,7 @@ requirements of impls and functions as explicit predicates. ### using implicit implied bounds as assumptions These bounds are not added to the `ParamEnv` of the affected item itself. For lexical -region resolution they are added using [`fn OutlivesEnvironment::new`]. +region resolution they are added using [`fn OutlivesEnvironment::from_normalized_bounds`]. Similarly, during MIR borrowck we add them using [`fn UniversalRegionRelationsBuilder::add_implied_bounds`]. @@ -55,7 +55,7 @@ The assumed outlives constraints for implicit bounds are computed using the MIR borrowck adds the outlives constraints for both the normalized and unnormalized types, lexical region resolution [only uses the unnormalized types][notnorm]. -[`fn OutlivesEnvironment::new`]: TODO +[`fn OutlivesEnvironment::from_normalized_bounds`]: https://github.com/rust-lang/rust/blob/8239a37f9c0951a037cfc51763ea52a20e71e6bd/compiler/rustc_infer/src/infer/outlives/env.rs#L50-L55 [`fn UniversalRegionRelationsBuilder::add_implied_bounds`]: https://github.com/rust-lang/rust/blob/5b8bc568d28b2e922290c9a966b3231d0ce9398b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs#L316 [mir]: https://github.com/rust-lang/rust/blob/91cae1dcdcf1a31bd8a92e4a63793d65cfe289bb/compiler/rustc_borrowck/src/type_check/free_region_relations.rs#L258-L332 [`fn assumed_wf_types`]: https://github.com/rust-lang/rust/blob/5b8bc568d28b2e922290c9a966b3231d0ce9398b/compiler/rustc_ty_utils/src/implied_bounds.rs#L21 diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 670e4bd1be6..6c7cdec3480 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -29,6 +29,7 @@ - [\*-apple-watchos](platform-support/apple-watchos.md) - [\*-apple-visionos](platform-support/apple-visionos.md) - [aarch64-nintendo-switch-freestanding](platform-support/aarch64-nintendo-switch-freestanding.md) + - [amdgcn-amd-amdhsa](platform-support/amdgcn-amd-amdhsa.md) - [armeb-unknown-linux-gnueabi](platform-support/armeb-unknown-linux-gnueabi.md) - [arm-none-eabi](platform-support/arm-none-eabi.md) - [armv4t-none-eabi](platform-support/armv4t-none-eabi.md) @@ -101,6 +102,7 @@ - [\*-win7-windows-gnu](platform-support/win7-windows-gnu.md) - [\*-win7-windows-msvc](platform-support/win7-windows-msvc.md) - [x86_64-fortanix-unknown-sgx](platform-support/x86_64-fortanix-unknown-sgx.md) + - [x86_64-pc-cygwin](platform-support/x86_64-pc-cygwin.md) - [x86_64-pc-solaris](platform-support/solaris.md) - [x86_64-unknown-linux-none.md](platform-support/x86_64-unknown-linux-none.md) - [x86_64-unknown-none](platform-support/x86_64-unknown-none.md) diff --git a/src/doc/rustc/src/check-cfg.md b/src/doc/rustc/src/check-cfg.md index c62ca9fd9ad..00add2651ae 100644 --- a/src/doc/rustc/src/check-cfg.md +++ b/src/doc/rustc/src/check-cfg.md @@ -135,7 +135,7 @@ As of `2025-01-02T`, the list of known names is as follows: - `windows` > Starting with 1.85.0, the `test` cfg is consider to be a "userspace" config -> despite being also set by `rustc` and should be managed by the build-system it-self. +> despite being also set by `rustc` and should be managed by the build system itself. Like with `values(any())`, well known names checking can be disabled by passing `cfg(any())` as argument to `--check-cfg`. diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md index f45217c69ff..8c1769a8c77 100644 --- a/src/doc/rustc/src/codegen-options/index.md +++ b/src/doc/rustc/src/codegen-options/index.md @@ -368,7 +368,7 @@ This flag controls the optimization level. * `s`: optimize for binary size. * `z`: optimize for binary size, but also turn off loop vectorization. -Note: The [`-O` flag][option-o-optimize] is an alias for `-C opt-level=2`. +Note: The [`-O` flag][option-o-optimize] is an alias for `-C opt-level=3`. The default is `0`. diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md index 0942b5ebfee..9dd2e7de1b3 100644 --- a/src/doc/rustc/src/command-line-arguments.md +++ b/src/doc/rustc/src/command-line-arguments.md @@ -308,7 +308,7 @@ A synonym for [`-C debuginfo=2`](codegen-options/index.md#debuginfo). <a id="option-o-optimize"></a> ## `-O`: optimize your code -A synonym for [`-C opt-level=2`](codegen-options/index.md#opt-level). +A synonym for [`-C opt-level=3`](codegen-options/index.md#opt-level). <a id="option-o-output"></a> ## `-o`: filename of the output diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 895014b499d..b5cd3864620 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -165,11 +165,11 @@ target | std | notes `i586-pc-windows-msvc` | * | 32-bit Windows (original Pentium) [^x86_32-floats-x87] `i586-unknown-linux-gnu` | ✓ | 32-bit Linux (kernel 3.2, glibc 2.17, original Pentium) [^x86_32-floats-x87] `i586-unknown-linux-musl` | ✓ | 32-bit Linux (musl 1.2.3, original Pentium) [^x86_32-floats-x87] -[`i686-linux-android`](platform-support/android.md) | ✓ | 32-bit x86 Android ([PentiumPro with SSE](https://developer.android.com/ndk/guides/abis.html#x86)) [^x86_32-floats-return-ABI] +[`i686-linux-android`](platform-support/android.md) | ✓ | 32-bit x86 Android ([Pentium 4 plus various extensions](https://developer.android.com/ndk/guides/abis.html#x86)) [^x86_32-floats-return-ABI] [`i686-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | 32-bit x86 MinGW (Windows 10+, Pentium 4), LLVM ABI [^x86_32-floats-return-ABI] [`i686-unknown-freebsd`](platform-support/freebsd.md) | ✓ | 32-bit x86 FreeBSD (Pentium 4) [^x86_32-floats-return-ABI] `i686-unknown-linux-musl` | ✓ | 32-bit Linux with musl 1.2.3 (Pentium 4) [^x86_32-floats-return-ABI] -[`i686-unknown-uefi`](platform-support/unknown-uefi.md) | ? (Pentium 4, softfloat) | 32-bit UEFI +[`i686-unknown-uefi`](platform-support/unknown-uefi.md) | ? | 32-bit UEFI (Pentium 4, softfloat) [`loongarch64-unknown-none`](platform-support/loongarch-none.md) | * | LoongArch64 Bare-metal (LP64D ABI) [`loongarch64-unknown-none-softfloat`](platform-support/loongarch-none.md) | * | LoongArch64 Bare-metal (LP64S ABI) [`nvptx64-nvidia-cuda`](platform-support/nvptx64-nvidia-cuda.md) | * | --emit=asm generates PTX code that [runs on NVIDIA GPUs] @@ -272,6 +272,7 @@ target | std | host | notes `aarch64_be-unknown-linux-gnu` | ✓ | ✓ | ARM64 Linux (big-endian) `aarch64_be-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (big-endian, ILP32 ABI) [`aarch64_be-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | ARM64 NetBSD (big-endian) +[`amdgcn-amd-amdhsa`](platform-support/amdgcn-amd-amdhsa.md) | * | | `-Ctarget-cpu=gfx...` to specify [the AMD GPU] to compile for [`arm64_32-apple-watchos`](platform-support/apple-watchos.md) | ✓ | | Arm Apple WatchOS 64-bit with 32-bit pointers [`arm64e-apple-darwin`](platform-support/arm64e-apple-darwin.md) | ✓ | ✓ | ARM64e Apple Darwin [`arm64e-apple-ios`](platform-support/arm64e-apple-ios.md) | ✓ | | ARM64e Apple iOS @@ -310,12 +311,12 @@ target | std | host | notes [`i386-apple-ios`](platform-support/apple-ios.md) | ✓ | | 32-bit x86 iOS (Penryn) [^x86_32-floats-return-ABI] [`i586-pc-nto-qnx700`](platform-support/nto-qnx.md) | * | | 32-bit x86 QNX Neutrino 7.0 RTOS (Pentium 4) [^x86_32-floats-return-ABI] [`i586-unknown-netbsd`](platform-support/netbsd.md) | ✓ | | 32-bit x86 (original Pentium) [^x86_32-floats-x87] +[`i586-unknown-redox`](platform-support/redox.md) | ✓ | | 32-bit x86 Redox OS (PentiumPro) [^x86_32-floats-x87] [`i686-apple-darwin`](platform-support/apple-darwin.md) | ✓ | ✓ | 32-bit macOS (10.12+, Sierra+, Penryn) [^x86_32-floats-return-ABI] `i686-unknown-haiku` | ✓ | ✓ | 32-bit Haiku (Pentium 4) [^x86_32-floats-return-ABI] -[`i686-unknown-hurd-gnu`](platform-support/hurd.md) | ✓ | ✓ | 32-bit GNU/Hurd (Pentium 4) [^x86_32-floats-x87] +[`i686-unknown-hurd-gnu`](platform-support/hurd.md) | ✓ | ✓ | 32-bit GNU/Hurd (Pentium 4) [^x86_32-floats-return-ABI] [`i686-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | NetBSD/i386 (Pentium 4) [^x86_32-floats-return-ABI] [`i686-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | 32-bit OpenBSD (Pentium 4) [^x86_32-floats-return-ABI] -[`i686-unknown-redox`](platform-support/redox.md) | ✓ | | i686 Redox OS (PentiumPro) [^x86_32-floats-x87] `i686-uwp-windows-gnu` | ✓ | | [^x86_32-floats-return-ABI] [`i686-uwp-windows-msvc`](platform-support/uwp-windows-msvc.md) | ✓ | | [^x86_32-floats-return-ABI] [`i686-win7-windows-gnu`](platform-support/win7-windows-gnu.md) | ✓ | | 32-bit Windows 7 support [^x86_32-floats-return-ABI] @@ -406,6 +407,7 @@ target | std | host | notes [`wasm64-unknown-unknown`](platform-support/wasm64-unknown-unknown.md) | ? | | WebAssembly [`x86_64-apple-tvos`](platform-support/apple-tvos.md) | ✓ | | x86 64-bit tvOS [`x86_64-apple-watchos-sim`](platform-support/apple-watchos.md) | ✓ | | x86 64-bit Apple WatchOS simulator +[`x86_64-pc-cygwin`](platform-support/x86_64-pc-cygwin.md) | ? | | 64-bit x86 Cygwin | [`x86_64-pc-nto-qnx710`](platform-support/nto-qnx.md) | ✓ | | x86 64-bit QNX Neutrino 7.1 RTOS with default network stack (io-pkt) | [`x86_64-pc-nto-qnx710_iosock`](platform-support/nto-qnx.md) | ✓ | | x86 64-bit QNX Neutrino 7.1 RTOS with new network stack (io-sock) | [`x86_64-pc-nto-qnx800`](platform-support/nto-qnx.md) | ✓ | | x86 64-bit QNX Neutrino 8.0 RTOS | @@ -432,3 +434,4 @@ target | std | host | notes [`xtensa-esp32s3-none-elf`](platform-support/xtensa.md) | * | | Xtensa ESP32-S3 [runs on NVIDIA GPUs]: https://github.com/japaric-archived/nvptx#targets +[the AMD GPU]: https://llvm.org/docs/AMDGPUUsage.html#processors diff --git a/src/doc/rustc/src/platform-support/amdgcn-amd-amdhsa.md b/src/doc/rustc/src/platform-support/amdgcn-amd-amdhsa.md new file mode 100644 index 00000000000..0b2f798e66d --- /dev/null +++ b/src/doc/rustc/src/platform-support/amdgcn-amd-amdhsa.md @@ -0,0 +1,111 @@ +# `amdgcn-amd-amdhsa` + +**Tier: 3** + +AMD GPU target for compute/HSA (Heterogeneous System Architecture). + +## Target maintainers + +- [@Flakebi](https://github.com/Flakebi) + +## Requirements + +AMD GPUs can be targeted via cross-compilation. +Supported GPUs depend on the LLVM version that is used by Rust. +In general, most GPUs starting from gfx7 (Sea Islands/CI) are supported as compilation targets, though older GPUs are not supported by the latest host runtime. +Details about supported GPUs can be found in [LLVM’s documentation] and [ROCm documentation]. + +Binaries can be loaded by [HIP] or by the HSA runtime implemented in [ROCR-Runtime]. +The format of binaries is a linked ELF. + +Binaries must be built with no-std. +They can use `core` and `alloc` (`alloc` only if an allocator is supplied). +At least one function needs to use the `"gpu-kernel"` calling convention and should be marked with `no_mangle` for simplicity. +Functions using the `"gpu-kernel"` calling convention are kernel entrypoints and can be used from the host runtime. + +## Building the target + +The target is included in rustc. + +## Building Rust programs + +The amdgpu target supports many hardware generations, which need different binaries. +The generations are exposed as different target-cpus in the backend. +As there are many, Rust does not ship pre-compiled libraries for this target. +Therefore, you have to build your own copy of `core` by using `cargo -Zbuild-std=core` or similar. + +To build a binary, create a no-std library: +```rust,ignore (platform-specific) +// src/lib.rs +#![feature(abi_gpu_kernel)] +#![no_std] + +#[panic_handler] +fn panic(_: &core::panic::PanicInfo) -> ! { + loop {} +} + +#[no_mangle] +pub extern "gpu-kernel" fn kernel(/* Arguments */) { + // Code +} +``` + +Build the library as `cdylib`: +```toml +# Cargo.toml +[lib] +crate-type = ["cdylib"] + +[profile.dev] +lto = true # LTO must be explicitly enabled for now +[profile.release] +lto = true +``` + +The target-cpu must be from the list [supported by LLVM] (or printed with `rustc --target amdgcn-amd-amdhsa --print target-cpus`). +The GPU version on the current system can be found e.g. with [`rocminfo`]. + +Example `.cargo/config.toml` file to set the target and GPU generation: +```toml +# .cargo/config.toml +[build] +target = "amdgcn-amd-amdhsa" +rustflags = ["-Ctarget-cpu=gfx1100"] + +[unstable] +build-std = ["core"] # Optional: "alloc" +``` + +## Running Rust programs + +To run a binary on an AMD GPU, a host runtime is needed. +On Linux and Windows, [HIP] can be used to load and run binaries. +Example code on how to load a compiled binary and run it is available in [ROCm examples]. + +On Linux, binaries can also run through the HSA runtime as implemented in [ROCR-Runtime]. + +<!-- Mention an allocator once a suitable one exists for amdgpu --> + +<!-- +## Testing + +Does the target support running binaries, or do binaries have varying +expectations that prevent having a standard way to run them? If users can run +binaries, can they do so in some common emulator, or do they need native +hardware? Does the target support running the Rust testsuite? + +--> + +## Additional information + +More information can be found on the [LLVM page for amdgpu]. + +[LLVM’s documentation]: https://llvm.org/docs/AMDGPUUsage.html#processors +[ROCm documentation]: https://rocmdocs.amd.com +[HIP]: https://rocm.docs.amd.com/projects/HIP/ +[ROCR-Runtime]: https://github.com/ROCm/ROCR-Runtime +[supported by LLVM]: https://llvm.org/docs/AMDGPUUsage.html#processors +[LLVM page for amdgpu]: https://llvm.org/docs/AMDGPUUsage.html +[`rocminfo`]: https://github.com/ROCm/rocminfo +[ROCm examples]: https://github.com/ROCm/rocm-examples/tree/ca8ef5b6f1390176616cd1c18fbc98785cbc73f6/HIP-Basic/module_api diff --git a/src/doc/rustc/src/platform-support/redox.md b/src/doc/rustc/src/platform-support/redox.md index 1b3321956ef..2bba92d504c 100644 --- a/src/doc/rustc/src/platform-support/redox.md +++ b/src/doc/rustc/src/platform-support/redox.md @@ -9,7 +9,7 @@ Target triplets available so far: - `x86_64-unknown-redox` (tier 2) - `aarch64-unknown-redox` (tier 3) -- `i686-unknown-redox` (tier 3) +- `i586-unknown-redox` (tier 3) ## Target maintainers @@ -36,7 +36,7 @@ target = [ "<HOST_TARGET>", "x86_64-unknown-redox", "aarch64-unknown-redox", - "i686-unknown-redox", + "i586-unknown-redox", ] ``` diff --git a/src/doc/rustc/src/platform-support/x86_64-pc-cygwin.md b/src/doc/rustc/src/platform-support/x86_64-pc-cygwin.md new file mode 100644 index 00000000000..a8fc4f181d8 --- /dev/null +++ b/src/doc/rustc/src/platform-support/x86_64-pc-cygwin.md @@ -0,0 +1,39 @@ +# `x86_64-pc-cygwin` + +**Tier: 3** + +Windows targets supporting Cygwin. +The `*-cygwin` targets are **not** intended as native target for applications, +a developer writing Windows applications should use the `*-pc-windows-*` targets instead, which are *native* Windows. + +Cygwin is only intended as an emulation layer for Unix-only programs which do not support the native Windows targets. + +## Target maintainers + +- [Berrysoft](https://github.com/Berrysoft) + +## Requirements + +This target is cross compiled. It needs `x86_64-pc-cygwin-gcc` as linker. + +The `target_os` of the target is `cygwin`, and it is `unix`. + +## Building the target + +For cross-compilation you want LLVM with [llvm/llvm-project#121439 (merged)](https://github.com/llvm/llvm-project/pull/121439) applied to fix the LLVM codegen on importing external global variables from DLLs. +No native builds on Cygwin now. It should be possible theoretically though, but might need a lot of patches. + +## Building Rust programs + +Rust does not yet ship pre-compiled artifacts for this target. To compile for +this target, you will either need to build Rust with the target enabled (see +"Building the target" above), or build your own copy of `core` by using +`build-std` or similar. + +## Testing + +Created binaries work fine on Windows with Cygwin. + +## Cross-compilation toolchains and C code + +Compatible C code can be built with GCC shipped with Cygwin. Clang is untested. diff --git a/src/doc/unstable-book/src/language-features/asm-experimental-arch.md b/src/doc/unstable-book/src/language-features/asm-experimental-arch.md index c2f4170d7d2..d9566c9f55c 100644 --- a/src/doc/unstable-book/src/language-features/asm-experimental-arch.md +++ b/src/doc/unstable-book/src/language-features/asm-experimental-arch.md @@ -199,3 +199,5 @@ These flags registers must be restored upon exiting the asm block if the `preser - SPARC - Integer condition codes (`icc` and `xcc`) - Floating-point condition codes (`fcc[0-3]`) +- CSKY + - Condition/carry bit (C) in `PSR`. diff --git a/src/doc/unstable-book/src/language-features/extended-varargs-abi-support.md b/src/doc/unstable-book/src/language-features/extended-varargs-abi-support.md new file mode 100644 index 00000000000..b20c30ec8f1 --- /dev/null +++ b/src/doc/unstable-book/src/language-features/extended-varargs-abi-support.md @@ -0,0 +1,10 @@ +# `extended_varargs_abi_support` + +The tracking issue for this feature is: [#100189] + +[#100189]: https://github.com/rust-lang/rust/issues/100189 + +------------------------ + +This feature adds the possibility of using `sysv64`, `win64` or `efiapi` calling +conventions on functions with varargs. diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index b576f28176e..bec7fbe8f52 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -13,8 +13,8 @@ use rustc_session::parse::ParseSess; use rustc_span::Span; use rustc_span::symbol::{Symbol, sym}; +use crate::display::Joined as _; use crate::html::escape::Escape; -use crate::joined::Joined as _; #[cfg(test)] mod tests; diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 3d51ab1967d..e10a74221ae 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -488,7 +488,7 @@ pub(crate) fn build_impl( impl_ .items .iter() - .map(|item| tcx.hir().impl_item(item.id)) + .map(|item| tcx.hir_impl_item(item.id)) .filter(|item| { // Filter out impl items whose corresponding trait item has `doc(hidden)` // not to document such impl items. @@ -703,7 +703,7 @@ fn build_module_items( pub(crate) fn print_inlined_const(tcx: TyCtxt<'_>, did: DefId) -> String { if let Some(did) = did.as_local() { let hir_id = tcx.local_def_id_to_hir_id(did); - rustc_hir_pretty::id_to_string(&tcx.hir(), hir_id) + rustc_hir_pretty::id_to_string(&tcx, hir_id) } else { tcx.rendered_const(did).clone() } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 1d62a93e723..92ef3ab7a1d 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1145,7 +1145,7 @@ fn clean_args_from_types_and_body_id<'tcx>( types: &[hir::Ty<'tcx>], body_id: hir::BodyId, ) -> Arguments { - let body = cx.tcx.hir().body(body_id); + let body = cx.tcx.hir_body(body_id); Arguments { values: types @@ -2845,7 +2845,7 @@ fn clean_maybe_renamed_item<'tcx>( ItemKind::Trait(_, _, generics, bounds, item_ids) => { let items = item_ids .iter() - .map(|ti| clean_trait_item(cx.tcx.hir().trait_item(ti.id), cx)) + .map(|ti| clean_trait_item(cx.tcx.hir_trait_item(ti.id), cx)) .collect(); TraitItem(Box::new(Trait { @@ -2891,7 +2891,7 @@ fn clean_impl<'tcx>( let items = impl_ .items .iter() - .map(|ii| clean_impl_item(tcx.hir().impl_item(ii.id), cx)) + .map(|ii| clean_impl_item(tcx.hir_impl_item(ii.id), cx)) .collect::<Vec<_>>(); // If this impl block is an implementation of the Deref trait, then we diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 5f7c30a33ab..8b424499724 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -220,12 +220,11 @@ impl ExternalCrate { None }; if root.is_local() { - tcx.hir() - .root_module() + tcx.hir_root_module() .item_ids .iter() .filter_map(|&id| { - let item = tcx.hir().item(id); + let item = tcx.hir_item(id); match item.kind { hir::ItemKind::Mod(_) => { as_keyword(Res::Def(DefKind::Mod, id.owner_id.to_def_id())) @@ -277,12 +276,11 @@ impl ExternalCrate { }; if root.is_local() { - tcx.hir() - .root_module() + tcx.hir_root_module() .item_ids .iter() .filter_map(|&id| { - let item = tcx.hir().item(id); + let item = tcx.hir_item(id); match item.kind { hir::ItemKind::Mod(_) => { as_primitive(Res::Def(DefKind::Mod, id.owner_id.to_def_id())) @@ -2122,9 +2120,8 @@ impl Discriminant { /// Will be `None` in the case of cross-crate reexports, and may be /// simplified pub(crate) fn expr(&self, tcx: TyCtxt<'_>) -> Option<String> { - self.expr.map(|body| { - rendered_const(tcx, tcx.hir().body(body), tcx.hir().body_owner_def_id(body)) - }) + self.expr + .map(|body| rendered_const(tcx, tcx.hir_body(body), tcx.hir().body_owner_def_id(body))) } pub(crate) fn value(&self, tcx: TyCtxt<'_>, with_underscores: bool) -> String { print_evaluated_const(tcx, self.value, with_underscores, false).unwrap() @@ -2420,7 +2417,7 @@ impl ConstantKind { ConstantKind::Path { ref path } => path.to_string(), ConstantKind::Extern { def_id } => print_inlined_const(tcx, def_id), ConstantKind::Local { body, .. } | ConstantKind::Anonymous { body } => { - rendered_const(tcx, tcx.hir().body(body), tcx.hir().body_owner_def_id(body)) + rendered_const(tcx, tcx.hir_body(body), tcx.hir().body_owner_def_id(body)) } ConstantKind::Infer { .. } => "_".to_string(), } diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 5c146da03ac..1ead87fd69d 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -378,7 +378,7 @@ pub(crate) fn run_global_ctxt( ctxt.external_traits.insert(sized_trait_did, sized_trait); } - debug!("crate: {:?}", tcx.hir().krate()); + debug!("crate: {:?}", tcx.hir_crate(())); let mut krate = tcx.sess.time("clean_crate", || clean::krate(&mut ctxt)); @@ -464,10 +464,10 @@ impl<'tcx> EmitIgnoredResolutionErrors<'tcx> { impl<'tcx> Visitor<'tcx> for EmitIgnoredResolutionErrors<'tcx> { type NestedFilter = nested_filter::OnlyBodies; - fn nested_visit_map(&mut self) -> Self::Map { + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { // We need to recurse into nested closures, // since those will fallback to the parent for type checking. - self.tcx.hir() + self.tcx } fn visit_path(&mut self, path: &Path<'tcx>, _id: HirId) { diff --git a/src/librustdoc/joined.rs b/src/librustdoc/display.rs index f369c6cf237..ee8dde013ee 100644 --- a/src/librustdoc/joined.rs +++ b/src/librustdoc/display.rs @@ -1,3 +1,5 @@ +//! Various utilities for working with [`fmt::Display`] implementations. + use std::fmt::{self, Display, Formatter}; pub(crate) trait Joined: IntoIterator { @@ -27,3 +29,19 @@ where Ok(()) } } + +pub(crate) trait MaybeDisplay { + /// For a given `Option<T: Display>`, returns a `Display` implementation that will display `t` if `Some(t)`, or nothing if `None`. + fn maybe_display(self) -> impl Display; +} + +impl<T: Display> MaybeDisplay for Option<T> { + fn maybe_display(self) -> impl Display { + fmt::from_fn(move |f| { + if let Some(t) = self.as_ref() { + t.fmt(f)?; + } + Ok(()) + }) + } +} diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 8b522e614b8..4a379b4235f 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -786,6 +786,7 @@ impl IndividualTestOptions { /// [`clean`]: crate::clean /// [`run_merged_tests`]: crate::doctest::runner::DocTestRunner::run_merged_tests /// [`generate_unique_doctest`]: crate::doctest::make::DocTestBuilder::generate_unique_doctest +#[derive(Debug)] pub(crate) struct ScrapedDocTest { filename: FileName, line: usize, diff --git a/src/librustdoc/doctest/rust.rs b/src/librustdoc/doctest/rust.rs index c4956bfd2b4..0d52e21419f 100644 --- a/src/librustdoc/doctest/rust.rs +++ b/src/librustdoc/doctest/rust.rs @@ -147,14 +147,14 @@ impl HirCollector<'_> { impl<'tcx> intravisit::Visitor<'tcx> for HirCollector<'tcx> { type NestedFilter = nested_filter::All; - fn nested_visit_map(&mut self) -> Self::Map { - self.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.tcx } fn visit_item(&mut self, item: &'tcx hir::Item<'_>) { let name = match &item.kind { hir::ItemKind::Impl(impl_) => { - rustc_hir_pretty::id_to_string(&self.tcx.hir(), impl_.self_ty.hir_id) + rustc_hir_pretty::id_to_string(&self.tcx, impl_.self_ty.hir_id) } _ => item.ident.to_string(), }; diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index b6a73602a32..91b4b3ba1eb 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -30,120 +30,15 @@ use super::url_parts_builder::{UrlPartsBuilder, estimate_item_path_byte_length}; use crate::clean::types::ExternalLocation; use crate::clean::utils::find_nearest_parent_module; use crate::clean::{self, ExternalCrate, PrimitiveType}; +use crate::display::Joined as _; use crate::formats::cache::Cache; use crate::formats::item_type::ItemType; use crate::html::escape::{Escape, EscapeBodyText}; use crate::html::render::Context; -use crate::joined::Joined as _; use crate::passes::collect_intra_doc_links::UrlFragment; -pub(crate) trait Print { - fn print(self, buffer: &mut Buffer); -} - -impl<F> Print for F -where - F: FnOnce(&mut Buffer), -{ - fn print(self, buffer: &mut Buffer) { - (self)(buffer) - } -} - -impl Print for String { - fn print(self, buffer: &mut Buffer) { - buffer.write_str(&self); - } -} - -impl Print for &'_ str { - fn print(self, buffer: &mut Buffer) { - buffer.write_str(self); - } -} - -#[derive(Debug, Clone)] -pub(crate) struct Buffer { - for_html: bool, - buffer: String, -} - -impl core::fmt::Write for Buffer { - #[inline] - fn write_str(&mut self, s: &str) -> fmt::Result { - self.buffer.write_str(s) - } - - #[inline] - fn write_char(&mut self, c: char) -> fmt::Result { - self.buffer.write_char(c) - } - - #[inline] - fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> fmt::Result { - self.buffer.write_fmt(args) - } -} - -impl Buffer { - pub(crate) fn empty_from(v: &Buffer) -> Buffer { - Buffer { for_html: v.for_html, buffer: String::new() } - } - - pub(crate) fn html() -> Buffer { - Buffer { for_html: true, buffer: String::new() } - } - - pub(crate) fn new() -> Buffer { - Buffer { for_html: false, buffer: String::new() } - } - - pub(crate) fn is_empty(&self) -> bool { - self.buffer.is_empty() - } - - pub(crate) fn into_inner(self) -> String { - self.buffer - } - - pub(crate) fn push(&mut self, c: char) { - self.buffer.push(c); - } - - pub(crate) fn push_str(&mut self, s: &str) { - self.buffer.push_str(s); - } - - pub(crate) fn push_buffer(&mut self, other: Buffer) { - self.buffer.push_str(&other.buffer); - } - - // Intended for consumption by write! and writeln! (std::fmt) but without - // the fmt::Result return type imposed by fmt::Write (and avoiding the trait - // import). - pub(crate) fn write_str(&mut self, s: &str) { - self.buffer.push_str(s); - } - - // Intended for consumption by write! and writeln! (std::fmt) but without - // the fmt::Result return type imposed by fmt::Write (and avoiding the trait - // import). - pub(crate) fn write_fmt(&mut self, v: fmt::Arguments<'_>) { - self.buffer.write_fmt(v).unwrap(); - } - - pub(crate) fn to_display<T: Print>(mut self, t: T) -> String { - t.print(&mut self); - self.into_inner() - } - - pub(crate) fn reserve(&mut self, additional: usize) { - self.buffer.reserve(additional) - } - - pub(crate) fn len(&self) -> usize { - self.buffer.len() - } +pub(crate) fn write_str(s: &mut String, f: fmt::Arguments<'_>) { + s.write_fmt(f).unwrap(); } pub(crate) fn print_generic_bounds<'a, 'tcx: 'a>( @@ -772,7 +667,7 @@ pub(crate) fn link_tooltip(did: DefId, fragment: &Option<UrlFragment>, cx: &Cont else { return String::new(); }; - let mut buf = Buffer::new(); + let mut buf = String::new(); let fqp = if *shortty == ItemType::Primitive { // primitives are documented in a crate, but not actually part of it &fqp[fqp.len() - 1..] @@ -780,19 +675,19 @@ pub(crate) fn link_tooltip(did: DefId, fragment: &Option<UrlFragment>, cx: &Cont fqp }; if let &Some(UrlFragment::Item(id)) = fragment { - write!(buf, "{} ", cx.tcx().def_descr(id)); + write_str(&mut buf, format_args!("{} ", cx.tcx().def_descr(id))); for component in fqp { - write!(buf, "{component}::"); + write_str(&mut buf, format_args!("{component}::")); } - write!(buf, "{}", cx.tcx().item_name(id)); + write_str(&mut buf, format_args!("{}", cx.tcx().item_name(id))); } else if !fqp.is_empty() { let mut fqp_it = fqp.iter(); - write!(buf, "{shortty} {}", fqp_it.next().unwrap()); + write_str(&mut buf, format_args!("{shortty} {}", fqp_it.next().unwrap())); for component in fqp_it { - write!(buf, "::{component}"); + write_str(&mut buf, format_args!("::{component}")); } } - buf.into_inner() + buf } /// Used to render a [`clean::Path`]. @@ -814,19 +709,22 @@ fn resolved_path( if w.alternate() { write!(w, "{}{:#}", last.name, last.args.print(cx))?; } else { - let path = if use_absolute { - if let Ok((_, _, fqp)) = href(did, cx) { - format!( - "{path}::{anchor}", - path = join_with_double_colon(&fqp[..fqp.len() - 1]), - anchor = anchor(did, *fqp.last().unwrap(), cx) - ) + let path = fmt::from_fn(|f| { + if use_absolute { + if let Ok((_, _, fqp)) = href(did, cx) { + write!( + f, + "{path}::{anchor}", + path = join_with_double_colon(&fqp[..fqp.len() - 1]), + anchor = anchor(did, *fqp.last().unwrap(), cx) + ) + } else { + write!(f, "{}", last.name) + } } else { - last.name.to_string() + write!(f, "{}", anchor(did, last.name, cx)) } - } else { - anchor(did, last.name, cx).to_string() - }; + }); write!(w, "{path}{args}", args = last.args.print(cx))?; } Ok(()) @@ -854,16 +752,20 @@ fn primitive_link_fragment( match m.primitive_locations.get(&prim) { Some(&def_id) if def_id.is_local() => { let len = cx.current.len(); - let path = if len == 0 { - let cname_sym = ExternalCrate { crate_num: def_id.krate }.name(cx.tcx()); - format!("{cname_sym}/") - } else { - "../".repeat(len - 1) - }; + let path = fmt::from_fn(|f| { + if len == 0 { + let cname_sym = ExternalCrate { crate_num: def_id.krate }.name(cx.tcx()); + write!(f, "{cname_sym}/")?; + } else { + for _ in 0..(len - 1) { + f.write_str("../")?; + } + } + Ok(()) + }); write!( f, - "<a class=\"primitive\" href=\"{}primitive.{}.html{fragment}\">", - path, + "<a class=\"primitive\" href=\"{path}primitive.{}.html{fragment}\">", prim.as_sym() )?; needs_termination = true; diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 8c91cae4931..ed4b97d3625 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -14,7 +14,7 @@ use rustc_span::edition::Edition; use rustc_span::symbol::Symbol; use rustc_span::{BytePos, DUMMY_SP, Span}; -use super::format::{self, Buffer}; +use super::format::{self, write_str}; use crate::clean::PrimitiveType; use crate::html::escape::EscapeBodyText; use crate::html::render::{Context, LinkFromSrc}; @@ -48,72 +48,80 @@ pub(crate) enum Tooltip { /// Highlights `src` as an inline example, returning the HTML output. pub(crate) fn render_example_with_highlighting( src: &str, - out: &mut Buffer, + out: &mut String, tooltip: Tooltip, playground_button: Option<&str>, extra_classes: &[String], ) { write_header(out, "rust-example-rendered", None, tooltip, extra_classes); - write_code(out, src, None, None); + write_code(out, src, None, None, None); write_footer(out, playground_button); } fn write_header( - out: &mut Buffer, + out: &mut String, class: &str, - extra_content: Option<Buffer>, + extra_content: Option<&str>, tooltip: Tooltip, extra_classes: &[String], ) { - write!( + write_str( out, - "<div class=\"example-wrap{}\">", - match tooltip { - Tooltip::Ignore => " ignore", - Tooltip::CompileFail => " compile_fail", - Tooltip::ShouldPanic => " should_panic", - Tooltip::Edition(_) => " edition", - Tooltip::None => "", - }, + format_args!( + "<div class=\"example-wrap{}\">", + match tooltip { + Tooltip::Ignore => " ignore", + Tooltip::CompileFail => " compile_fail", + Tooltip::ShouldPanic => " should_panic", + Tooltip::Edition(_) => " edition", + Tooltip::None => "", + } + ), ); if tooltip != Tooltip::None { let edition_code; - write!( + write_str( out, - "<a href=\"#\" class=\"tooltip\" title=\"{}\">ⓘ</a>", - match tooltip { - Tooltip::Ignore => "This example is not tested", - Tooltip::CompileFail => "This example deliberately fails to compile", - Tooltip::ShouldPanic => "This example panics", - Tooltip::Edition(edition) => { - edition_code = format!("This example runs with edition {edition}"); - &edition_code + format_args!( + "<a href=\"#\" class=\"tooltip\" title=\"{}\">ⓘ</a>", + match tooltip { + Tooltip::Ignore => "This example is not tested", + Tooltip::CompileFail => "This example deliberately fails to compile", + Tooltip::ShouldPanic => "This example panics", + Tooltip::Edition(edition) => { + edition_code = format!("This example runs with edition {edition}"); + &edition_code + } + Tooltip::None => unreachable!(), } - Tooltip::None => unreachable!(), - }, + ), ); } if let Some(extra) = extra_content { - out.push_buffer(extra); + out.push_str(&extra); } if class.is_empty() { - write!( + write_str( out, - "<pre class=\"rust{}{}\">", - if extra_classes.is_empty() { "" } else { " " }, - extra_classes.join(" "), + format_args!( + "<pre class=\"rust{}{}\">", + if extra_classes.is_empty() { "" } else { " " }, + extra_classes.join(" ") + ), ); } else { - write!( + write_str( out, - "<pre class=\"rust {class}{}{}\">", - if extra_classes.is_empty() { "" } else { " " }, - extra_classes.join(" "), + format_args!( + "<pre class=\"rust {class}{}{}\">", + if extra_classes.is_empty() { "" } else { " " }, + extra_classes.join(" ") + ), ); } - write!(out, "<code>"); + write_str(out, format_args!("<code>")); } /// Check if two `Class` can be merged together. In the following rules, "unclassified" means `None` @@ -150,6 +158,7 @@ struct TokenHandler<'a, 'tcx, F: Write> { /// used to generate links. pending_elems: Vec<(&'a str, Option<Class>)>, href_context: Option<HrefContext<'a, 'tcx>>, + write_line_number: fn(&mut F, u32, &'static str), } impl<F: Write> TokenHandler<'_, '_, F> { @@ -182,7 +191,14 @@ impl<F: Write> TokenHandler<'_, '_, F> { && can_merge(current_class, Some(*parent_class), "") { for (text, class) in self.pending_elems.iter() { - string(self.out, EscapeBodyText(text), *class, &self.href_context, false); + string( + self.out, + EscapeBodyText(text), + *class, + &self.href_context, + false, + self.write_line_number, + ); } } else { // We only want to "open" the tag ourselves if we have more than one pending and if the @@ -204,6 +220,7 @@ impl<F: Write> TokenHandler<'_, '_, F> { *class, &self.href_context, close_tag.is_none(), + self.write_line_number, ); } if let Some(close_tag) = close_tag { @@ -213,6 +230,11 @@ impl<F: Write> TokenHandler<'_, '_, F> { self.pending_elems.clear(); true } + + #[inline] + fn write_line_number(&mut self, line: u32, extra: &'static str) { + (self.write_line_number)(&mut self.out, line, extra); + } } impl<F: Write> Drop for TokenHandler<'_, '_, F> { @@ -226,6 +248,43 @@ impl<F: Write> Drop for TokenHandler<'_, '_, F> { } } +fn write_scraped_line_number(out: &mut impl Write, line: u32, extra: &'static str) { + // https://developers.google.com/search/docs/crawling-indexing/robots-meta-tag#data-nosnippet-attr + // Do not show "1 2 3 4 5 ..." in web search results. + write!(out, "{extra}<span data-nosnippet>{line}</span>",).unwrap(); +} + +fn write_line_number(out: &mut impl Write, line: u32, extra: &'static str) { + // https://developers.google.com/search/docs/crawling-indexing/robots-meta-tag#data-nosnippet-attr + // Do not show "1 2 3 4 5 ..." in web search results. + write!(out, "{extra}<a href=#{line} id={line} data-nosnippet>{line}</a>",).unwrap(); +} + +fn empty_line_number(out: &mut impl Write, _: u32, extra: &'static str) { + out.write_str(extra).unwrap(); +} + +#[derive(Clone, Copy)] +pub(super) struct LineInfo { + pub(super) start_line: u32, + max_lines: u32, + pub(super) is_scraped_example: bool, +} + +impl LineInfo { + pub(super) fn new(max_lines: u32) -> Self { + Self { start_line: 1, max_lines: max_lines + 1, is_scraped_example: false } + } + + pub(super) fn new_scraped(max_lines: u32, start_line: u32) -> Self { + Self { + start_line: start_line + 1, + max_lines: max_lines + start_line + 1, + is_scraped_example: true, + } + } +} + /// Convert the given `src` source code into HTML by adding classes for highlighting. /// /// This code is used to render code blocks (in the documentation) as well as the source code pages. @@ -242,6 +301,7 @@ pub(super) fn write_code( src: &str, href_context: Option<HrefContext<'_, '_>>, decoration_info: Option<&DecorationInfo>, + line_info: Option<LineInfo>, ) { // This replace allows to fix how the code source with DOS backline characters is displayed. let src = src.replace("\r\n", "\n"); @@ -252,6 +312,23 @@ pub(super) fn write_code( current_class: None, pending_elems: Vec::new(), href_context, + write_line_number: match line_info { + Some(line_info) => { + if line_info.is_scraped_example { + write_scraped_line_number + } else { + write_line_number + } + } + None => empty_line_number, + }, + }; + + let (mut line, max_lines) = if let Some(line_info) = line_info { + token_handler.write_line_number(line_info.start_line, ""); + (line_info.start_line, line_info.max_lines) + } else { + (0, u32::MAX) }; Classifier::new( @@ -282,7 +359,14 @@ pub(super) fn write_code( if need_current_class_update { token_handler.current_class = class.map(Class::dummy); } - token_handler.pending_elems.push((text, class)); + if text == "\n" { + line += 1; + if line < max_lines { + token_handler.pending_elems.push((text, Some(Class::Backline(line)))); + } + } else { + token_handler.pending_elems.push((text, class)); + } } Highlight::EnterSpan { class } => { let mut should_add = true; @@ -322,8 +406,8 @@ pub(super) fn write_code( }); } -fn write_footer(out: &mut Buffer, playground_button: Option<&str>) { - writeln!(out, "</code></pre>{}</div>", playground_button.unwrap_or_default()); +fn write_footer(out: &mut String, playground_button: Option<&str>) { + write_str(out, format_args_nl!("</code></pre>{}</div>", playground_button.unwrap_or_default())); } /// How a span of text is classified. Mostly corresponds to token kinds. @@ -348,6 +432,7 @@ enum Class { PreludeVal(Span), QuestionMark, Decoration(&'static str), + Backline(u32), } impl Class { @@ -396,6 +481,7 @@ impl Class { Class::PreludeVal(_) => "prelude-val", Class::QuestionMark => "question-mark", Class::Decoration(kind) => kind, + Class::Backline(_) => "", } } @@ -419,7 +505,8 @@ impl Class { | Self::Bool | Self::Lifetime | Self::QuestionMark - | Self::Decoration(_) => None, + | Self::Decoration(_) + | Self::Backline(_) => None, } } } @@ -694,8 +781,13 @@ impl<'src> Classifier<'src> { ) { let lookahead = self.peek(); let no_highlight = |sink: &mut dyn FnMut(_)| sink(Highlight::Token { text, class: None }); + let whitespace = |sink: &mut dyn FnMut(_)| { + for part in text.split('\n').intersperse("\n").filter(|s| !s.is_empty()) { + sink(Highlight::Token { text: part, class: None }); + } + }; let class = match token { - TokenKind::Whitespace => return no_highlight(sink), + TokenKind::Whitespace => return whitespace(sink), TokenKind::LineComment { doc_style } | TokenKind::BlockComment { doc_style, .. } => { if doc_style.is_some() { Class::DocComment @@ -716,7 +808,7 @@ impl<'src> Classifier<'src> { // or a reference or pointer type. Unless, of course, it looks like // a logical and or a multiplication operator: `&&` or `* `. TokenKind::Star => match self.tokens.peek() { - Some((TokenKind::Whitespace, _)) => return no_highlight(sink), + Some((TokenKind::Whitespace, _)) => return whitespace(sink), Some((TokenKind::Ident, "mut")) => { self.next(); sink(Highlight::Token { text: "*mut", class: Some(Class::RefKeyWord) }); @@ -740,7 +832,7 @@ impl<'src> Classifier<'src> { sink(Highlight::Token { text: "&=", class: None }); return; } - Some((TokenKind::Whitespace, _)) => return no_highlight(sink), + Some((TokenKind::Whitespace, _)) => return whitespace(sink), Some((TokenKind::Ident, "mut")) => { self.next(); sink(Highlight::Token { text: "&mut", class: Some(Class::RefKeyWord) }); @@ -887,7 +979,9 @@ impl<'src> Classifier<'src> { }; // Anything that didn't return above is the simple case where we the // class just spans a single token, so we can use the `string` method. - sink(Highlight::Token { text, class: Some(class) }); + for part in text.split('\n').intersperse("\n").filter(|s| !s.is_empty()) { + sink(Highlight::Token { text: part, class: Some(class) }); + } } fn peek(&mut self) -> Option<TokenKind> { @@ -939,14 +1033,18 @@ fn exit_span(out: &mut impl Write, closing_tag: &str) { /// Note that if `context` is not `None` and that the given `klass` contains a `Span`, the function /// will then try to find this `span` in the `span_correspondence_map`. If found, it'll then /// generate a link for this element (which corresponds to where its definition is located). -fn string<T: Display>( - out: &mut impl Write, +fn string<T: Display, W: Write>( + out: &mut W, text: T, klass: Option<Class>, href_context: &Option<HrefContext<'_, '_>>, open_tag: bool, + write_line_number_callback: fn(&mut W, u32, &'static str), ) { - if let Some(closing_tag) = string_without_closing_tag(out, text, klass, href_context, open_tag) + if let Some(Class::Backline(line)) = klass { + write_line_number_callback(out, line, "\n"); + } else if let Some(closing_tag) = + string_without_closing_tag(out, text, klass, href_context, open_tag) { out.write_str(closing_tag).unwrap(); } diff --git a/src/librustdoc/html/highlight/tests.rs b/src/librustdoc/html/highlight/tests.rs index fccbb98f80f..2603e887bea 100644 --- a/src/librustdoc/html/highlight/tests.rs +++ b/src/librustdoc/html/highlight/tests.rs @@ -3,7 +3,6 @@ use rustc_data_structures::fx::FxIndexMap; use rustc_span::create_default_session_globals_then; use super::{DecorationInfo, write_code}; -use crate::html::format::Buffer; const STYLE: &str = r#" <style> @@ -22,9 +21,9 @@ fn test_html_highlighting() { create_default_session_globals_then(|| { let src = include_str!("fixtures/sample.rs"); let html = { - let mut out = Buffer::new(); - write_code(&mut out, src, None, None); - format!("{STYLE}<pre><code>{}</code></pre>\n", out.into_inner()) + let mut out = String::new(); + write_code(&mut out, src, None, None, None); + format!("{STYLE}<pre><code>{out}</code></pre>\n") }; expect_file!["fixtures/sample.html"].assert_eq(&html); }); @@ -36,9 +35,9 @@ fn test_dos_backline() { let src = "pub fn foo() {\r\n\ println!(\"foo\");\r\n\ }\r\n"; - let mut html = Buffer::new(); - write_code(&mut html, src, None, None); - expect_file!["fixtures/dos_line.html"].assert_eq(&html.into_inner()); + let mut html = String::new(); + write_code(&mut html, src, None, None, None); + expect_file!["fixtures/dos_line.html"].assert_eq(&html); }); } @@ -50,9 +49,9 @@ use self::whatever; let x = super::b::foo; let y = Self::whatever;"; - let mut html = Buffer::new(); - write_code(&mut html, src, None, None); - expect_file!["fixtures/highlight.html"].assert_eq(&html.into_inner()); + let mut html = String::new(); + write_code(&mut html, src, None, None, None); + expect_file!["fixtures/highlight.html"].assert_eq(&html); }); } @@ -60,9 +59,9 @@ let y = Self::whatever;"; fn test_union_highlighting() { create_default_session_globals_then(|| { let src = include_str!("fixtures/union.rs"); - let mut html = Buffer::new(); - write_code(&mut html, src, None, None); - expect_file!["fixtures/union.html"].assert_eq(&html.into_inner()); + let mut html = String::new(); + write_code(&mut html, src, None, None, None); + expect_file!["fixtures/union.html"].assert_eq(&html); }); } @@ -77,8 +76,8 @@ let a = 4;"; decorations.insert("example", vec![(0, 10), (11, 21)]); decorations.insert("example2", vec![(22, 32)]); - let mut html = Buffer::new(); - write_code(&mut html, src, None, Some(&DecorationInfo(decorations))); - expect_file!["fixtures/decorations.html"].assert_eq(&html.into_inner()); + let mut html = String::new(); + write_code(&mut html, src, None, Some(&DecorationInfo(decorations)), None); + expect_file!["fixtures/decorations.html"].assert_eq(&html); }); } diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index d957cf1b569..df70df062fe 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -1,3 +1,4 @@ +use std::fmt::{self, Display}; use std::path::PathBuf; use rinja::Template; @@ -5,7 +6,6 @@ use rustc_data_structures::fx::FxIndexMap; use super::static_files::{STATIC_FILES, StaticFiles}; use crate::externalfiles::ExternalHtml; -use crate::html::format::{Buffer, Print}; use crate::html::render::{StylePath, ensure_trailing_slash}; #[derive(Clone)] @@ -71,7 +71,24 @@ struct PageLayout<'a> { pub(crate) use crate::html::render::sidebar::filters; -pub(crate) fn render<T: Print, S: Print>( +/// Implements [`Display`] for a function that accepts a mutable reference to a [`String`], and (optionally) writes to it. +/// +/// The wrapped function will receive an empty string, and can modify it, +/// and the `Display` implementation will write the contents of the string after the function has finished. +pub(crate) struct BufDisplay<F>(pub F); + +impl<F> Display for BufDisplay<F> +where + F: Fn(&mut String), +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut buf = String::new(); + self.0(&mut buf); + f.write_str(&buf) + } +} + +pub(crate) fn render<T: Display, S: Display>( layout: &Layout, page: &Page<'_>, sidebar: S, @@ -98,8 +115,8 @@ pub(crate) fn render<T: Print, S: Print>( let mut themes: Vec<String> = style_files.iter().map(|s| s.basename().unwrap()).collect(); themes.sort(); - let content = Buffer::html().to_display(t); // Note: This must happen before making the sidebar. - let sidebar = Buffer::html().to_display(sidebar); + let content = t.to_string(); // Note: This must happen before making the sidebar. + let sidebar = sidebar.to_string(); PageLayout { static_root_path, page, diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 7e835585b73..d9e49577d39 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -38,7 +38,7 @@ use std::sync::{Arc, Weak}; use pulldown_cmark::{ BrokenLink, CodeBlockKind, CowStr, Event, LinkType, Options, Parser, Tag, TagEnd, html, }; -use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; use rustc_errors::{Diag, DiagMessage}; use rustc_hir::def_id::LocalDefId; use rustc_middle::ty::TyCtxt; @@ -52,7 +52,6 @@ use crate::clean::RenderedLink; use crate::doctest; use crate::doctest::GlobalTestOptions; use crate::html::escape::{Escape, EscapeBodyText}; -use crate::html::format::Buffer; use crate::html::highlight; use crate::html::length_limit::HtmlWithLimit; use crate::html::render::small_url_encode; @@ -140,7 +139,7 @@ impl ErrorCodes { /// Controls whether a line will be hidden or shown in HTML output. /// /// All lines are used in documentation tests. -enum Line<'a> { +pub(crate) enum Line<'a> { Hidden(&'a str), Shown(Cow<'a, str>), } @@ -153,7 +152,7 @@ impl<'a> Line<'a> { } } - fn for_code(self) -> Cow<'a, str> { + pub(crate) fn for_code(self) -> Cow<'a, str> { match self { Line::Shown(l) => l, Line::Hidden(l) => Cow::Borrowed(l), @@ -161,12 +160,14 @@ impl<'a> Line<'a> { } } +/// This function is used to handle the "hidden lines" (ie starting with `#`) in +/// doctests. It also transforms `##` back into `#`. // FIXME: There is a minor inconsistency here. For lines that start with ##, we // have no easy way of removing a potential single space after the hashes, which // is done in the single # case. This inconsistency seems okay, if non-ideal. In // order to fix it we'd have to iterate to find the first non-# character, and // then reallocate to remove it; which would make us return a String. -fn map_line(s: &str) -> Line<'_> { +pub(crate) fn map_line(s: &str) -> Line<'_> { let trimmed = s.trim(); if trimmed.starts_with("##") { Line::Shown(Cow::Owned(s.replacen("##", "#", 1))) @@ -329,7 +330,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> { // insert newline to clearly separate it from the // previous block so we can shorten the html output - let mut s = Buffer::new(); + let mut s = String::new(); s.push('\n'); highlight::render_example_with_highlighting( @@ -339,7 +340,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> { playground_button.as_deref(), &added_classes, ); - Some(Event::Html(s.into_inner().into())) + Some(Event::Html(s.into())) } } @@ -1762,6 +1763,46 @@ pub(crate) fn markdown_links<'md, R>( } }; + let span_for_refdef = |link: &CowStr<'_>, span: Range<usize>| { + // We want to underline the link's definition, but `span` will point at the entire refdef. + // Skip the label, then try to find the entire URL. + let mut square_brace_count = 0; + let mut iter = md.as_bytes()[span.start..span.end].iter().copied().enumerate(); + for (_i, c) in &mut iter { + match c { + b':' if square_brace_count == 0 => break, + b'[' => square_brace_count += 1, + b']' => square_brace_count -= 1, + _ => {} + } + } + while let Some((i, c)) = iter.next() { + if c == b'<' { + while let Some((j, c)) = iter.next() { + match c { + b'\\' => { + let _ = iter.next(); + } + b'>' => { + return MarkdownLinkRange::Destination( + i + 1 + span.start..j + span.start, + ); + } + _ => {} + } + } + } else if !c.is_ascii_whitespace() { + while let Some((j, c)) = iter.next() { + if c.is_ascii_whitespace() { + return MarkdownLinkRange::Destination(i + span.start..j + span.start); + } + } + return MarkdownLinkRange::Destination(i + span.start..span.end); + } + } + span_for_link(link, span) + }; + let span_for_offset_backward = |span: Range<usize>, open: u8, close: u8| { let mut open_brace = !0; let mut close_brace = !0; @@ -1843,9 +1884,16 @@ pub(crate) fn markdown_links<'md, R>( .into_offset_iter(); let mut links = Vec::new(); + let mut refdefs = FxIndexMap::default(); + for (label, refdef) in event_iter.reference_definitions().iter() { + refdefs.insert(label.to_string(), (false, refdef.dest.to_string(), refdef.span.clone())); + } + for (event, span) in event_iter { match event { - Event::Start(Tag::Link { link_type, dest_url, .. }) if may_be_doc_link(link_type) => { + Event::Start(Tag::Link { link_type, dest_url, id, .. }) + if may_be_doc_link(link_type) => + { let range = match link_type { // Link is pulled from the link itself. LinkType::ReferenceUnknown | LinkType::ShortcutUnknown => { @@ -1855,7 +1903,12 @@ pub(crate) fn markdown_links<'md, R>( LinkType::Inline => span_for_offset_backward(span, b'(', b')'), // Link is pulled from elsewhere in the document. LinkType::Reference | LinkType::Collapsed | LinkType::Shortcut => { - span_for_link(&dest_url, span) + if let Some((is_used, dest_url, span)) = refdefs.get_mut(&id[..]) { + *is_used = true; + span_for_refdef(&CowStr::from(&dest_url[..]), span.clone()) + } else { + span_for_link(&dest_url, span) + } } LinkType::Autolink | LinkType::Email => unreachable!(), }; @@ -1872,6 +1925,18 @@ pub(crate) fn markdown_links<'md, R>( } } + for (_label, (is_used, dest_url, span)) in refdefs.into_iter() { + if !is_used + && let Some(link) = preprocess_link(MarkdownLink { + kind: LinkType::Reference, + range: span_for_refdef(&CowStr::from(&dest_url[..]), span), + link: dest_url, + }) + { + links.push(link); + } + } + links } diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index 1cefdf96bbc..146bdd34069 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -1,5 +1,6 @@ use std::cell::RefCell; use std::collections::BTreeMap; +use std::fmt::{self, Write as _}; use std::io; use std::path::{Path, PathBuf}; use std::sync::mpsc::{Receiver, channel}; @@ -26,11 +27,12 @@ use crate::formats::FormatRenderer; use crate::formats::cache::Cache; use crate::formats::item_type::ItemType; use crate::html::escape::Escape; -use crate::html::format::{Buffer, join_with_double_colon}; +use crate::html::format::join_with_double_colon; +use crate::html::layout::{self, BufDisplay}; use crate::html::markdown::{self, ErrorCodes, IdMap, plain_text_summary}; use crate::html::render::write_shared::write_shared; use crate::html::url_parts_builder::UrlPartsBuilder; -use crate::html::{layout, sources, static_files}; +use crate::html::{sources, static_files}; use crate::scrape_examples::AllCallLocations; use crate::{DOC_RUST_LANG_ORG_VERSION, try_err}; @@ -235,7 +237,7 @@ impl<'tcx> Context<'tcx> { }; if !render_redirect_pages { - let mut page_buffer = Buffer::html(); + let mut page_buffer = String::new(); print_item(self, it, &mut page_buffer); let page = layout::Page { css_class: tyname_s, @@ -249,8 +251,10 @@ impl<'tcx> Context<'tcx> { layout::render( &self.shared.layout, &page, - |buf: &mut _| print_sidebar(self, it, buf), - move |buf: &mut Buffer| buf.push_buffer(page_buffer), + BufDisplay(|buf: &mut String| { + print_sidebar(self, it, buf); + }), + page_buffer, &self.shared.style_files, ) } else { @@ -262,12 +266,12 @@ impl<'tcx> Context<'tcx> { // preventing an infinite redirection loop in the generated // documentation. - let mut path = String::new(); - for name in &names[..names.len() - 1] { - path.push_str(name.as_str()); - path.push('/'); - } - path.push_str(&item_path(ty, names.last().unwrap().as_str())); + let path = fmt::from_fn(|f| { + for name in &names[..names.len() - 1] { + write!(f, "{name}/")?; + } + write!(f, "{}", item_path(ty, names.last().unwrap().as_str())) + }); match self.shared.redirections { Some(ref redirections) => { let mut current_path = String::new(); @@ -275,8 +279,12 @@ impl<'tcx> Context<'tcx> { current_path.push_str(name.as_str()); current_path.push('/'); } - current_path.push_str(&item_path(ty, names.last().unwrap().as_str())); - redirections.borrow_mut().insert(current_path, path); + let _ = write!( + current_path, + "{}", + item_path(ty, names.last().unwrap().as_str()) + ); + redirections.borrow_mut().insert(current_path, path.to_string()); } None => { return layout::redirect(&format!( @@ -627,7 +635,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { rust_logo: has_doc_flag(self.tcx(), LOCAL_CRATE.as_def_id(), sym::rust_logo), }; let all = shared.all.replace(AllTypes::new()); - let mut sidebar = Buffer::html(); + let mut sidebar = String::new(); // all.html is not customizable, so a blank id map is fine let blocks = sidebar_module_like(all.item_sections(), &mut IdMap::new(), ModuleLike::Crate); @@ -646,8 +654,10 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { let v = layout::render( &shared.layout, &page, - sidebar.into_inner(), - |buf: &mut Buffer| all.print(buf), + sidebar, + BufDisplay(|buf: &mut String| { + all.print(buf); + }), &shared.style_files, ); shared.fs.write(final_file, v)?; @@ -665,7 +675,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { &shared.layout, &page, sidebar, - |buf: &mut Buffer| { + fmt::from_fn(|buf| { write!( buf, "<div class=\"main-heading\">\ @@ -684,7 +694,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { <script defer src=\"{static_root_path}{settings_js}\"></script>", static_root_path = page.get_static_root_path(), settings_js = static_files::STATIC_FILES.settings_js, - ); + )?; // Pre-load all theme CSS files, so that switching feels seamless. // // When loading settings.html as a popover, the equivalent HTML is @@ -697,10 +707,11 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { as=\"style\">", root_path = page.static_root_path.unwrap_or(""), suffix = page.resource_suffix, - ); + )?; } } - }, + Ok(()) + }), &shared.style_files, ); shared.fs.write(settings_file, v)?; @@ -716,25 +727,22 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { &shared.layout, &page, sidebar, - |buf: &mut Buffer| { - write!( - buf, - "<div class=\"main-heading\">\ - <h1>Rustdoc help</h1>\ - <span class=\"out-of-band\">\ - <a id=\"back\" href=\"javascript:void(0)\" onclick=\"history.back();\">\ - Back\ - </a>\ - </span>\ - </div>\ - <noscript>\ - <section>\ - <p>You need to enable JavaScript to use keyboard commands or search.</p>\ - <p>For more information, browse the <a href=\"{DOC_RUST_LANG_ORG_VERSION}/rustdoc/\">rustdoc handbook</a>.</p>\ - </section>\ - </noscript>", - ) - }, + format_args!( + "<div class=\"main-heading\">\ + <h1>Rustdoc help</h1>\ + <span class=\"out-of-band\">\ + <a id=\"back\" href=\"javascript:void(0)\" onclick=\"history.back();\">\ + Back\ + </a>\ + </span>\ + </div>\ + <noscript>\ + <section>\ + <p>You need to enable JavaScript to use keyboard commands or search.</p>\ + <p>For more information, browse the <a href=\"{DOC_RUST_LANG_ORG_VERSION}/rustdoc/\">rustdoc handbook</a>.</p>\ + </section>\ + </noscript>", + ), &shared.style_files, ); shared.fs.write(help_file, v)?; @@ -851,9 +859,9 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { if !buf.is_empty() { let name = item.name.as_ref().unwrap(); let item_type = item.type_(); - let file_name = &item_path(item_type, name.as_str()); + let file_name = item_path(item_type, name.as_str()).to_string(); self.shared.ensure_dir(&self.dst)?; - let joint_dst = self.dst.join(file_name); + let joint_dst = self.dst.join(&file_name); self.shared.fs.write(joint_dst, buf)?; if !self.info.render_redirect_pages { @@ -870,7 +878,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { format!("{crate_name}/{file_name}"), ); } else { - let v = layout::redirect(file_name); + let v = layout::redirect(&file_name); let redir_dst = self.dst.join(redir_name); self.shared.fs.write(redir_dst, v)?; } diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index f7dcb87e4f3..204631063a2 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -63,15 +63,16 @@ pub(crate) use self::context::*; pub(crate) use self::span_map::{LinkFromSrc, collect_spans_and_sources}; pub(crate) use self::write_shared::*; use crate::clean::{self, ItemId, RenderedLink}; +use crate::display::{Joined as _, MaybeDisplay as _}; use crate::error::Error; use crate::formats::Impl; use crate::formats::cache::Cache; use crate::formats::item_type::ItemType; use crate::html::escape::Escape; use crate::html::format::{ - Buffer, Ending, HrefError, PrintWithSpace, href, join_with_double_colon, print_abi_with_space, + Ending, HrefError, PrintWithSpace, href, join_with_double_colon, print_abi_with_space, print_constness_with_space, print_default_space, print_generic_bounds, print_where_clause, - visibility_print_with_space, + visibility_print_with_space, write_str, }; use crate::html::markdown::{ HeadingOffset, IdMap, Markdown, MarkdownItemInfo, MarkdownSummaryLine, @@ -436,27 +437,29 @@ impl AllTypes { sections } - fn print(self, f: &mut Buffer) { - fn print_entries(f: &mut Buffer, e: &FxIndexSet<ItemEntry>, kind: ItemSection) { + fn print(&self, f: &mut String) { + fn print_entries(f: &mut String, e: &FxIndexSet<ItemEntry>, kind: ItemSection) { if !e.is_empty() { let mut e: Vec<&ItemEntry> = e.iter().collect(); e.sort(); - write!( + write_str( f, - "<h3 id=\"{id}\">{title}</h3><ul class=\"all-items\">", - id = kind.id(), - title = kind.name(), + format_args!( + "<h3 id=\"{id}\">{title}</h3><ul class=\"all-items\">", + id = kind.id(), + title = kind.name(), + ), ); for s in e.iter() { - write!(f, "<li>{}</li>", s.print()); + write_str(f, format_args!("<li>{}</li>", s.print())); } - f.write_str("</ul>"); + f.push_str("</ul>"); } } - f.write_str("<h1>List of all items</h1>"); + f.push_str("<h1>List of all items</h1>"); // Note: print_entries does not escape the title, because we know the current set of titles // doesn't require escaping. print_entries(f, &self.structs, ItemSection::Structs); @@ -566,17 +569,27 @@ fn document_short<'a, 'cx: 'a>( let (mut summary_html, has_more_content) = MarkdownSummaryLine(&s, &item.links(cx)).into_string_with_has_more_content(); - if has_more_content { - let link = format!(" <a{}>Read more</a>", assoc_href_attr(item, link, cx)); + let link = if has_more_content { + let link = fmt::from_fn(|f| { + write!( + f, + " <a{}>Read more</a>", + assoc_href_attr(item, link, cx).maybe_display() + ) + }); if let Some(idx) = summary_html.rfind("</p>") { - summary_html.insert_str(idx, &link); + summary_html.insert_str(idx, &link.to_string()); + None } else { - summary_html.push_str(&link); + Some(link) } + } else { + None } + .maybe_display(); - write!(f, "<div class='docblock'>{summary_html}</div>")?; + write!(f, "<div class='docblock'>{summary_html}{link}</div>")?; } Ok(()) }) @@ -761,7 +774,7 @@ pub(crate) fn render_impls( let did = i.trait_did().unwrap(); let provided_trait_methods = i.inner_impl().provided_trait_methods(cx.tcx()); let assoc_link = AssocItemLink::GotoSource(did.into(), &provided_trait_methods); - let mut buffer = Buffer::new(); + let mut buffer = String::new(); render_impl( &mut buffer, cx, @@ -778,7 +791,7 @@ pub(crate) fn render_impls( toggle_open_by_default, }, ); - buffer.into_inner() + buffer }) .collect::<Vec<_>>(); rendered_impls.sort(); @@ -786,13 +799,23 @@ pub(crate) fn render_impls( } /// Build a (possibly empty) `href` attribute (a key-value pair) for the given associated item. -fn assoc_href_attr(it: &clean::Item, link: AssocItemLink<'_>, cx: &Context<'_>) -> String { +fn assoc_href_attr<'a, 'tcx>( + it: &clean::Item, + link: AssocItemLink<'a>, + cx: &Context<'tcx>, +) -> Option<impl fmt::Display + 'a + Captures<'tcx>> { let name = it.name.unwrap(); let item_type = it.type_(); + enum Href<'a> { + AnchorId(&'a str), + Anchor(ItemType), + Url(String, ItemType), + } + let href = match link { - AssocItemLink::Anchor(Some(ref id)) => Some(format!("#{id}")), - AssocItemLink::Anchor(None) => Some(format!("#{item_type}.{name}")), + AssocItemLink::Anchor(Some(ref id)) => Href::AnchorId(id), + AssocItemLink::Anchor(None) => Href::Anchor(item_type), AssocItemLink::GotoSource(did, provided_methods) => { // We're creating a link from the implementation of an associated item to its // declaration in the trait declaration. @@ -812,7 +835,7 @@ fn assoc_href_attr(it: &clean::Item, link: AssocItemLink<'_>, cx: &Context<'_>) }; match href(did.expect_def_id(), cx) { - Ok((url, ..)) => Some(format!("{url}#{item_type}.{name}")), + Ok((url, ..)) => Href::Url(url, item_type), // The link is broken since it points to an external crate that wasn't documented. // Do not create any link in such case. This is better than falling back to a // dummy anchor like `#{item_type}.{name}` representing the `id` of *this* impl item @@ -824,15 +847,25 @@ fn assoc_href_attr(it: &clean::Item, link: AssocItemLink<'_>, cx: &Context<'_>) // those two items are distinct! // In this scenario, the actual `id` of this impl item would be // `#{item_type}.{name}-{n}` for some number `n` (a disambiguator). - Err(HrefError::DocumentationNotBuilt) => None, - Err(_) => Some(format!("#{item_type}.{name}")), + Err(HrefError::DocumentationNotBuilt) => return None, + Err(_) => Href::Anchor(item_type), } } }; + let href = fmt::from_fn(move |f| match &href { + Href::AnchorId(id) => write!(f, "#{id}"), + Href::Url(url, item_type) => { + write!(f, "{url}#{item_type}.{name}") + } + Href::Anchor(item_type) => { + write!(f, "#{item_type}.{name}") + } + }); + // If there is no `href` for the reason explained above, simply do not render it which is valid: // https://html.spec.whatwg.org/multipage/links.html#links-created-by-a-and-area-elements - href.map(|href| format!(" href=\"{href}\"")).unwrap_or_default() + Some(fmt::from_fn(move |f| write!(f, " href=\"{href}\""))) } #[derive(Debug)] @@ -847,7 +880,7 @@ enum AssocConstValue<'a> { } fn assoc_const( - w: &mut Buffer, + w: &mut String, it: &clean::Item, generics: &clean::Generics, ty: &clean::Type, @@ -857,15 +890,17 @@ fn assoc_const( cx: &Context<'_>, ) { let tcx = cx.tcx(); - write!( + write_str( w, - "{indent}{vis}const <a{href} class=\"constant\">{name}</a>{generics}: {ty}", - indent = " ".repeat(indent), - vis = visibility_print_with_space(it, cx), - href = assoc_href_attr(it, link, cx), - name = it.name.as_ref().unwrap(), - generics = generics.print(cx), - ty = ty.print(cx), + format_args!( + "{indent}{vis}const <a{href} class=\"constant\">{name}</a>{generics}: {ty}", + indent = " ".repeat(indent), + vis = visibility_print_with_space(it, cx), + href = assoc_href_attr(it, link, cx).maybe_display(), + name = it.name.as_ref().unwrap(), + generics = generics.print(cx), + ty = ty.print(cx), + ), ); if let AssocConstValue::TraitDefault(konst) | AssocConstValue::Impl(konst) = value { // FIXME: `.value()` uses `clean::utils::format_integer_with_underscore_sep` under the @@ -879,14 +914,14 @@ fn assoc_const( AssocConstValue::Impl(_) => repr != "_", // show if there is a meaningful value to show AssocConstValue::None => unreachable!(), } { - write!(w, " = {}", Escape(&repr)); + write_str(w, format_args!(" = {}", Escape(&repr))); } } - write!(w, "{}", print_where_clause(generics, cx, indent, Ending::NoNewline)); + write_str(w, format_args!("{}", print_where_clause(generics, cx, indent, Ending::NoNewline))); } fn assoc_type( - w: &mut Buffer, + w: &mut String, it: &clean::Item, generics: &clean::Generics, bounds: &[clean::GenericBound], @@ -895,27 +930,29 @@ fn assoc_type( indent: usize, cx: &Context<'_>, ) { - write!( + write_str( w, - "{indent}{vis}type <a{href} class=\"associatedtype\">{name}</a>{generics}", - indent = " ".repeat(indent), - vis = visibility_print_with_space(it, cx), - href = assoc_href_attr(it, link, cx), - name = it.name.as_ref().unwrap(), - generics = generics.print(cx), + format_args!( + "{indent}{vis}type <a{href} class=\"associatedtype\">{name}</a>{generics}", + indent = " ".repeat(indent), + vis = visibility_print_with_space(it, cx), + href = assoc_href_attr(it, link, cx).maybe_display(), + name = it.name.as_ref().unwrap(), + generics = generics.print(cx), + ), ); if !bounds.is_empty() { - write!(w, ": {}", print_generic_bounds(bounds, cx)) + write_str(w, format_args!(": {}", print_generic_bounds(bounds, cx))); } // Render the default before the where-clause which aligns with the new recommended style. See #89122. if let Some(default) = default { - write!(w, " = {}", default.print(cx)) + write_str(w, format_args!(" = {}", default.print(cx))); } - write!(w, "{}", print_where_clause(generics, cx, indent, Ending::NoNewline)); + write_str(w, format_args!("{}", print_where_clause(generics, cx, indent, Ending::NoNewline))); } fn assoc_method( - w: &mut Buffer, + w: &mut String, meth: &clean::Item, g: &clean::Generics, d: &clean::FnDecl, @@ -942,7 +979,7 @@ fn assoc_method( let asyncness = header.asyncness.print_with_space(); let safety = header.safety.print_with_space(); let abi = print_abi_with_space(header.abi).to_string(); - let href = assoc_href_attr(meth, link, cx); + let href = assoc_href_attr(meth, link, cx).maybe_display(); // NOTE: `{:#}` does not print HTML formatting, `{}` does. So `g.print` can't be reused between the length calculation and `write!`. let generics_len = format!("{:#}", g.print(cx)).len(); @@ -956,35 +993,36 @@ fn assoc_method( + name.as_str().len() + generics_len; - let notable_traits = notable_traits_button(&d.output, cx); + let notable_traits = notable_traits_button(&d.output, cx).maybe_display(); let (indent, indent_str, end_newline) = if parent == ItemType::Trait { header_len += 4; let indent_str = " "; - write!(w, "{}", render_attributes_in_pre(meth, indent_str, cx)); + write_str(w, format_args!("{}", render_attributes_in_pre(meth, indent_str, cx))); (4, indent_str, Ending::NoNewline) } else { render_attributes_in_code(w, meth, cx); (0, "", Ending::Newline) }; w.reserve(header_len + "<a href=\"\" class=\"fn\">{".len() + "</a>".len()); - write!( + write_str( w, - "{indent}{vis}{defaultness}{constness}{asyncness}{safety}{abi}fn \ + format_args!( + "{indent}{vis}{defaultness}{constness}{asyncness}{safety}{abi}fn \ <a{href} class=\"fn\">{name}</a>{generics}{decl}{notable_traits}{where_clause}", - indent = indent_str, - vis = vis, - defaultness = defaultness, - constness = constness, - asyncness = asyncness, - safety = safety, - abi = abi, - href = href, - name = name, - generics = g.print(cx), - decl = d.full_print(header_len, indent, cx), - notable_traits = notable_traits.unwrap_or_default(), - where_clause = print_where_clause(g, cx, indent, end_newline), + indent = indent_str, + vis = vis, + defaultness = defaultness, + constness = constness, + asyncness = asyncness, + safety = safety, + abi = abi, + href = href, + name = name, + generics = g.print(cx), + decl = d.full_print(header_len, indent, cx), + where_clause = print_where_clause(g, cx, indent, end_newline), + ), ); } @@ -1003,7 +1041,7 @@ fn assoc_method( /// will include the const-stable version, but no stable version will be emitted, as a natural /// consequence of the above rules. fn render_stability_since_raw_with_extra( - w: &mut Buffer, + w: &mut String, stable_version: Option<StableSince>, const_stability: Option<ConstStability>, extra_class: &str, @@ -1058,7 +1096,10 @@ fn render_stability_since_raw_with_extra( } if !stability.is_empty() { - write!(w, r#"<span class="since{extra_class}" title="{title}">{stability}</span>"#); + write_str( + w, + format_args!(r#"<span class="since{extra_class}" title="{title}">{stability}</span>"#), + ); } !stability.is_empty() @@ -1074,7 +1115,7 @@ fn since_to_string(since: &StableSince) -> Option<String> { #[inline] fn render_stability_since_raw( - w: &mut Buffer, + w: &mut String, ver: Option<StableSince>, const_stability: Option<ConstStability>, ) -> bool { @@ -1082,7 +1123,7 @@ fn render_stability_since_raw( } fn render_assoc_item( - w: &mut Buffer, + w: &mut String, item: &clean::Item, link: AssocItemLink<'_>, parent: ItemType, @@ -1222,9 +1263,11 @@ pub(crate) fn render_all_impls( synthetic: &[&Impl], blanket_impl: &[&Impl], ) { - let mut impls = Buffer::html(); - render_impls(cx, &mut impls, concrete, containing_item, true); - let impls = impls.into_inner(); + let impls = { + let mut buf = String::new(); + render_impls(cx, &mut buf, concrete, containing_item, true); + buf + }; if !impls.is_empty() { write_impl_section_heading(&mut w, "Trait Implementations", "trait-implementations"); write!(w, "<div id=\"trait-implementations-list\">{impls}</div>").unwrap(); @@ -1277,7 +1320,7 @@ fn render_assoc_items_inner( let (non_trait, traits): (Vec<_>, _) = v.iter().partition(|i| i.inner_impl().trait_.is_none()); if !non_trait.is_empty() { let mut close_tags = <Vec<&str>>::with_capacity(1); - let mut tmp_buf = Buffer::html(); + let mut tmp_buf = String::new(); let (render_mode, id, class_html) = match what { AssocItemRender::All => { write_impl_section_heading(&mut tmp_buf, "Implementations", "implementations"); @@ -1287,7 +1330,7 @@ fn render_assoc_items_inner( let id = cx.derive_id(small_url_encode(format!("deref-methods-{:#}", type_.print(cx)))); let derived_id = cx.derive_id(&id); - tmp_buf.write_str("<details class=\"toggle big-toggle\" open><summary>"); + tmp_buf.push_str("<details class=\"toggle big-toggle\" open><summary>"); close_tags.push("</details>"); write_impl_section_heading( &mut tmp_buf, @@ -1298,14 +1341,14 @@ fn render_assoc_items_inner( ), &id, ); - tmp_buf.write_str("</summary>"); + tmp_buf.push_str("</summary>"); if let Some(def_id) = type_.def_id(cx.cache()) { cx.deref_id_map.borrow_mut().insert(def_id, id); } (RenderMode::ForDeref { mut_: deref_mut_ }, derived_id, r#" class="impl-items""#) } }; - let mut impls_buf = Buffer::html(); + let mut impls_buf = String::new(); for i in &non_trait { render_impl( &mut impls_buf, @@ -1325,13 +1368,7 @@ fn render_assoc_items_inner( ); } if !impls_buf.is_empty() { - write!( - w, - "{}<div id=\"{id}\"{class_html}>{}</div>", - tmp_buf.into_inner(), - impls_buf.into_inner() - ) - .unwrap(); + write!(w, "{tmp_buf}<div id=\"{id}\"{class_html}>{impls_buf}</div>").unwrap(); for tag in close_tags.into_iter().rev() { w.write_str(tag).unwrap(); } @@ -1431,7 +1468,10 @@ fn should_render_item(item: &clean::Item, deref_mut_: bool, tcx: TyCtxt<'_>) -> } } -pub(crate) fn notable_traits_button(ty: &clean::Type, cx: &Context<'_>) -> Option<String> { +pub(crate) fn notable_traits_button<'a, 'tcx>( + ty: &'a clean::Type, + cx: &'a Context<'tcx>, +) -> Option<impl fmt::Display + 'a + Captures<'tcx>> { let mut has_notable_trait = false; if ty.is_unit() { @@ -1473,19 +1513,20 @@ pub(crate) fn notable_traits_button(ty: &clean::Type, cx: &Context<'_>) -> Optio } } - if has_notable_trait { + has_notable_trait.then(|| { cx.types_with_notable_traits.borrow_mut().insert(ty.clone()); - Some(format!( - " <a href=\"#\" class=\"tooltip\" data-notable-ty=\"{ty}\">ⓘ</a>", - ty = Escape(&format!("{:#}", ty.print(cx))), - )) - } else { - None - } + fmt::from_fn(|f| { + write!( + f, + " <a href=\"#\" class=\"tooltip\" data-notable-ty=\"{ty}\">ⓘ</a>", + ty = Escape(&format!("{:#}", ty.print(cx))), + ) + }) + }) } fn notable_traits_decl(ty: &clean::Type, cx: &Context<'_>) -> (String, String) { - let mut out = Buffer::html(); + let mut out = String::new(); let did = ty.def_id(cx.cache()).expect("notable_traits_button already checked this"); @@ -1507,15 +1548,20 @@ fn notable_traits_decl(ty: &clean::Type, cx: &Context<'_>) -> (String, String) { if cx.cache().traits.get(&trait_did).is_some_and(|t| t.is_notable_trait(cx.tcx())) { if out.is_empty() { - write!( + write_str( &mut out, - "<h3>Notable traits for <code>{}</code></h3>\ - <pre><code>", - impl_.for_.print(cx) + format_args!( + "<h3>Notable traits for <code>{}</code></h3>\ + <pre><code>", + impl_.for_.print(cx) + ), ); } - write!(&mut out, "<div class=\"where\">{}</div>", impl_.print(false, cx)); + write_str( + &mut out, + format_args!("<div class=\"where\">{}</div>", impl_.print(false, cx)), + ); for it in &impl_.items { if let clean::AssocTypeItem(ref tydef, ref _bounds) = it.kind { out.push_str("<div class=\"where\"> "); @@ -1538,10 +1584,10 @@ fn notable_traits_decl(ty: &clean::Type, cx: &Context<'_>) -> (String, String) { } } if out.is_empty() { - out.write_str("</code></pre>"); + out.push_str("</code></pre>"); } - (format!("{:#}", ty.print(cx)), out.into_inner()) + (format!("{:#}", ty.print(cx)), out) } pub(crate) fn notable_traits_json<'a>( @@ -1577,7 +1623,7 @@ struct ImplRenderingParameters { } fn render_impl( - w: &mut Buffer, + w: &mut String, cx: &Context<'_>, i: &Impl, parent: &clean::Item, @@ -1598,8 +1644,8 @@ fn render_impl( // `containing_item` is used for rendering stability info. If the parent is a trait impl, // `containing_item` will the grandparent, since trait impls can't have stability attached. fn doc_impl_item( - boring: &mut Buffer, - interesting: &mut Buffer, + boring: &mut String, + interesting: &mut String, cx: &Context<'_>, item: &clean::Item, parent: &clean::Item, @@ -1622,8 +1668,8 @@ fn render_impl( let in_trait_class = if trait_.is_some() { " trait-impl" } else { "" }; - let mut doc_buffer = Buffer::empty_from(boring); - let mut info_buffer = Buffer::empty_from(boring); + let mut doc_buffer = String::new(); + let mut info_buffer = String::new(); let mut short_documented = true; if render_method_item { @@ -1638,25 +1684,26 @@ fn render_impl( document_item_info(cx, it, Some(parent)) .render_into(&mut info_buffer) .unwrap(); - write!( + write_str( &mut doc_buffer, - "{}", - document_full(item, cx, HeadingOffset::H5) + format_args!("{}", document_full(item, cx, HeadingOffset::H5)), ); short_documented = false; } else { // In case the item isn't documented, // provide short documentation from the trait. - write!( + write_str( &mut doc_buffer, - "{}", - document_short( - it, - cx, - link, - parent, - rendering_params.show_def_docs, - ) + format_args!( + "{}", + document_short( + it, + cx, + link, + parent, + rendering_params.show_def_docs, + ) + ), ); } } @@ -1665,15 +1712,20 @@ fn render_impl( .render_into(&mut info_buffer) .unwrap(); if rendering_params.show_def_docs { - write!(&mut doc_buffer, "{}", document_full(item, cx, HeadingOffset::H5)); + write_str( + &mut doc_buffer, + format_args!("{}", document_full(item, cx, HeadingOffset::H5)), + ); short_documented = false; } } } else { - write!( + write_str( &mut doc_buffer, - "{}", - document_short(item, cx, link, parent, rendering_params.show_def_docs) + format_args!( + "{}", + document_short(item, cx, link, parent, rendering_params.show_def_docs) + ), ); } } @@ -1682,7 +1734,10 @@ fn render_impl( let toggled = !doc_buffer.is_empty(); if toggled { let method_toggle_class = if item_type.is_method() { " method-toggle" } else { "" }; - write!(w, "<details class=\"toggle{method_toggle_class}\" open><summary>"); + write_str( + w, + format_args!("<details class=\"toggle{method_toggle_class}\" open><summary>"), + ); } match &item.kind { clean::MethodItem(..) | clean::RequiredMethodItem(_) => { @@ -1697,13 +1752,16 @@ fn render_impl( .find(|item| item.name.map(|n| n == *name).unwrap_or(false)) }) .map(|item| format!("{}.{name}", item.type_())); - write!(w, "<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">"); + write_str( + w, + format_args!("<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">"), + ); render_rightside(w, cx, item, render_mode); if trait_.is_some() { // Anchors are only used on trait impls. - write!(w, "<a href=\"#{id}\" class=\"anchor\">§</a>"); + write_str(w, format_args!("<a href=\"#{id}\" class=\"anchor\">§</a>")); } - w.write_str("<h4 class=\"code-header\">"); + w.push_str("<h4 class=\"code-header\">"); render_assoc_item( w, item, @@ -1712,19 +1770,22 @@ fn render_impl( cx, render_mode, ); - w.write_str("</h4></section>"); + w.push_str("</h4></section>"); } } clean::RequiredAssocConstItem(ref generics, ref ty) => { let source_id = format!("{item_type}.{name}"); let id = cx.derive_id(&source_id); - write!(w, "<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">"); + write_str( + w, + format_args!("<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">"), + ); render_rightside(w, cx, item, render_mode); if trait_.is_some() { // Anchors are only used on trait impls. - write!(w, "<a href=\"#{id}\" class=\"anchor\">§</a>"); + write_str(w, format_args!("<a href=\"#{id}\" class=\"anchor\">§</a>")); } - w.write_str("<h4 class=\"code-header\">"); + w.push_str("<h4 class=\"code-header\">"); assoc_const( w, item, @@ -1735,18 +1796,21 @@ fn render_impl( 0, cx, ); - w.write_str("</h4></section>"); + w.push_str("</h4></section>"); } clean::ProvidedAssocConstItem(ci) | clean::ImplAssocConstItem(ci) => { let source_id = format!("{item_type}.{name}"); let id = cx.derive_id(&source_id); - write!(w, "<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">"); + write_str( + w, + format_args!("<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">"), + ); render_rightside(w, cx, item, render_mode); if trait_.is_some() { // Anchors are only used on trait impls. - write!(w, "<a href=\"#{id}\" class=\"anchor\">§</a>"); + write_str(w, format_args!("<a href=\"#{id}\" class=\"anchor\">§</a>")); } - w.write_str("<h4 class=\"code-header\">"); + w.push_str("<h4 class=\"code-header\">"); assoc_const( w, item, @@ -1761,18 +1825,21 @@ fn render_impl( 0, cx, ); - w.write_str("</h4></section>"); + w.push_str("</h4></section>"); } clean::RequiredAssocTypeItem(ref generics, ref bounds) => { let source_id = format!("{item_type}.{name}"); let id = cx.derive_id(&source_id); - write!(w, "<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">"); + write_str( + w, + format_args!("<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">"), + ); render_rightside(w, cx, item, render_mode); if trait_.is_some() { // Anchors are only used on trait impls. - write!(w, "<a href=\"#{id}\" class=\"anchor\">§</a>"); + write_str(w, format_args!("<a href=\"#{id}\" class=\"anchor\">§</a>")); } - w.write_str("<h4 class=\"code-header\">"); + w.push_str("<h4 class=\"code-header\">"); assoc_type( w, item, @@ -1783,18 +1850,21 @@ fn render_impl( 0, cx, ); - w.write_str("</h4></section>"); + w.push_str("</h4></section>"); } clean::AssocTypeItem(tydef, _bounds) => { let source_id = format!("{item_type}.{name}"); let id = cx.derive_id(&source_id); - write!(w, "<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">"); + write_str( + w, + format_args!("<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">"), + ); render_rightside(w, cx, item, render_mode); if trait_.is_some() { // Anchors are only used on trait impls. - write!(w, "<a href=\"#{id}\" class=\"anchor\">§</a>"); + write_str(w, format_args!("<a href=\"#{id}\" class=\"anchor\">§</a>")); } - w.write_str("<h4 class=\"code-header\">"); + w.push_str("<h4 class=\"code-header\">"); assoc_type( w, item, @@ -1805,22 +1875,22 @@ fn render_impl( 0, cx, ); - w.write_str("</h4></section>"); + w.push_str("</h4></section>"); } clean::StrippedItem(..) => return, _ => panic!("can't make docs for trait item with name {:?}", item.name), } - w.push_buffer(info_buffer); + w.push_str(&info_buffer); if toggled { - w.write_str("</summary>"); - w.push_buffer(doc_buffer); + w.push_str("</summary>"); + w.push_str(&doc_buffer); w.push_str("</details>"); } } - let mut impl_items = Buffer::empty_from(w); - let mut default_impl_items = Buffer::empty_from(w); + let mut impl_items = String::new(); + let mut default_impl_items = String::new(); let impl_ = i.inner_impl(); // Impl items are grouped by kinds: @@ -1894,8 +1964,8 @@ fn render_impl( } fn render_default_items( - boring: &mut Buffer, - interesting: &mut Buffer, + boring: &mut String, + interesting: &mut String, cx: &Context<'_>, t: &clean::Trait, i: &clean::Impl, @@ -1960,11 +2030,13 @@ fn render_impl( let toggled = !(impl_items.is_empty() && default_impl_items.is_empty()); if toggled { close_tags.push("</details>"); - write!( + write_str( w, - "<details class=\"toggle implementors-toggle\"{}>\ - <summary>", - if rendering_params.toggle_open_by_default { " open" } else { "" } + format_args!( + "<details class=\"toggle implementors-toggle\"{}>\ + <summary>", + if rendering_params.toggle_open_by_default { " open" } else { "" } + ), ); } @@ -1995,38 +2067,38 @@ fn render_impl( &before_dox, ); if toggled { - w.write_str("</summary>"); + w.push_str("</summary>"); } if before_dox.is_some() { if trait_.is_none() && impl_.items.is_empty() { - w.write_str( + w.push_str( "<div class=\"item-info\">\ <div class=\"stab empty-impl\">This impl block contains no items.</div>\ </div>", ); } if let Some(after_dox) = after_dox { - write!(w, "<div class=\"docblock\">{after_dox}</div>"); + write_str(w, format_args!("<div class=\"docblock\">{after_dox}</div>")); } } if !default_impl_items.is_empty() || !impl_items.is_empty() { - w.write_str("<div class=\"impl-items\">"); + w.push_str("<div class=\"impl-items\">"); close_tags.push("</div>"); } } if !default_impl_items.is_empty() || !impl_items.is_empty() { - w.push_buffer(default_impl_items); - w.push_buffer(impl_items); + w.push_str(&default_impl_items); + w.push_str(&impl_items); } for tag in close_tags.into_iter().rev() { - w.write_str(tag); + w.push_str(tag); } } // Render the items that appear on the right side of methods, impls, and // associated types. For example "1.0.0 (const: 1.39.0) · source". -fn render_rightside(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, render_mode: RenderMode) { +fn render_rightside(w: &mut String, cx: &Context<'_>, item: &clean::Item, render_mode: RenderMode) { let tcx = cx.tcx(); // FIXME: Once https://github.com/rust-lang/rust/issues/67792 is implemented, we can remove @@ -2038,7 +2110,7 @@ fn render_rightside(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, render let src_href = cx.src_href(item); let has_src_ref = src_href.is_some(); - let mut rightside = Buffer::new(); + let mut rightside = String::new(); let has_stability = render_stability_since_raw_with_extra( &mut rightside, item.stable_since(tcx), @@ -2047,20 +2119,26 @@ fn render_rightside(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, render ); if let Some(link) = src_href { if has_stability { - write!(rightside, " · <a class=\"src\" href=\"{link}\">Source</a>") + write_str( + &mut rightside, + format_args!(" · <a class=\"src\" href=\"{link}\">Source</a>"), + ); } else { - write!(rightside, "<a class=\"src rightside\" href=\"{link}\">Source</a>") + write_str( + &mut rightside, + format_args!("<a class=\"src rightside\" href=\"{link}\">Source</a>"), + ); } } if has_stability && has_src_ref { - write!(w, "<span class=\"rightside\">{}</span>", rightside.into_inner()); + write_str(w, format_args!("<span class=\"rightside\">{rightside}</span>")); } else { - w.push_buffer(rightside); + w.push_str(&rightside); } } pub(crate) fn render_impl_summary( - w: &mut Buffer, + w: &mut String, cx: &Context<'_>, i: &Impl, parent: &clean::Item, @@ -2073,25 +2151,27 @@ pub(crate) fn render_impl_summary( ) { let inner_impl = i.inner_impl(); let id = cx.derive_id(get_id_for_impl(cx.tcx(), i.impl_item.item_id)); - let aliases = if aliases.is_empty() { - String::new() - } else { - format!(" data-aliases=\"{}\"", aliases.join(",")) - }; - write!(w, "<section id=\"{id}\" class=\"impl\"{aliases}>"); + let aliases = (!aliases.is_empty()) + .then_some(fmt::from_fn(|f| { + write!(f, " data-aliases=\"{}\"", fmt::from_fn(|f| aliases.iter().joined(",", f))) + })) + .maybe_display(); + write_str(w, format_args!("<section id=\"{id}\" class=\"impl\"{aliases}>")); render_rightside(w, cx, &i.impl_item, RenderMode::Normal); - write!( + write_str( w, - "<a href=\"#{id}\" class=\"anchor\">§</a>\ - <h3 class=\"code-header\">" + format_args!( + "<a href=\"#{id}\" class=\"anchor\">§</a>\ + <h3 class=\"code-header\">" + ), ); if let Some(use_absolute) = use_absolute { - write!(w, "{}", inner_impl.print(use_absolute, cx)); + write_str(w, format_args!("{}", inner_impl.print(use_absolute, cx))); if show_def_docs { for it in &inner_impl.items { if let clean::AssocTypeItem(ref tydef, ref _bounds) = it.kind { - w.write_str("<div class=\"where\"> "); + w.push_str("<div class=\"where\"> "); assoc_type( w, it, @@ -2102,30 +2182,32 @@ pub(crate) fn render_impl_summary( 0, cx, ); - w.write_str(";</div>"); + w.push_str(";</div>"); } } } } else { - write!(w, "{}", inner_impl.print(false, cx)); + write_str(w, format_args!("{}", inner_impl.print(false, cx))); } - w.write_str("</h3>"); + w.push_str("</h3>"); let is_trait = inner_impl.trait_.is_some(); if is_trait && let Some(portability) = portability(&i.impl_item, Some(parent)) { - write!( + write_str( w, - "<span class=\"item-info\">\ + format_args!( + "<span class=\"item-info\">\ <div class=\"stab portability\">{portability}</div>\ </span>", + ), ); } if let Some(doc) = doc { - write!(w, "<div class=\"docblock\">{doc}</div>"); + write_str(w, format_args!("<div class=\"docblock\">{doc}</div>")); } - w.write_str("</section>"); + w.push_str("</section>"); } pub(crate) fn small_url_encode(s: String) -> String { @@ -2577,7 +2659,7 @@ fn render_call_locations<W: fmt::Write>(mut w: W, cx: &Context<'_>, item: &clean cx, &cx.root_path(), &highlight::DecorationInfo(decoration_info), - sources::SourceContext::Embedded(sources::ScrapedInfo { + &sources::SourceContext::Embedded(sources::ScrapedInfo { needs_expansion, offset: line_min, name: &call_data.display_name, diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 4f51b7a0108..d2d7415261b 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -1,6 +1,6 @@ use std::cmp::Ordering; use std::fmt; -use std::fmt::{Display, Write}; +use std::fmt::Display; use itertools::Itertools; use rinja::Template; @@ -27,17 +27,17 @@ use super::{ }; use crate::clean; use crate::config::ModuleSorting; +use crate::display::{Joined as _, MaybeDisplay as _}; use crate::formats::Impl; use crate::formats::item_type::ItemType; use crate::html::escape::{Escape, EscapeBodyTextWithWbr}; use crate::html::format::{ - Buffer, Ending, PrintWithSpace, join_with_double_colon, print_abi_with_space, - print_constness_with_space, print_where_clause, visibility_print_with_space, + Ending, PrintWithSpace, join_with_double_colon, print_abi_with_space, + print_constness_with_space, print_where_clause, visibility_print_with_space, write_str, }; use crate::html::markdown::{HeadingOffset, MarkdownSummaryLine}; use crate::html::render::{document_full, document_item_info}; use crate::html::url_parts_builder::UrlPartsBuilder; -use crate::joined::Joined as _; /// Generates a Rinja template struct for rendering items with common methods. /// @@ -165,16 +165,16 @@ struct ItemVars<'a> { /// Calls `print_where_clause` and returns `true` if a `where` clause was generated. fn print_where_clause_and_check<'a, 'tcx: 'a>( - buffer: &mut Buffer, + buffer: &mut String, gens: &'a clean::Generics, cx: &'a Context<'tcx>, ) -> bool { let len_before = buffer.len(); - write!(buffer, "{}", print_where_clause(gens, cx, 0, Ending::Newline)); + write_str(buffer, format_args!("{}", print_where_clause(gens, cx, 0, Ending::Newline))); len_before != buffer.len() } -pub(super) fn print_item(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer) { +pub(super) fn print_item(cx: &Context<'_>, item: &clean::Item, buf: &mut String) { debug_assert!(!item.is_stripped()); let typ = match item.kind { clean::ModuleItem(_) => { @@ -207,13 +207,15 @@ pub(super) fn print_item(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer) unreachable!(); } }; - let mut stability_since_raw = Buffer::new(); - render_stability_since_raw( - &mut stability_since_raw, - item.stable_since(cx.tcx()), - item.const_stability(cx.tcx()), - ); - let stability_since_raw: String = stability_since_raw.into_inner(); + let stability_since_raw = { + let mut buf = String::new(); + render_stability_since_raw( + &mut buf, + item.stable_since(cx.tcx()), + item.const_stability(cx.tcx()), + ); + buf + }; // Write source tag // @@ -278,10 +280,12 @@ pub(super) fn print_item(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer) // Render notable-traits.js used for all methods in this module. let mut types_with_notable_traits = cx.types_with_notable_traits.borrow_mut(); if !types_with_notable_traits.is_empty() { - write!( + write_str( buf, - r#"<script type="text/json" id="notable-traits-data">{}</script>"#, - notable_traits_json(types_with_notable_traits.iter(), cx) + format_args!( + r#"<script type="text/json" id="notable-traits-data">{}</script>"#, + notable_traits_json(types_with_notable_traits.iter(), cx) + ), ); types_with_notable_traits.clear(); } @@ -311,8 +315,8 @@ trait ItemTemplate<'a, 'cx: 'a>: rinja::Template + Display { fn item_and_cx(&self) -> (&'a clean::Item, &'a Context<'cx>); } -fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) { - write!(w, "{}", document(cx, item, None, HeadingOffset::H2)); +fn item_module(w: &mut String, cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) { + write_str(w, format_args!("{}", document(cx, item, None, HeadingOffset::H2))); let mut not_stripped_items = items.iter().filter(|i| !i.is_stripped()).enumerate().collect::<Vec<_>>(); @@ -398,7 +402,7 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl let my_section = item_ty_to_section(myitem.type_()); if Some(my_section) != last_section { if last_section.is_some() { - w.write_str(ITEM_TABLE_CLOSE); + w.push_str(ITEM_TABLE_CLOSE); } last_section = Some(my_section); let section_id = my_section.id(); @@ -412,21 +416,29 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl use crate::html::format::anchor; match *src { - Some(src) => write!( - w, - "<dt><code>{}extern crate {} as {};", - visibility_print_with_space(myitem, cx), - anchor(myitem.item_id.expect_def_id(), src, cx), - EscapeBodyTextWithWbr(myitem.name.unwrap().as_str()), - ), - None => write!( - w, - "<dt><code>{}extern crate {};", - visibility_print_with_space(myitem, cx), - anchor(myitem.item_id.expect_def_id(), myitem.name.unwrap(), cx), - ), + Some(src) => { + write_str( + w, + format_args!( + "<dt><code>{}extern crate {} as {};", + visibility_print_with_space(myitem, cx), + anchor(myitem.item_id.expect_def_id(), src, cx), + EscapeBodyTextWithWbr(myitem.name.unwrap().as_str()) + ), + ); + } + None => { + write_str( + w, + format_args!( + "<dt><code>{}extern crate {};", + visibility_print_with_space(myitem, cx), + anchor(myitem.item_id.expect_def_id(), myitem.name.unwrap(), cx) + ), + ); + } } - w.write_str("</code></dt>"); + w.push_str("</code></dt>"); } clean::ImportItem(ref import) => { @@ -440,13 +452,15 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl } clean::ImportKind::Glob => String::new(), }; - write!( + write_str( w, - "<dt{id}>\ - <code>{vis}{imp}</code>{stab_tags}\ - </dt>", - vis = visibility_print_with_space(myitem, cx), - imp = import.print(cx), + format_args!( + "<dt{id}>\ + <code>{vis}{imp}</code>{stab_tags}\ + </dt>", + vis = visibility_print_with_space(myitem, cx), + imp = import.print(cx) + ), ); } @@ -484,33 +498,35 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl MarkdownSummaryLine(&myitem.doc_value(), &myitem.links(cx)).into_string(); let (docs_before, docs_after) = if docs.is_empty() { ("", "") } else { ("<dd>", "</dd>") }; - write!( + write_str( w, - "<dt>\ - <a class=\"{class}\" href=\"{href}\" title=\"{title}\">{name}</a>\ - {visibility_and_hidden}\ - {unsafety_flag}\ - {stab_tags}\ - </dt>\ - {docs_before}{docs}{docs_after}", - name = EscapeBodyTextWithWbr(myitem.name.unwrap().as_str()), - visibility_and_hidden = visibility_and_hidden, - stab_tags = extra_info_tags(tcx, myitem, item, None), - class = myitem.type_(), - unsafety_flag = unsafety_flag, - href = item_path(myitem.type_(), myitem.name.unwrap().as_str()), - title = [myitem.type_().to_string(), full_path(cx, myitem)] - .iter() - .filter_map(|s| if !s.is_empty() { Some(s.as_str()) } else { None }) - .collect::<Vec<_>>() - .join(" "), + format_args!( + "<dt>\ + <a class=\"{class}\" href=\"{href}\" title=\"{title}\">{name}</a>\ + {visibility_and_hidden}\ + {unsafety_flag}\ + {stab_tags}\ + </dt>\ + {docs_before}{docs}{docs_after}", + name = EscapeBodyTextWithWbr(myitem.name.unwrap().as_str()), + visibility_and_hidden = visibility_and_hidden, + stab_tags = extra_info_tags(tcx, myitem, item, None), + class = myitem.type_(), + unsafety_flag = unsafety_flag, + href = item_path(myitem.type_(), myitem.name.unwrap().as_str()), + title = [myitem.type_().to_string(), full_path(cx, myitem)] + .iter() + .filter_map(|s| if !s.is_empty() { Some(s.as_str()) } else { None }) + .collect::<Vec<_>>() + .join(" "), + ), ); } } } if last_section.is_some() { - w.write_str(ITEM_TABLE_CLOSE); + w.push_str(ITEM_TABLE_CLOSE); } } @@ -572,7 +588,7 @@ fn extra_info_tags<'a, 'tcx: 'a>( }) } -fn item_function(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, f: &clean::Function) { +fn item_function(w: &mut String, cx: &Context<'_>, it: &clean::Item, f: &clean::Function) { let tcx = cx.tcx(); let header = it.fn_header(tcx).expect("printing a function which isn't a function"); debug!( @@ -603,31 +619,32 @@ fn item_function(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, f: &clean:: + name.as_str().len() + generics_len; - let notable_traits = notable_traits_button(&f.decl.output, cx); + let notable_traits = notable_traits_button(&f.decl.output, cx).maybe_display(); wrap_item(w, |w| { w.reserve(header_len); - write!( + write_str( w, - "{attrs}{vis}{constness}{asyncness}{safety}{abi}fn \ + format_args!( + "{attrs}{vis}{constness}{asyncness}{safety}{abi}fn \ {name}{generics}{decl}{notable_traits}{where_clause}", - attrs = render_attributes_in_pre(it, "", cx), - vis = visibility, - constness = constness, - asyncness = asyncness, - safety = safety, - abi = abi, - name = name, - generics = f.generics.print(cx), - where_clause = print_where_clause(&f.generics, cx, 0, Ending::Newline), - decl = f.decl.full_print(header_len, 0, cx), - notable_traits = notable_traits.unwrap_or_default(), + attrs = render_attributes_in_pre(it, "", cx), + vis = visibility, + constness = constness, + asyncness = asyncness, + safety = safety, + abi = abi, + name = name, + generics = f.generics.print(cx), + where_clause = print_where_clause(&f.generics, cx, 0, Ending::Newline), + decl = f.decl.full_print(header_len, 0, cx), + ), ); }); - write!(w, "{}", document(cx, it, None, HeadingOffset::H2)); + write_str(w, format_args!("{}", document(cx, it, None, HeadingOffset::H2))); } -fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Trait) { +fn item_trait(w: &mut String, cx: &Context<'_>, it: &clean::Item, t: &clean::Trait) { let tcx = cx.tcx(); let bounds = bounds(&t.bounds, false, cx); let required_types = @@ -645,28 +662,33 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra // Output the trait definition wrap_item(w, |mut w| { - write!( + write_str( w, - "{attrs}{vis}{safety}{is_auto}trait {name}{generics}{bounds}", - attrs = render_attributes_in_pre(it, "", cx), - vis = visibility_print_with_space(it, cx), - safety = t.safety(tcx).print_with_space(), - is_auto = if t.is_auto(tcx) { "auto " } else { "" }, - name = it.name.unwrap(), - generics = t.generics.print(cx), + format_args!( + "{attrs}{vis}{safety}{is_auto}trait {name}{generics}{bounds}", + attrs = render_attributes_in_pre(it, "", cx), + vis = visibility_print_with_space(it, cx), + safety = t.safety(tcx).print_with_space(), + is_auto = if t.is_auto(tcx) { "auto " } else { "" }, + name = it.name.unwrap(), + generics = t.generics.print(cx), + ), ); if !t.generics.where_predicates.is_empty() { - write!(w, "{}", print_where_clause(&t.generics, cx, 0, Ending::Newline)); + write_str( + w, + format_args!("{}", print_where_clause(&t.generics, cx, 0, Ending::Newline)), + ); } else { - w.write_str(" "); + w.push_str(" "); } if t.items.is_empty() { - w.write_str("{ }"); + w.push_str("{ }"); } else { // FIXME: we should be using a derived_id for the Anchors here - w.write_str("{\n"); + w.push_str("{\n"); let mut toggle = false; // If there are too many associated types, hide _everything_ @@ -687,7 +709,7 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra cx, RenderMode::Normal, ); - w.write_str(";\n"); + w.push_str(";\n"); } } // If there are too many associated constants, hide everything after them @@ -707,7 +729,7 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra ); } if count_types != 0 && (count_consts != 0 || count_methods != 0) { - w.write_str("\n"); + w.push_str("\n"); } for consts in [&required_consts, &provided_consts] { for c in consts { @@ -719,7 +741,7 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra cx, RenderMode::Normal, ); - w.write_str(";\n"); + w.push_str(";\n"); } } if !toggle && should_hide_fields(count_methods) { @@ -727,11 +749,14 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra toggle_open(&mut w, format_args!("{count_methods} methods")); } if count_consts != 0 && count_methods != 0 { - w.write_str("\n"); + w.push_str("\n"); } if !required_methods.is_empty() { - writeln!(w, " // Required method{}", pluralize(required_methods.len())); + write_str( + w, + format_args_nl!(" // Required method{}", pluralize(required_methods.len())), + ); } for (pos, m) in required_methods.iter().enumerate() { render_assoc_item( @@ -742,18 +767,21 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra cx, RenderMode::Normal, ); - w.write_str(";\n"); + w.push_str(";\n"); if pos < required_methods.len() - 1 { - w.write_str("<span class=\"item-spacer\"></span>"); + w.push_str("<span class=\"item-spacer\"></span>"); } } if !required_methods.is_empty() && !provided_methods.is_empty() { - w.write_str("\n"); + w.push_str("\n"); } if !provided_methods.is_empty() { - writeln!(w, " // Provided method{}", pluralize(provided_methods.len())); + write_str( + w, + format_args_nl!(" // Provided method{}", pluralize(provided_methods.len())), + ); } for (pos, m) in provided_methods.iter().enumerate() { render_assoc_item( @@ -765,39 +793,42 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra RenderMode::Normal, ); - w.write_str(" { ... }\n"); + w.push_str(" { ... }\n"); if pos < provided_methods.len() - 1 { - w.write_str("<span class=\"item-spacer\"></span>"); + w.push_str("<span class=\"item-spacer\"></span>"); } } if toggle { toggle_close(&mut w); } - w.write_str("}"); + w.push_str("}"); } }); // Trait documentation - write!(w, "{}", document(cx, it, None, HeadingOffset::H2)); + write_str(w, format_args!("{}", document(cx, it, None, HeadingOffset::H2))); - fn trait_item(w: &mut Buffer, cx: &Context<'_>, m: &clean::Item, t: &clean::Item) { + fn trait_item(w: &mut String, cx: &Context<'_>, m: &clean::Item, t: &clean::Item) { let name = m.name.unwrap(); info!("Documenting {name} on {ty_name:?}", ty_name = t.name); let item_type = m.type_(); let id = cx.derive_id(format!("{item_type}.{name}")); - let mut content = Buffer::empty_from(w); - write!(content, "{}", document_full(m, cx, HeadingOffset::H5)); + let mut content = String::new(); + write_str(&mut content, format_args!("{}", document_full(m, cx, HeadingOffset::H5))); let toggled = !content.is_empty(); if toggled { let method_toggle_class = if item_type.is_method() { " method-toggle" } else { "" }; - write!(w, "<details class=\"toggle{method_toggle_class}\" open><summary>"); + write_str( + w, + format_args!("<details class=\"toggle{method_toggle_class}\" open><summary>"), + ); } - write!(w, "<section id=\"{id}\" class=\"method\">"); + write_str(w, format_args!("<section id=\"{id}\" class=\"method\">")); render_rightside(w, cx, m, RenderMode::Normal); - write!(w, "<h4 class=\"code-header\">"); + write_str(w, format_args!("<h4 class=\"code-header\">")); render_assoc_item( w, m, @@ -806,12 +837,12 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra cx, RenderMode::Normal, ); - w.write_str("</h4></section>"); + w.push_str("</h4></section>"); document_item_info(cx, m, Some(t)).render_into(w).unwrap(); if toggled { - write!(w, "</summary>"); - w.push_buffer(content); - write!(w, "</details>"); + write_str(w, format_args!("</summary>")); + w.push_str(&content); + write_str(w, format_args!("</details>")); } } @@ -826,7 +857,7 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra for t in required_consts { trait_item(w, cx, t, it); } - w.write_str("</div>"); + w.push_str("</div>"); } if !provided_consts.is_empty() { write_section_heading( @@ -839,7 +870,7 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra for t in provided_consts { trait_item(w, cx, t, it); } - w.write_str("</div>"); + w.push_str("</div>"); } if !required_types.is_empty() { @@ -853,7 +884,7 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra for t in required_types { trait_item(w, cx, t, it); } - w.write_str("</div>"); + w.push_str("</div>"); } if !provided_types.is_empty() { write_section_heading( @@ -866,7 +897,7 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra for t in provided_types { trait_item(w, cx, t, it); } - w.write_str("</div>"); + w.push_str("</div>"); } // Output the documentation for each function individually @@ -880,17 +911,19 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra ); if let Some(list) = must_implement_one_of_functions.as_deref() { - write!( + write_str( w, - "<div class=\"stab must_implement\">At least one of the `{}` methods is required.</div>", - list.iter().join("`, `") + format_args!( + "<div class=\"stab must_implement\">At least one of the `{}` methods is required.</div>", + list.iter().join("`, `") + ), ); } for m in required_methods { trait_item(w, cx, m, it); } - w.write_str("</div>"); + w.push_str("</div>"); } if !provided_methods.is_empty() { write_section_heading( @@ -903,11 +936,17 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra for m in provided_methods { trait_item(w, cx, m, it); } - w.write_str("</div>"); + w.push_str("</div>"); } // If there are methods directly on this trait object, render them here. - write!(w, "{}", render_assoc_items(cx, it, it.item_id.expect_def_id(), AssocItemRender::All)); + write_str( + w, + format_args!( + "{}", + render_assoc_items(cx, it, it.item_id.expect_def_id(), AssocItemRender::All) + ), + ); let mut extern_crates = FxIndexSet::default(); @@ -997,7 +1036,7 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra for implementor in concrete { render_implementor(cx, implementor, it, w, &implementor_dups, &[]); } - w.write_str("</div>"); + w.push_str("</div>"); if t.is_auto(tcx) { write_section_heading( @@ -1020,7 +1059,7 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra ), ); } - w.write_str("</div>"); + w.push_str("</div>"); } } else { // even without any implementations to write in, we still want the heading and list, so the @@ -1136,10 +1175,12 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra .join(","); let (extern_before, extern_after) = if extern_crates.is_empty() { ("", "") } else { (" data-ignore-extern-crates=\"", "\"") }; - write!( + write_str( w, - "<script src=\"{src}\"{extern_before}{extern_crates}{extern_after} async></script>", - src = js_src_path.finish(), + format_args!( + "<script src=\"{src}\"{extern_before}{extern_crates}{extern_after} async></script>", + src = js_src_path.finish() + ), ); } @@ -1171,21 +1212,23 @@ fn item_trait_alias( .unwrap(); } -fn item_type_alias(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::TypeAlias) { +fn item_type_alias(w: &mut String, cx: &Context<'_>, it: &clean::Item, t: &clean::TypeAlias) { wrap_item(w, |w| { - write!( + write_str( w, - "{attrs}{vis}type {name}{generics}{where_clause} = {type_};", - attrs = render_attributes_in_pre(it, "", cx), - vis = visibility_print_with_space(it, cx), - name = it.name.unwrap(), - generics = t.generics.print(cx), - where_clause = print_where_clause(&t.generics, cx, 0, Ending::Newline), - type_ = t.type_.print(cx), + format_args!( + "{attrs}{vis}type {name}{generics}{where_clause} = {type_};", + attrs = render_attributes_in_pre(it, "", cx), + vis = visibility_print_with_space(it, cx), + name = it.name.unwrap(), + generics = t.generics.print(cx), + where_clause = print_where_clause(&t.generics, cx, 0, Ending::Newline), + type_ = t.type_.print(cx), + ), ); }); - write!(w, "{}", document(cx, it, None, HeadingOffset::H2)); + write_str(w, format_args!("{}", document(cx, it, None, HeadingOffset::H2))); if let Some(inner_type) = &t.inner_type { write_section_heading(w, "Aliased Type", "aliased-type", None, ""); @@ -1201,7 +1244,7 @@ fn item_type_alias(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean let variants_count = variants_iter().count(); let has_stripped_entries = variants_len != variants_count; - write!(w, "enum {}{}", it.name.unwrap(), t.generics.print(cx)); + write_str(w, format_args!("enum {}{}", it.name.unwrap(), t.generics.print(cx))); render_enum_fields( w, cx, @@ -1220,7 +1263,10 @@ fn item_type_alias(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean let fields_count = fields.iter().filter(|i| !i.is_stripped()).count(); let has_stripped_fields = fields.len() != fields_count; - write!(w, "union {}{}", it.name.unwrap(), t.generics.print(cx)); + write_str( + w, + format_args!("union {}{}", it.name.unwrap(), t.generics.print(cx)), + ); render_struct_fields( w, Some(&t.generics), @@ -1239,7 +1285,10 @@ fn item_type_alias(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean let fields_count = fields.iter().filter(|i| !i.is_stripped()).count(); let has_stripped_fields = fields.len() != fields_count; - write!(w, "struct {}{}", it.name.unwrap(), t.generics.print(cx)); + write_str( + w, + format_args!("struct {}{}", it.name.unwrap(), t.generics.print(cx)), + ); render_struct_fields( w, Some(&t.generics), @@ -1261,8 +1310,8 @@ fn item_type_alias(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean // won't be visible anywhere in the docs. It would be nice to also show // associated items from the aliased type (see discussion in #32077), but // we need #14072 to make sense of the generics. - write!(w, "{}", render_assoc_items(cx, it, def_id, AssocItemRender::All)); - write!(w, "{}", document_type_layout(cx, def_id)); + write_str(w, format_args!("{}", render_assoc_items(cx, it, def_id, AssocItemRender::All))); + write_str(w, format_args!("{}", document_type_layout(cx, def_id))); // [RUSTDOCIMPL] type.impl // @@ -1352,15 +1401,17 @@ fn item_type_alias(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean js_src_path.extend(target_fqp[..target_fqp.len() - 1].iter().copied()); js_src_path.push_fmt(format_args!("{target_type}.{}.js", target_fqp.last().unwrap())); let self_path = self_fqp.iter().map(Symbol::as_str).collect::<Vec<&str>>().join("::"); - write!( + write_str( w, - "<script src=\"{src}\" data-self-path=\"{self_path}\" async></script>", - src = js_src_path.finish(), + format_args!( + "<script src=\"{src}\" data-self-path=\"{self_path}\" async></script>", + src = js_src_path.finish() + ), ); } } -fn item_union(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Union) { +fn item_union(w: &mut String, cx: &Context<'_>, it: &clean::Item, s: &clean::Union) { item_template!( #[template(path = "item_union.html")] struct ItemUnion<'a, 'cx> { @@ -1445,16 +1496,18 @@ fn print_tuple_struct_fields<'a, 'cx: 'a>( }) } -fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum) { +fn item_enum(w: &mut String, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum) { let count_variants = e.variants().count(); wrap_item(w, |w| { render_attributes_in_code(w, it, cx); - write!( + write_str( w, - "{}enum {}{}", - visibility_print_with_space(it, cx), - it.name.unwrap(), - e.generics.print(cx), + format_args!( + "{}enum {}{}", + visibility_print_with_space(it, cx), + it.name.unwrap(), + e.generics.print(cx), + ), ); render_enum_fields( @@ -1469,14 +1522,14 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum ); }); - write!(w, "{}", document(cx, it, None, HeadingOffset::H2)); + write_str(w, format_args!("{}", document(cx, it, None, HeadingOffset::H2))); if count_variants != 0 { item_variants(w, cx, it, &e.variants, it.def_id().unwrap()); } let def_id = it.item_id.expect_def_id(); - write!(w, "{}", render_assoc_items(cx, it, def_id, AssocItemRender::All)); - write!(w, "{}", document_type_layout(cx, def_id)); + write_str(w, format_args!("{}", render_assoc_items(cx, it, def_id, AssocItemRender::All))); + write_str(w, format_args!("{}", document_type_layout(cx, def_id))); } /// It'll return false if any variant is not a C-like variant. Otherwise it'll return true if at @@ -1505,7 +1558,7 @@ fn should_show_enum_discriminant( } fn display_c_like_variant( - w: &mut Buffer, + w: &mut String, cx: &Context<'_>, item: &clean::Item, variant: &clean::Variant, @@ -1515,22 +1568,22 @@ fn display_c_like_variant( ) { let name = item.name.unwrap(); if let Some(ref value) = variant.discriminant { - write!(w, "{} = {}", name.as_str(), value.value(cx.tcx(), true)); + write_str(w, format_args!("{} = {}", name.as_str(), value.value(cx.tcx(), true))); } else if should_show_enum_discriminant { let adt_def = cx.tcx().adt_def(enum_def_id); let discr = adt_def.discriminant_for_variant(cx.tcx(), index); if discr.ty.is_signed() { - write!(w, "{} = {}", name.as_str(), discr.val as i128); + write_str(w, format_args!("{} = {}", name.as_str(), discr.val as i128)); } else { - write!(w, "{} = {}", name.as_str(), discr.val); + write_str(w, format_args!("{} = {}", name.as_str(), discr.val)); } } else { - w.write_str(name.as_str()); + w.push_str(name.as_str()); } } fn render_enum_fields( - mut w: &mut Buffer, + mut w: &mut String, cx: &Context<'_>, g: Option<&clean::Generics>, variants: &IndexVec<VariantIdx, clean::Item>, @@ -1542,14 +1595,14 @@ fn render_enum_fields( let should_show_enum_discriminant = should_show_enum_discriminant(cx, enum_def_id, variants); if !g.is_some_and(|g| print_where_clause_and_check(w, g, cx)) { // If there wasn't a `where` clause, we add a whitespace. - w.write_str(" "); + w.push_str(" "); } let variants_stripped = has_stripped_entries; if count_variants == 0 && !variants_stripped { - w.write_str("{}"); + w.push_str("{}"); } else { - w.write_str("{\n"); + w.push_str("{\n"); let toggle = should_hide_fields(count_variants); if toggle { toggle_open(&mut w, format_args!("{count_variants} variants")); @@ -1559,7 +1612,7 @@ fn render_enum_fields( if v.is_stripped() { continue; } - w.write_str(TAB); + w.push_str(TAB); match v.kind { clean::VariantItem(ref var) => match var.kind { clean::VariantKind::CLike => display_c_like_variant( @@ -1572,7 +1625,14 @@ fn render_enum_fields( enum_def_id, ), clean::VariantKind::Tuple(ref s) => { - write!(w, "{}({})", v.name.unwrap(), print_tuple_struct_fields(cx, s)); + write_str( + w, + format_args!( + "{}({})", + v.name.unwrap(), + print_tuple_struct_fields(cx, s) + ), + ); } clean::VariantKind::Struct(ref s) => { render_struct(w, v, None, None, &s.fields, TAB, false, cx); @@ -1580,21 +1640,21 @@ fn render_enum_fields( }, _ => unreachable!(), } - w.write_str(",\n"); + w.push_str(",\n"); } if variants_stripped && !is_non_exhaustive { - w.write_str(" <span class=\"comment\">// some variants omitted</span>\n"); + w.push_str(" <span class=\"comment\">// some variants omitted</span>\n"); } if toggle { toggle_close(&mut w); } - w.write_str("}"); + w.push_str("}"); } } fn item_variants( - w: &mut Buffer, + w: &mut String, cx: &Context<'_>, it: &clean::Item, variants: &IndexVec<VariantIdx, clean::Item>, @@ -1615,10 +1675,12 @@ fn item_variants( continue; } let id = cx.derive_id(format!("{}.{}", ItemType::Variant, variant.name.unwrap())); - write!( + write_str( w, - "<section id=\"{id}\" class=\"variant\">\ - <a href=\"#{id}\" class=\"anchor\">§</a>", + format_args!( + "<section id=\"{id}\" class=\"variant\">\ + <a href=\"#{id}\" class=\"anchor\">§</a>" + ), ); render_stability_since_raw_with_extra( w, @@ -1626,7 +1688,7 @@ fn item_variants( variant.const_stability(tcx), " rightside", ); - w.write_str("<h3 class=\"code-header\">"); + w.push_str("<h3 class=\"code-header\">"); if let clean::VariantItem(ref var) = variant.kind && let clean::VariantKind::CLike = var.kind { @@ -1640,17 +1702,17 @@ fn item_variants( enum_def_id, ); } else { - w.write_str(variant.name.unwrap().as_str()); + w.push_str(variant.name.unwrap().as_str()); } let clean::VariantItem(variant_data) = &variant.kind else { unreachable!() }; if let clean::VariantKind::Tuple(ref s) = variant_data.kind { - write!(w, "({})", print_tuple_struct_fields(cx, s)); + write_str(w, format_args!("({})", print_tuple_struct_fields(cx, s))); } - w.write_str("</h3></section>"); + w.push_str("</h3></section>"); - write!(w, "{}", document(cx, variant, Some(it), HeadingOffset::H4)); + write_str(w, format_args!("{}", document(cx, variant, Some(it), HeadingOffset::H4))); let heading_and_fields = match &variant_data.kind { clean::VariantKind::Struct(s) => { @@ -1676,12 +1738,14 @@ fn item_variants( if let Some((heading, fields)) = heading_and_fields { let variant_id = cx.derive_id(format!("{}.{}.fields", ItemType::Variant, variant.name.unwrap())); - write!( + write_str( w, - "<div class=\"sub-variant\" id=\"{variant_id}\">\ - <h4>{heading}</h4>\ - {}", - document_non_exhaustive(variant) + format_args!( + "<div class=\"sub-variant\" id=\"{variant_id}\">\ + <h4>{heading}</h4>\ + {}", + document_non_exhaustive(variant) + ), ); for field in fields { match field.kind { @@ -1692,40 +1756,44 @@ fn item_variants( variant.name.unwrap(), field.name.unwrap() )); - write!( + write_str( w, - "<div class=\"sub-variant-field\">\ - <span id=\"{id}\" class=\"section-header\">\ - <a href=\"#{id}\" class=\"anchor field\">§</a>\ - <code>{f}: {t}</code>\ - </span>", - f = field.name.unwrap(), - t = ty.print(cx), + format_args!( + "<div class=\"sub-variant-field\">\ + <span id=\"{id}\" class=\"section-header\">\ + <a href=\"#{id}\" class=\"anchor field\">§</a>\ + <code>{f}: {t}</code>\ + </span>", + f = field.name.unwrap(), + t = ty.print(cx), + ), ); - write!( + write_str( w, - "{}</div>", - document(cx, field, Some(variant), HeadingOffset::H5) + format_args!( + "{}</div>", + document(cx, field, Some(variant), HeadingOffset::H5), + ), ); } _ => unreachable!(), } } - w.write_str("</div>"); + w.push_str("</div>"); } } - write!(w, "</div>"); + write_str(w, format_args!("</div>")); } -fn item_macro(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Macro) { +fn item_macro(w: &mut String, cx: &Context<'_>, it: &clean::Item, t: &clean::Macro) { wrap_item(w, |w| { // FIXME: Also print `#[doc(hidden)]` for `macro_rules!` if it `is_doc_hidden`. if !t.macro_rules { - write!(w, "{}", visibility_print_with_space(it, cx)); + write_str(w, format_args!("{}", visibility_print_with_space(it, cx))); } - write!(w, "{}", Escape(&t.source)); + write_str(w, format_args!("{}", Escape(&t.source))); }); - write!(w, "{}", document(cx, it, None, HeadingOffset::H2)) + write_str(w, format_args!("{}", document(cx, it, None, HeadingOffset::H2))); } fn item_proc_macro( @@ -1779,7 +1847,7 @@ fn item_primitive(w: &mut impl fmt::Write, cx: &Context<'_>, it: &clean::Item) { } fn item_constant( - w: &mut Buffer, + w: &mut String, cx: &Context<'_>, it: &clean::Item, generics: &clean::Generics, @@ -1790,14 +1858,16 @@ fn item_constant( let tcx = cx.tcx(); render_attributes_in_code(w, it, cx); - write!( + write_str( w, - "{vis}const {name}{generics}: {typ}{where_clause}", - vis = visibility_print_with_space(it, cx), - name = it.name.unwrap(), - generics = generics.print(cx), - typ = ty.print(cx), - where_clause = print_where_clause(generics, cx, 0, Ending::NoNewline), + format_args!( + "{vis}const {name}{generics}: {typ}{where_clause}", + vis = visibility_print_with_space(it, cx), + name = it.name.unwrap(), + generics = generics.print(cx), + typ = ty.print(cx), + where_clause = print_where_clause(generics, cx, 0, Ending::NoNewline) + ), ); // FIXME: The code below now prints @@ -1813,9 +1883,9 @@ fn item_constant( let is_literal = c.is_literal(tcx); let expr = c.expr(tcx); if value.is_some() || is_literal { - write!(w, " = {expr};", expr = Escape(&expr)); + write_str(w, format_args!(" = {expr};", expr = Escape(&expr))); } else { - w.write_str(";"); + w.push_str(";"); } if !is_literal { @@ -1826,32 +1896,32 @@ fn item_constant( if value_lowercase != expr_lowercase && value_lowercase.trim_end_matches("i32") != expr_lowercase { - write!(w, " // {value}", value = Escape(value)); + write_str(w, format_args!(" // {value}", value = Escape(value))); } } } }); - write!(w, "{}", document(cx, it, None, HeadingOffset::H2)) + write_str(w, format_args!("{}", document(cx, it, None, HeadingOffset::H2))); } -fn item_struct(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Struct) { +fn item_struct(w: &mut String, cx: &Context<'_>, it: &clean::Item, s: &clean::Struct) { wrap_item(w, |w| { render_attributes_in_code(w, it, cx); render_struct(w, it, Some(&s.generics), s.ctor_kind, &s.fields, "", true, cx); }); - write!(w, "{}", document(cx, it, None, HeadingOffset::H2)); + write_str(w, format_args!("{}", document(cx, it, None, HeadingOffset::H2))); item_fields(w, cx, it, &s.fields, s.ctor_kind); let def_id = it.item_id.expect_def_id(); - write!(w, "{}", render_assoc_items(cx, it, def_id, AssocItemRender::All)); - write!(w, "{}", document_type_layout(cx, def_id)); + write_str(w, format_args!("{}", render_assoc_items(cx, it, def_id, AssocItemRender::All))); + write_str(w, format_args!("{}", document_type_layout(cx, def_id))); } fn item_fields( - w: &mut Buffer, + w: &mut String, cx: &Context<'_>, it: &clean::Item, fields: &[clean::Item], @@ -1876,16 +1946,18 @@ fn item_fields( let field_name = field.name.map_or_else(|| index.to_string(), |sym| sym.as_str().to_string()); let id = cx.derive_id(format!("{typ}.{field_name}", typ = ItemType::StructField)); - write!( + write_str( w, - "<span id=\"{id}\" class=\"{item_type} section-header\">\ - <a href=\"#{id}\" class=\"anchor field\">§</a>\ - <code>{field_name}: {ty}</code>\ - </span>", - item_type = ItemType::StructField, - ty = ty.print(cx) + format_args!( + "<span id=\"{id}\" class=\"{item_type} section-header\">\ + <a href=\"#{id}\" class=\"anchor field\">§</a>\ + <code>{field_name}: {ty}</code>\ + </span>", + item_type = ItemType::StructField, + ty = ty.print(cx) + ), ); - write!(w, "{}", document(cx, field, Some(it), HeadingOffset::H3)); + write_str(w, format_args!("{}", document(cx, field, Some(it), HeadingOffset::H3))); } } } @@ -1933,8 +2005,8 @@ fn item_foreign_type(w: &mut impl fmt::Write, cx: &Context<'_>, it: &clean::Item .unwrap(); } -fn item_keyword(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item) { - write!(w, "{}", document(cx, it, None, HeadingOffset::H2)) +fn item_keyword(w: &mut String, cx: &Context<'_>, it: &clean::Item) { + write_str(w, format_args!("{}", document(cx, it, None, HeadingOffset::H2))); } /// Compare two strings treating multi-digit numbers as single units (i.e. natural sort order). @@ -2043,34 +2115,33 @@ pub(super) fn full_path(cx: &Context<'_>, item: &clean::Item) -> String { s } -pub(super) fn item_path(ty: ItemType, name: &str) -> String { - match ty { - ItemType::Module => format!("{}index.html", ensure_trailing_slash(name)), - _ => format!("{ty}.{name}.html"), - } +pub(super) fn item_path(ty: ItemType, name: &str) -> impl Display + '_ { + fmt::from_fn(move |f| match ty { + ItemType::Module => write!(f, "{}index.html", ensure_trailing_slash(name)), + _ => write!(f, "{ty}.{name}.html"), + }) } -fn bounds(t_bounds: &[clean::GenericBound], trait_alias: bool, cx: &Context<'_>) -> String { - let mut bounds = String::new(); - if t_bounds.is_empty() { - return bounds; - } - let has_lots_of_bounds = t_bounds.len() > 2; - let inter_str = if has_lots_of_bounds { "\n + " } else { " + " }; - if !trait_alias { - if has_lots_of_bounds { - bounds.push_str(":\n "); - } else { - bounds.push_str(": "); - } - } - write!( - bounds, - "{}", - fmt::from_fn(|f| t_bounds.iter().map(|p| p.print(cx)).joined(inter_str, f)) - ) - .unwrap(); - bounds +fn bounds<'a, 'tcx>( + bounds: &'a [clean::GenericBound], + trait_alias: bool, + cx: &'a Context<'tcx>, +) -> impl Display + 'a + Captures<'tcx> { + (!bounds.is_empty()) + .then_some(fmt::from_fn(move |f| { + let has_lots_of_bounds = bounds.len() > 2; + let inter_str = if has_lots_of_bounds { "\n + " } else { " + " }; + if !trait_alias { + if has_lots_of_bounds { + f.write_str(":\n ")?; + } else { + f.write_str(": ")?; + } + } + + bounds.iter().map(|p| p.print(cx)).joined(inter_str, f) + })) + .maybe_display() } fn wrap_item<W, F>(w: &mut W, f: F) @@ -2108,7 +2179,7 @@ fn render_implementor( cx: &Context<'_>, implementor: &Impl, trait_: &clean::Item, - w: &mut Buffer, + w: &mut String, implementor_dups: &FxHashMap<Symbol, (DefId, bool)>, aliases: &[String], ) { @@ -2152,10 +2223,9 @@ fn render_union<'a, 'cx: 'a>( let where_displayed = g .map(|g| { - let mut buf = Buffer::html(); - write!(buf, "{}", g.print(cx)); + let mut buf = g.print(cx).to_string(); let where_displayed = print_where_clause_and_check(&mut buf, g, cx); - write!(f, "{buf}", buf = buf.into_inner()).unwrap(); + f.write_str(&buf).unwrap(); where_displayed }) .unwrap_or(false); @@ -2197,7 +2267,7 @@ fn render_union<'a, 'cx: 'a>( } fn render_struct( - w: &mut Buffer, + w: &mut String, it: &clean::Item, g: Option<&clean::Generics>, ty: Option<CtorKind>, @@ -2206,15 +2276,17 @@ fn render_struct( structhead: bool, cx: &Context<'_>, ) { - write!( + write_str( w, - "{}{}{}", - visibility_print_with_space(it, cx), - if structhead { "struct " } else { "" }, - it.name.unwrap() + format_args!( + "{}{}{}", + visibility_print_with_space(it, cx), + if structhead { "struct " } else { "" }, + it.name.unwrap() + ), ); if let Some(g) = g { - write!(w, "{}", g.print(cx)) + write_str(w, format_args!("{}", g.print(cx))); } render_struct_fields( w, @@ -2229,7 +2301,7 @@ fn render_struct( } fn render_struct_fields( - mut w: &mut Buffer, + mut w: &mut String, g: Option<&clean::Generics>, ty: Option<CtorKind>, fields: &[clean::Item], @@ -2245,9 +2317,9 @@ fn render_struct_fields( // If there wasn't a `where` clause, we add a whitespace. if !where_displayed { - w.write_str(" {"); + w.push_str(" {"); } else { - w.write_str("{"); + w.push_str("{"); } let count_fields = fields.iter().filter(|f| matches!(f.kind, clean::StructFieldItem(..))).count(); @@ -2258,66 +2330,82 @@ fn render_struct_fields( } for field in fields { if let clean::StructFieldItem(ref ty) = field.kind { - write!( + write_str( w, - "\n{tab} {vis}{name}: {ty},", - vis = visibility_print_with_space(field, cx), - name = field.name.unwrap(), - ty = ty.print(cx), + format_args!( + "\n{tab} {vis}{name}: {ty},", + vis = visibility_print_with_space(field, cx), + name = field.name.unwrap(), + ty = ty.print(cx) + ), ); } } if has_visible_fields { if has_stripped_entries { - write!(w, "\n{tab} <span class=\"comment\">/* private fields */</span>"); + write_str( + w, + format_args!( + "\n{tab} <span class=\"comment\">/* private fields */</span>" + ), + ); } - write!(w, "\n{tab}"); + write_str(w, format_args!("\n{tab}")); } else if has_stripped_entries { - write!(w, " <span class=\"comment\">/* private fields */</span> "); + write_str(w, format_args!(" <span class=\"comment\">/* private fields */</span> ")); } if toggle { toggle_close(&mut w); } - w.write_str("}"); + w.push_str("}"); } Some(CtorKind::Fn) => { - w.write_str("("); + w.push_str("("); if !fields.is_empty() && fields.iter().all(|field| { matches!(field.kind, clean::StrippedItem(box clean::StructFieldItem(..))) }) { - write!(w, "<span class=\"comment\">/* private fields */</span>"); + write_str(w, format_args!("<span class=\"comment\">/* private fields */</span>")); } else { for (i, field) in fields.iter().enumerate() { if i > 0 { - w.write_str(", "); + w.push_str(", "); } match field.kind { - clean::StrippedItem(box clean::StructFieldItem(..)) => write!(w, "_"), + clean::StrippedItem(box clean::StructFieldItem(..)) => { + write_str(w, format_args!("_")); + } clean::StructFieldItem(ref ty) => { - write!(w, "{}{}", visibility_print_with_space(field, cx), ty.print(cx),) + write_str( + w, + format_args!( + "{}{}", + visibility_print_with_space(field, cx), + ty.print(cx) + ), + ); } _ => unreachable!(), } } } - w.write_str(")"); + w.push_str(")"); if let Some(g) = g { - write!(w, "{}", print_where_clause(g, cx, 0, Ending::NoNewline)); + write_str(w, format_args!("{}", print_where_clause(g, cx, 0, Ending::NoNewline))); } // We only want a ";" when we are displaying a tuple struct, not a variant tuple struct. if structhead { - w.write_str(";"); + w.push_str(";"); } } Some(CtorKind::Const) => { // Needed for PhantomData. if let Some(g) = g { - write!(w, "{}", print_where_clause(g, cx, 0, Ending::NoNewline)); + write_str(w, format_args!("{}", print_where_clause(g, cx, 0, Ending::NoNewline))); } - w.write_str(";"); + w.push_str(";"); } } } diff --git a/src/librustdoc/html/render/sidebar.rs b/src/librustdoc/html/render/sidebar.rs index 23ac568fdf8..50c09b98db4 100644 --- a/src/librustdoc/html/render/sidebar.rs +++ b/src/librustdoc/html/render/sidebar.rs @@ -11,7 +11,6 @@ use super::{Context, ItemSection, item_ty_to_section}; use crate::clean; use crate::formats::Impl; use crate::formats::item_type::ItemType; -use crate::html::format::Buffer; use crate::html::markdown::{IdMap, MarkdownWithToc}; #[derive(Clone, Copy)] @@ -114,7 +113,7 @@ pub(crate) mod filters { } } -pub(super) fn print_sidebar(cx: &Context<'_>, it: &clean::Item, buffer: &mut Buffer) { +pub(super) fn print_sidebar(cx: &Context<'_>, it: &clean::Item, buffer: &mut String) { let mut ids = IdMap::new(); let mut blocks: Vec<LinkBlock<'_>> = docblock_toc(cx, it, &mut ids).into_iter().collect(); let deref_id_map = cx.deref_id_map.borrow(); diff --git a/src/librustdoc/html/render/span_map.rs b/src/librustdoc/html/render/span_map.rs index a15ac155123..fa2465c1926 100644 --- a/src/librustdoc/html/render/span_map.rs +++ b/src/librustdoc/html/render/span_map.rs @@ -221,8 +221,8 @@ impl SpanMapVisitor<'_> { impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> { type NestedFilter = nested_filter::All; - fn nested_visit_map(&mut self) -> Self::Map { - self.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.tcx } fn visit_path(&mut self, path: &rustc_hir::Path<'tcx>, _id: HirId) { diff --git a/src/librustdoc/html/render/tests.rs b/src/librustdoc/html/render/tests.rs index 4a9724a6f84..657cd3c82aa 100644 --- a/src/librustdoc/html/render/tests.rs +++ b/src/librustdoc/html/render/tests.rs @@ -1,7 +1,7 @@ use std::cmp::Ordering; +use super::AllTypes; use super::print_item::compare_names; -use super::{AllTypes, Buffer}; #[test] fn test_compare_names() { @@ -47,8 +47,8 @@ fn test_all_types_prints_header_once() { // Regression test for #82477 let all_types = AllTypes::new(); - let mut buffer = Buffer::new(); + let mut buffer = String::new(); all_types.print(&mut buffer); - assert_eq!(1, buffer.into_inner().matches("List of all items").count()); + assert_eq!(1, buffer.matches("List of all items").count()); } diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index 57d07c05c11..a4dec013fc0 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -44,7 +44,6 @@ use crate::docfs::PathError; use crate::error::Error; use crate::formats::Impl; use crate::formats::item_type::ItemType; -use crate::html::format::Buffer; use crate::html::layout; use crate::html::render::ordered_json::{EscapedJson, OrderedJson}; use crate::html::render::search_index::{SerializedSearchIndex, build_index}; @@ -622,7 +621,6 @@ impl TypeAliasPart { // to make that functionality work here, it needs to be called with // each type alias, and if it gives a different result, split the impl for &(type_alias_fqp, type_alias_item) in type_aliases { - let mut buf = Buffer::html(); cx.id_map.borrow_mut().clear(); cx.deref_id_map.borrow_mut().clear(); let target_did = impl_ @@ -638,23 +636,26 @@ impl TypeAliasPart { } else { AssocItemLink::Anchor(None) }; - super::render_impl( - &mut buf, - cx, - impl_, - type_alias_item, - assoc_link, - RenderMode::Normal, - None, - &[], - ImplRenderingParameters { - show_def_docs: true, - show_default_items: true, - show_non_assoc_items: true, - toggle_open_by_default: true, - }, - ); - let text = buf.into_inner(); + let text = { + let mut buf = String::new(); + super::render_impl( + &mut buf, + cx, + impl_, + type_alias_item, + assoc_link, + RenderMode::Normal, + None, + &[], + ImplRenderingParameters { + show_def_docs: true, + show_default_items: true, + show_non_assoc_items: true, + toggle_open_by_default: true, + }, + ); + buf + }; let type_alias_fqp = (*type_alias_fqp).iter().join("::"); if Some(&text) == ret.last().map(|s: &AliasSerializableImpl| &s.text) { ret.last_mut() diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs index 1ac0c10c612..78c86a27632 100644 --- a/src/librustdoc/html/sources.rs +++ b/src/librustdoc/html/sources.rs @@ -1,6 +1,5 @@ use std::cell::RefCell; use std::ffi::OsStr; -use std::ops::RangeInclusive; use std::path::{Component, Path, PathBuf}; use std::{fmt, fs}; @@ -12,12 +11,13 @@ use rustc_session::Session; use rustc_span::{FileName, FileNameDisplayPreference, RealFileName, sym}; use tracing::info; +use super::highlight; +use super::layout::{self, BufDisplay}; +use super::render::Context; use crate::clean; use crate::clean::utils::has_doc_flag; use crate::docfs::PathError; use crate::error::Error; -use crate::html::render::Context; -use crate::html::{highlight, layout}; use crate::visit::DocVisitor; pub(crate) fn render(cx: &mut Context<'_>, krate: &clean::Crate) -> Result<(), Error> { @@ -238,11 +238,12 @@ impl SourceCollector<'_, '_> { resource_suffix: &shared.resource_suffix, rust_logo: has_doc_flag(self.cx.tcx(), LOCAL_CRATE.as_def_id(), sym::rust_logo), }; + let source_context = SourceContext::Standalone { file_path }; let v = layout::render( &shared.layout, &page, "", - |buf: &mut _| { + BufDisplay(|buf: &mut String| { print_src( buf, contents, @@ -250,9 +251,9 @@ impl SourceCollector<'_, '_> { self.cx, &root_path, &highlight::DecorationInfo::default(), - SourceContext::Standalone { file_path }, - ) - }, + &source_context, + ); + }), &shared.style_files, ); shared.fs.write(cur, v)?; @@ -302,17 +303,17 @@ pub(crate) struct ScrapedInfo<'a> { #[derive(Template)] #[template(path = "scraped_source.html")] struct ScrapedSource<'a, Code: std::fmt::Display> { - info: ScrapedInfo<'a>, - lines: RangeInclusive<usize>, + info: &'a ScrapedInfo<'a>, code_html: Code, + max_nb_digits: u32, } #[derive(Template)] #[template(path = "source.html")] struct Source<Code: std::fmt::Display> { - lines: RangeInclusive<usize>, code_html: Code, file_path: Option<(String, String)>, + max_nb_digits: u32, } pub(crate) enum SourceContext<'a> { @@ -329,8 +330,17 @@ pub(crate) fn print_src( context: &Context<'_>, root_path: &str, decoration_info: &highlight::DecorationInfo, - source_context: SourceContext<'_>, + source_context: &SourceContext<'_>, ) { + let mut lines = s.lines().count(); + let line_info = if let SourceContext::Embedded(ref info) = source_context { + highlight::LineInfo::new_scraped(lines as u32, info.offset as u32) + } else { + highlight::LineInfo::new(lines as u32) + }; + if line_info.is_scraped_example { + lines += line_info.start_line as usize; + } let code = fmt::from_fn(move |fmt| { let current_href = context .href_from_span(clean::Span::new(file_span), false) @@ -340,13 +350,13 @@ pub(crate) fn print_src( s, Some(highlight::HrefContext { context, file_span, root_path, current_href }), Some(decoration_info), + Some(line_info), ); Ok(()) }); - let lines = s.lines().count(); + let max_nb_digits = if lines > 0 { lines.ilog(10) + 1 } else { 1 }; match source_context { SourceContext::Standalone { file_path } => Source { - lines: (1..=lines), code_html: code, file_path: if let Some(file_name) = file_path.file_name() && let Some(file_path) = file_path.parent() @@ -355,12 +365,14 @@ pub(crate) fn print_src( } else { None }, + max_nb_digits, } .render_into(&mut writer) .unwrap(), SourceContext::Embedded(info) => { - let lines = (1 + info.offset)..=(lines + info.offset); - ScrapedSource { info, lines, code_html: code }.render_into(&mut writer).unwrap(); + ScrapedSource { info, code_html: code, max_nb_digits } + .render_into(&mut writer) + .unwrap(); } }; } diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index d0612e997fd..4f5f8f92264 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -40,6 +40,20 @@ xmlns="http://www.w3.org/2000/svg" fill="black" height="18px">\ --docblock-indent: 24px; --font-family: "Source Serif 4", NanumBarunGothic, serif; --font-family-code: "Source Code Pro", monospace; + --line-number-padding: 4px; + /* scraped examples icons (34x33px) */ + --prev-arrow-image: url('data:image/svg+xml,<svg width="16" height="16" viewBox="0 0 16 16" \ + enable-background="new 0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path fill="none" \ + d="M8,3l-4,5l4,5m-4,-5h10" stroke="black" stroke-width="2"/></svg>'); + --next-arrow-image: url('data:image/svg+xml,<svg width="16" height="16" viewBox="0 0 16 16" \ + enable-background="new 0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path fill="none" \ + d="M8,3l4,5l-4,5m4,-5h-10" stroke="black" stroke-width="2"/></svg>'); + --expand-arrow-image: url('data:image/svg+xml,<svg width="16" height="16" viewBox="0 0 16 16" \ + enable-background="new 0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path fill="none" \ + d="M3,10l4,4l4,-4m-4,4M3,7l4,-4l4,4" stroke="black" stroke-width="2"/></svg>'); + --collapse-arrow-image: url('data:image/svg+xml,<svg width="16" height="16" viewBox="0 0 16 16" \ + enable-background="new 0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path fill="none" \ + d="M3,8l4,4l4,-4m-4,4M3,4l4,4l4,-4" stroke="black" stroke-width="2"/></svg>'); } :root.sans-serif { @@ -450,9 +464,7 @@ pre.item-decl { .src .content pre { padding: 20px; -} -.rustdoc.src .example-wrap .src-line-numbers { - padding: 20px 0 20px 4px; + padding-left: 16px; } img { @@ -901,29 +913,58 @@ both the code example and the line numbers, so we need to remove the radius in t min-width: fit-content; /* prevent collapsing into nothing in truncated scraped examples */ flex-grow: 0; text-align: right; + -moz-user-select: none; -webkit-user-select: none; + -ms-user-select: none; user-select: none; padding: 14px 8px; padding-right: 2px; color: var(--src-line-numbers-span-color); } -.rustdoc .scraped-example .example-wrap .src-line-numbers { - padding: 0; +.example-wrap.digits-1 [data-nosnippet] { + width: calc(1ch + var(--line-number-padding) * 2); +} +.example-wrap.digits-2 [data-nosnippet] { + width: calc(2ch + var(--line-number-padding) * 2); +} +.example-wrap.digits-3 [data-nosnippet] { + width: calc(3ch + var(--line-number-padding) * 2); +} +.example-wrap.digits-4 [data-nosnippet] { + width: calc(4ch + var(--line-number-padding) * 2); +} +.example-wrap.digits-5 [data-nosnippet] { + width: calc(5ch + var(--line-number-padding) * 2); } -.rustdoc .src-line-numbers pre { - padding: 14px 0; +.example-wrap.digits-6 [data-nosnippet] { + width: calc(6ch + var(--line-number-padding) * 2); } -.src-line-numbers a, .src-line-numbers span { +.example-wrap.digits-7 [data-nosnippet] { + width: calc(7ch + var(--line-number-padding) * 2); +} +.example-wrap.digits-8 [data-nosnippet] { + width: calc(8ch + var(--line-number-padding) * 2); +} +.example-wrap.digits-9 [data-nosnippet] { + width: calc(9ch + var(--line-number-padding) * 2); +} + +.example-wrap [data-nosnippet] { color: var(--src-line-numbers-span-color); - padding: 0 8px; + text-align: right; + display: inline-block; + margin-right: 20px; + -moz-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; + padding: 0 4px; } -.src-line-numbers :target { - background-color: transparent; +.example-wrap [data-nosnippet]:target { border-right: none; - padding: 0 8px; } -.src-line-numbers .line-highlighted { +.example-wrap .line-highlighted[data-nosnippet] { background-color: var(--src-line-number-highlighted-background-color); } @@ -1110,7 +1151,7 @@ because of the `[-]` element which would overlap with it. */ } .main-heading a:hover, -.example-wrap .rust a:hover, +.example-wrap .rust a:hover:not([data-nosnippet]), .all-items a:hover, .docblock a:not(.scrape-help):not(.tooltip):hover:not(.doc-anchor), .item-table dd a:not(.scrape-help):not(.tooltip):hover, @@ -1568,7 +1609,7 @@ pre.rust .doccomment { color: var(--code-highlight-doc-comment-color); } -.rustdoc.src .example-wrap pre.rust a { +.rustdoc.src .example-wrap pre.rust a:not([data-nosnippet]) { background: var(--codeblock-link-background); } @@ -1701,7 +1742,10 @@ instead, we check that it's not a "finger" cursor. padding: 2px 0 0 4px; } .example-wrap .button-holder .copy-button::before, -.example-wrap .test-arrow::before { +.example-wrap .test-arrow::before, +.example-wrap .button-holder .prev::before, +.example-wrap .button-holder .next::before, +.example-wrap .button-holder .expand::before { filter: var(--copy-path-img-filter); } .example-wrap .button-holder .copy-button::before { @@ -1716,6 +1760,24 @@ instead, we check that it's not a "finger" cursor. padding-right: 5px; } +.example-wrap .button-holder .prev, +.example-wrap .button-holder .next, +.example-wrap .button-holder .expand { + line-height: 0px; +} +.example-wrap .button-holder .prev::before { + content: var(--prev-arrow-image); +} +.example-wrap .button-holder .next::before { + content: var(--next-arrow-image); +} +.example-wrap .button-holder .expand::before { + content: var(--expand-arrow-image); +} +.example-wrap .button-holder .expand.collapse::before { + content: var(--collapse-arrow-image); +} + .code-attribute { font-weight: 300; color: var(--code-attribute-color); @@ -1759,8 +1821,7 @@ instead, we check that it's not a "finger" cursor. } } -:target { - padding-right: 3px; +:target:not([data-nosnippet]) { background-color: var(--target-background-color); border-right: 3px solid var(--target-border-color); } @@ -1985,6 +2046,13 @@ button#toggle-all-docs:before { filter: var(--settings-menu-filter); } +button#toggle-all-docs.will-expand:before { + /* Custom arrow icon */ + content: url('data:image/svg+xml,<svg width="18" height="18" viewBox="0 0 12 12" \ + enable-background="new 0 0 12 12" xmlns="http://www.w3.org/2000/svg">\ + <path d="M2,5l4,-4l4,4M2,7l4,4l4,-4" stroke="black" fill="none" stroke-width="2px"/></svg>'); +} + #help-button > a:before { /* Question mark with circle */ content: url('data:image/svg+xml,<svg width="18" height="18" viewBox="0 0 12 12" \ @@ -3153,7 +3221,7 @@ Original by Dempfi (https://github.com/dempfi/ayu) color: #ff7733; } -:root[data-theme="ayu"] .src-line-numbers .line-highlighted { +:root[data-theme="ayu"] a[data-nosnippet].line-highlighted { color: #708090; padding-right: 7px; border-right: 1px solid #ffb44c; diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index a348c6c5678..e46cc1897e9 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -2039,7 +2039,10 @@ function preLoadCss(cssUrl) { // Most page titles are '<Item> in <path::to::module> - Rust', except // modules (which don't have the first part) and keywords/primitives // (which don't have a module path) - const [item, module] = document.title.split(" in "); + const titleElement = document.querySelector("title"); + const title = titleElement && titleElement.textContent ? + titleElement.textContent.replace(" - Rust", "") : ""; + const [item, module] = title.split(" in "); const path = [item]; if (module !== undefined) { path.unshift(module); diff --git a/src/librustdoc/html/static/js/scrape-examples.js b/src/librustdoc/html/static/js/scrape-examples.js index d08f15a5bfa..d641405c875 100644 --- a/src/librustdoc/html/static/js/scrape-examples.js +++ b/src/librustdoc/html/static/js/scrape-examples.js @@ -16,7 +16,7 @@ // Scroll code block to the given code location function scrollToLoc(elt, loc, isHidden) { - const lines = elt.querySelector(".src-line-numbers > pre"); + const lines = elt.querySelectorAll("[data-nosnippet]"); let scrollOffset; // If the block is greater than the size of the viewer, @@ -25,24 +25,24 @@ const maxLines = isHidden ? HIDDEN_MAX_LINES : DEFAULT_MAX_LINES; if (loc[1] - loc[0] > maxLines) { const line = Math.max(0, loc[0] - 1); - scrollOffset = lines.children[line].offsetTop; + scrollOffset = lines[line].offsetTop; } else { const halfHeight = elt.offsetHeight / 2; - const offsetTop = lines.children[loc[0]].offsetTop; - const lastLine = lines.children[loc[1]]; + const offsetTop = lines[loc[0]].offsetTop; + const lastLine = lines[loc[1]]; const offsetBot = lastLine.offsetTop + lastLine.offsetHeight; const offsetMid = (offsetTop + offsetBot) / 2; scrollOffset = offsetMid - halfHeight; } - lines.parentElement.scrollTo(0, scrollOffset); + lines[0].parentElement.scrollTo(0, scrollOffset); elt.querySelector(".rust").scrollTo(0, scrollOffset); } function createScrapeButton(parent, className, content) { const button = document.createElement("button"); button.className = className; - button.innerText = content; + button.title = content; parent.insertBefore(button, parent.firstChild); return button; } @@ -54,14 +54,14 @@ let expandButton = null; if (!example.classList.contains("expanded")) { - expandButton = createScrapeButton(buttonHolder, "expand", "↕"); + expandButton = createScrapeButton(buttonHolder, "expand", "Show all"); } const isHidden = example.parentElement.classList.contains("more-scraped-examples"); const locs = example.locs; if (locs.length > 1) { - const next = createScrapeButton(buttonHolder, "next", "≻"); - const prev = createScrapeButton(buttonHolder, "prev", "≺"); + const next = createScrapeButton(buttonHolder, "next", "Next usage"); + const prev = createScrapeButton(buttonHolder, "prev", "Previous usage"); // Toggle through list of examples in a given file const onChangeLoc = changeIndex => { @@ -94,9 +94,13 @@ expandButton.addEventListener("click", () => { if (hasClass(example, "expanded")) { removeClass(example, "expanded"); + removeClass(expandButton, "collapse"); + expandButton.title = "Show all"; scrollToLoc(example, locs[0][0], isHidden); } else { addClass(example, "expanded"); + addClass(expandButton, "collapse"); + expandButton.title = "Show single example"; } }); } diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 121a43e3d92..ccbd6811b07 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -5318,8 +5318,9 @@ function registerSearchEvents() { // @ts-expect-error searchState.input.addEventListener("blur", () => { - // @ts-expect-error - searchState.input.placeholder = searchState.input.origPlaceholder; + if (window.searchState.input) { + window.searchState.input.placeholder = window.searchState.origPlaceholder; + } }); // Push and pop states are used to add search results to the browser diff --git a/src/librustdoc/html/static/js/src-script.js b/src/librustdoc/html/static/js/src-script.js index 8f712f4c20c..fc27241334b 100644 --- a/src/librustdoc/html/static/js/src-script.js +++ b/src/librustdoc/html/static/js/src-script.js @@ -138,10 +138,8 @@ function highlightSrcLines() { if (x) { x.scrollIntoView(); } - onEachLazy(document.getElementsByClassName("src-line-numbers"), e => { - onEachLazy(e.getElementsByTagName("a"), i_e => { - removeClass(i_e, "line-highlighted"); - }); + onEachLazy(document.querySelectorAll("a[data-nosnippet]"), e => { + removeClass(e, "line-highlighted"); }); for (let i = from; i <= to; ++i) { elem = document.getElementById(i); @@ -200,7 +198,7 @@ const handleSrcHighlight = (function() { window.addEventListener("hashchange", highlightSrcLines); -onEachLazy(document.getElementsByClassName("src-line-numbers"), el => { +onEachLazy(document.querySelectorAll("a[data-nosnippet]"), el => { el.addEventListener("click", handleSrcHighlight); }); diff --git a/src/librustdoc/html/templates/scraped_source.html b/src/librustdoc/html/templates/scraped_source.html index bd54bbf58d5..3e69f1c8cad 100644 --- a/src/librustdoc/html/templates/scraped_source.html +++ b/src/librustdoc/html/templates/scraped_source.html @@ -2,17 +2,7 @@ <div class="scraped-example-title"> {{info.name +}} (<a href="{{info.url}}">{{info.title}}</a>) {# #} </div> {# #} - <div class="example-wrap"> - {# https://developers.google.com/search/docs/crawling-indexing/robots-meta-tag#data-nosnippet-attr - Do not show "1 2 3 4 5 ..." in web search results. #} - <div class="src-line-numbers" data-nosnippet> {# #} - <pre> - {% for line in lines.clone() %} - {# ~#} - <span>{{line|safe}}</span> - {% endfor %} - </pre> {# #} - </div> {# #} + <div class="example-wrap digits-{{max_nb_digits}}"> {# #} <pre class="rust"> {# #} <code> {{code_html|safe}} diff --git a/src/librustdoc/html/templates/source.html b/src/librustdoc/html/templates/source.html index ea530087e6f..454d4c27f1a 100644 --- a/src/librustdoc/html/templates/source.html +++ b/src/librustdoc/html/templates/source.html @@ -9,15 +9,7 @@ </div> {% else %} {% endmatch %} -<div class="example-wrap"> - {# https://developers.google.com/search/docs/crawling-indexing/robots-meta-tag#data-nosnippet-attr - Do not show "1 2 3 4 5 ..." in web search results. #} - <div data-nosnippet><pre class="src-line-numbers"> - {% for line in lines.clone() %} - {# ~#} - <a href="#{{line|safe}}" id="{{line|safe}}">{{line|safe}}</a> - {% endfor %} - </pre></div> {# #} +<div class="example-wrap digits-{{max_nb_digits}}"> {# #} <pre class="rust"> {# #} <code> {{code_html|safe}} diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index fcee2960979..bef59469179 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -846,7 +846,7 @@ fn convert_static( is_unsafe: safety.is_unsafe(), expr: stat .expr - .map(|e| rendered_const(tcx, tcx.hir().body(e), tcx.hir().body_owner_def_id(e))) + .map(|e| rendered_const(tcx, tcx.hir_body(e), tcx.hir().body_owner_def_id(e))) .unwrap_or_default(), } } diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 1d5bac3d1bf..e4acbcf2c62 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -7,6 +7,7 @@ #![feature(box_patterns)] #![feature(debug_closure_helpers)] #![feature(file_buffered)] +#![feature(format_args_nl)] #![feature(if_let_guard)] #![feature(impl_trait_in_assoc_type)] #![feature(iter_intersperse)] @@ -105,6 +106,7 @@ macro_rules! map { mod clean; mod config; mod core; +mod display; mod docfs; mod doctest; mod error; @@ -113,7 +115,6 @@ mod fold; mod formats; // used by the error-index generator, so it needs to be public pub mod html; -mod joined; mod json; pub(crate) mod lint; mod markdown; diff --git a/src/librustdoc/passes/calculate_doc_coverage.rs b/src/librustdoc/passes/calculate_doc_coverage.rs index 135aa799060..45b8dafa907 100644 --- a/src/librustdoc/passes/calculate_doc_coverage.rs +++ b/src/librustdoc/passes/calculate_doc_coverage.rs @@ -232,7 +232,7 @@ impl DocVisitor<'_> for CoverageCalculator<'_, '_> { .item_id .as_def_id() .and_then(|def_id| self.ctx.tcx.opt_parent(def_id)) - .and_then(|def_id| self.ctx.tcx.hir().get_if_local(def_id)) + .and_then(|def_id| self.ctx.tcx.hir_get_if_local(def_id)) .map(|node| { matches!( node, diff --git a/src/librustdoc/passes/lint/check_code_block_syntax.rs b/src/librustdoc/passes/lint/check_code_block_syntax.rs index 459bdd991db..9662dd85d67 100644 --- a/src/librustdoc/passes/lint/check_code_block_syntax.rs +++ b/src/librustdoc/passes/lint/check_code_block_syntax.rs @@ -1,5 +1,6 @@ //! Validates syntax inside Rust code blocks (\`\`\`rust). +use std::borrow::Cow; use std::sync::Arc; use rustc_data_structures::sync::Lock; @@ -43,7 +44,11 @@ fn check_rust_syntax( let sm = Arc::new(SourceMap::new(FilePathMapping::empty())); let dcx = DiagCtxt::new(Box::new(emitter)).disable_warnings(); - let source = dox[code_block.code].to_owned(); + let source = dox[code_block.code] + .lines() + .map(|line| crate::html::markdown::map_line(line).for_code()) + .intersperse(Cow::Borrowed("\n")) + .collect::<String>(); let psess = ParseSess::with_dcx(dcx, sm); let edition = code_block.lang_string.edition.unwrap_or_else(|| cx.tcx.sess.edition()); diff --git a/src/librustdoc/passes/strip_aliased_non_local.rs b/src/librustdoc/passes/strip_aliased_non_local.rs index fa7737bc143..7f5c7da3634 100644 --- a/src/librustdoc/passes/strip_aliased_non_local.rs +++ b/src/librustdoc/passes/strip_aliased_non_local.rs @@ -26,7 +26,7 @@ impl DocFolder for AliasedNonLocalStripper<'_> { Some(match i.kind { clean::TypeAliasItem(..) => { let mut stripper = NonLocalStripper { tcx: self.tcx }; - // don't call `fold_item` as that could strip the type-alias it-self + // don't call `fold_item` as that could strip the type alias itself // which we don't want to strip out stripper.fold_item_recur(i) } diff --git a/src/librustdoc/scrape_examples.rs b/src/librustdoc/scrape_examples.rs index 599671bd4d4..dd9dbd7170e 100644 --- a/src/librustdoc/scrape_examples.rs +++ b/src/librustdoc/scrape_examples.rs @@ -123,8 +123,8 @@ where { type NestedFilter = nested_filter::OnlyBodies; - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx().hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx() } fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) { diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index e4628e4f837..f606a3d8a92 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -96,7 +96,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { let om = Module::new( cx.tcx.crate_name(LOCAL_CRATE), CRATE_DEF_ID, - cx.tcx.hir().root_module().spans.inner_span, + cx.tcx.hir_root_module().spans.inner_span, None, None, ); @@ -119,7 +119,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { } pub(crate) fn visit(mut self) -> Module<'tcx> { - let root_module = self.cx.tcx.hir().root_module(); + let root_module = self.cx.tcx.hir_root_module(); self.visit_mod_contents(CRATE_DEF_ID, root_module); let mut top_level_module = self.modules.pop().unwrap(); @@ -193,13 +193,13 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { // Reimplementation of `walk_mod` because we need to do it in two passes (explanations in // the second loop): for &i in m.item_ids { - let item = self.cx.tcx.hir().item(i); + let item = self.cx.tcx.hir_item(i); if !matches!(item.kind, hir::ItemKind::Use(_, hir::UseKind::Glob)) { self.visit_item(item); } } for &i in m.item_ids { - let item = self.cx.tcx.hir().item(i); + let item = self.cx.tcx.hir_item(i); // To match the way import precedence works, visit glob imports last. // Later passes in rustdoc will de-duplicate by name and kind, so if glob- // imported items appear last, then they'll be the ones that get discarded. @@ -315,7 +315,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { Node::Item(&hir::Item { kind: hir::ItemKind::Mod(m), .. }) if glob => { let prev = mem::replace(&mut self.inlining, true); for &i in m.item_ids { - let i = tcx.hir().item(i); + let i = tcx.hir_item(i); self.visit_item_inner(i, None, Some(def_id)); } self.inlining = prev; @@ -433,7 +433,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { match item.kind { hir::ItemKind::ForeignMod { items, .. } => { for item in items { - let item = tcx.hir().foreign_item(item.id); + let item = tcx.hir_foreign_item(item.id); self.visit_foreign_item_inner(item, None); } } @@ -563,8 +563,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { impl<'tcx> Visitor<'tcx> for RustdocVisitor<'_, 'tcx> { type NestedFilter = nested_filter::All; - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } fn visit_item(&mut self, i: &'tcx hir::Item<'tcx>) { diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index c21bf82b852..cd5ca74f8ad 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -67,6 +67,7 @@ static TARGETS: &[&str] = &[ "aarch64-unknown-none-softfloat", "aarch64-unknown-redox", "aarch64-unknown-uefi", + "amdgcn-amd-amdhsa", "arm64e-apple-darwin", "arm64e-apple-ios", "arm64e-apple-tvos", @@ -99,6 +100,7 @@ static TARGETS: &[&str] = &[ "i586-pc-windows-msvc", "i586-unknown-linux-gnu", "i586-unknown-linux-musl", + "i586-unknown-redox", "i686-apple-darwin", "i686-linux-android", "i686-pc-windows-gnu", @@ -107,7 +109,6 @@ static TARGETS: &[&str] = &[ "i686-unknown-freebsd", "i686-unknown-linux-gnu", "i686-unknown-linux-musl", - "i686-unknown-redox", "i686-unknown-uefi", "loongarch64-unknown-linux-gnu", "loongarch64-unknown-linux-musl", diff --git a/src/tools/cargo b/src/tools/cargo -Subproject 2928e32734b04925ee51e1ae88bea9a83d2fd45 +Subproject ce948f4616e3d4277e30c75c8bb01e094910df3 diff --git a/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs b/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs index f519a65fc27..aff40fa846b 100644 --- a/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs +++ b/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs @@ -338,7 +338,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering { return; } - let items = module.item_ids.iter().map(|&id| cx.tcx.hir().item(id)); + let items = module.item_ids.iter().map(|&id| cx.tcx.hir_item(id)); // Iterates over the items within a module. // diff --git a/src/tools/clippy/clippy_lints/src/async_yields_async.rs b/src/tools/clippy/clippy_lints/src/async_yields_async.rs index eeaa3de3725..013819b0da8 100644 --- a/src/tools/clippy/clippy_lints/src/async_yields_async.rs +++ b/src/tools/clippy/clippy_lints/src/async_yields_async.rs @@ -60,12 +60,12 @@ impl<'tcx> LateLintPass<'tcx> for AsyncYieldsAsync { // XXXkhuey maybe we should? return; }, - CoroutineSource::Block => cx.tcx.hir().body(*body_id).value, + CoroutineSource::Block => cx.tcx.hir_body(*body_id).value, CoroutineSource::Closure => { // Like `async fn`, async closures are wrapped in an additional block // to move all of the closure's arguments into the future. - let async_closure_body = cx.tcx.hir().body(*body_id).value; + let async_closure_body = cx.tcx.hir_body(*body_id).value; let ExprKind::Block(block, _) = async_closure_body.kind else { return; }; diff --git a/src/tools/clippy/clippy_lints/src/attrs/utils.rs b/src/tools/clippy/clippy_lints/src/attrs/utils.rs index 152e6ec70a1..a667649f734 100644 --- a/src/tools/clippy/clippy_lints/src/attrs/utils.rs +++ b/src/tools/clippy/clippy_lints/src/attrs/utils.rs @@ -22,7 +22,7 @@ pub(super) fn is_lint_level(symbol: Symbol, attr_id: AttrId) -> bool { pub(super) fn is_relevant_item(cx: &LateContext<'_>, item: &Item<'_>) -> bool { if let ItemKind::Fn { body: eid, .. } = item.kind { - is_relevant_expr(cx, cx.tcx.typeck_body(eid), cx.tcx.hir().body(eid).value) + is_relevant_expr(cx, cx.tcx.typeck_body(eid), cx.tcx.hir_body(eid).value) } else { true } @@ -30,7 +30,7 @@ pub(super) fn is_relevant_item(cx: &LateContext<'_>, item: &Item<'_>) -> bool { pub(super) fn is_relevant_impl(cx: &LateContext<'_>, item: &ImplItem<'_>) -> bool { match item.kind { - ImplItemKind::Fn(_, eid) => is_relevant_expr(cx, cx.tcx.typeck_body(eid), cx.tcx.hir().body(eid).value), + ImplItemKind::Fn(_, eid) => is_relevant_expr(cx, cx.tcx.typeck_body(eid), cx.tcx.hir_body(eid).value), _ => false, } } @@ -39,7 +39,7 @@ pub(super) fn is_relevant_trait(cx: &LateContext<'_>, item: &TraitItem<'_>) -> b match item.kind { TraitItemKind::Fn(_, TraitFn::Required(_)) => true, TraitItemKind::Fn(_, TraitFn::Provided(eid)) => { - is_relevant_expr(cx, cx.tcx.typeck_body(eid), cx.tcx.hir().body(eid).value) + is_relevant_expr(cx, cx.tcx.typeck_body(eid), cx.tcx.hir_body(eid).value) }, _ => false, } diff --git a/src/tools/clippy/clippy_lints/src/booleans.rs b/src/tools/clippy/clippy_lints/src/booleans.rs index f8c30d1c881..f30f16997d7 100644 --- a/src/tools/clippy/clippy_lints/src/booleans.rs +++ b/src/tools/clippy/clippy_lints/src/booleans.rs @@ -452,7 +452,7 @@ fn simplify_not(cx: &LateContext<'_>, curr_msrv: &Msrv, expr: &Expr<'_>) -> Opti }) }, ExprKind::Closure(closure) => { - let body = cx.tcx.hir().body(closure.body); + let body = cx.tcx.hir_body(closure.body); let params = body .params .iter() diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs b/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs index e4c0db5d9ef..57a135abc2e 100644 --- a/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs +++ b/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs @@ -66,7 +66,7 @@ fn is_used_as_unaligned(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { if matches!(name.ident.as_str(), "read_unaligned" | "write_unaligned") && let Some(def_id) = cx.typeck_results().type_dependent_def_id(parent.hir_id) && let Some(def_id) = cx.tcx.impl_of_method(def_id) - && cx.tcx.type_of(def_id).instantiate_identity().is_unsafe_ptr() + && cx.tcx.type_of(def_id).instantiate_identity().is_raw_ptr() { true } else { diff --git a/src/tools/clippy/clippy_lints/src/collection_is_never_read.rs b/src/tools/clippy/clippy_lints/src/collection_is_never_read.rs index 8276e53648c..1279be34ed8 100644 --- a/src/tools/clippy/clippy_lints/src/collection_is_never_read.rs +++ b/src/tools/clippy/clippy_lints/src/collection_is_never_read.rs @@ -118,7 +118,7 @@ fn has_no_read_access<'tcx, T: Visitable<'tcx>>(cx: &LateContext<'tcx>, id: HirI let is_read_in_closure_arg = args.iter().any(|arg| { if let ExprKind::Closure(closure) = arg.kind // To keep things simple, we only check the first param to see if its read. - && let Body { params: [param, ..], value } = cx.tcx.hir().body(closure.body) + && let Body { params: [param, ..], value } = cx.tcx.hir_body(closure.body) { !has_no_read_access(cx, param.hir_id, *value) } else { diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs index 233ebe00d8e..849c60b89b9 100644 --- a/src/tools/clippy/clippy_lints/src/dereference.rs +++ b/src/tools/clippy/clippy_lints/src/dereference.rs @@ -682,7 +682,7 @@ fn try_parse_ref_op<'tcx>( }, [arg], ) => (true, typeck.qpath_res(path, *hir_id).opt_def_id()?, arg), - ExprKind::Unary(UnOp::Deref, sub_expr) if !typeck.expr_ty(sub_expr).is_unsafe_ptr() => { + ExprKind::Unary(UnOp::Deref, sub_expr) if !typeck.expr_ty(sub_expr).is_raw_ptr() => { return Some((RefOp::Deref, sub_expr)); }, ExprKind::AddrOf(BorrowKind::Ref, mutability, sub_expr) => return Some((RefOp::AddrOf(mutability), sub_expr)), diff --git a/src/tools/clippy/clippy_lints/src/derivable_impls.rs b/src/tools/clippy/clippy_lints/src/derivable_impls.rs index 9569081ad08..bb445e0155f 100644 --- a/src/tools/clippy/clippy_lints/src/derivable_impls.rs +++ b/src/tools/clippy/clippy_lints/src/derivable_impls.rs @@ -197,7 +197,7 @@ impl<'tcx> LateLintPass<'tcx> for DerivableImpls { && let impl_item_hir = child.id.hir_id() && let Node::ImplItem(impl_item) = cx.tcx.hir_node(impl_item_hir) && let ImplItemKind::Fn(_, b) = &impl_item.kind - && let Body { value: func_expr, .. } = cx.tcx.hir().body(*b) + && let Body { value: func_expr, .. } = cx.tcx.hir_body(*b) && let &ty::Adt(adt_def, args) = cx.tcx.type_of(item.owner_id).instantiate_identity().kind() && let attrs = cx.tcx.hir().attrs(item.hir_id()) && !attrs.iter().any(|attr| attr.doc_str().is_some()) diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs index 91ddbb44ff8..db3e6034c5b 100644 --- a/src/tools/clippy/clippy_lints/src/derive.rs +++ b/src/tools/clippy/clippy_lints/src/derive.rs @@ -437,8 +437,8 @@ impl<'tcx> Visitor<'tcx> for UnsafeVisitor<'_, 'tcx> { walk_expr(self, expr) } - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } } diff --git a/src/tools/clippy/clippy_lints/src/doc/missing_headers.rs b/src/tools/clippy/clippy_lints/src/doc/missing_headers.rs index 8e2af6bf14a..d1ffbb6ffe2 100644 --- a/src/tools/clippy/clippy_lints/src/doc/missing_headers.rs +++ b/src/tools/clippy/clippy_lints/src/doc/missing_headers.rs @@ -68,7 +68,7 @@ pub fn check( } else if let Some(body_id) = body_id && let Some(future) = cx.tcx.lang_items().future_trait() && let typeck = cx.tcx.typeck_body(body_id) - && let body = cx.tcx.hir().body(body_id) + && let body = cx.tcx.hir_body(body_id) && let ret_ty = typeck.expr_ty(body.value) && implements_trait_with_env( cx.tcx, diff --git a/src/tools/clippy/clippy_lints/src/doc/mod.rs b/src/tools/clippy/clippy_lints/src/doc/mod.rs index 42e1f7fd950..93c2b7a2d18 100644 --- a/src/tools/clippy/clippy_lints/src/doc/mod.rs +++ b/src/tools/clippy/clippy_lints/src/doc/mod.rs @@ -597,7 +597,7 @@ impl<'tcx> LateLintPass<'tcx> for Documentation { if !(is_entrypoint_fn(cx, item.owner_id.to_def_id()) || item.span.in_external_macro(cx.tcx.sess.source_map())) { - let body = cx.tcx.hir().body(body_id); + let body = cx.tcx.hir_body(body_id); let panic_info = FindPanicUnwrap::find_span(cx, cx.tcx.typeck(item.owner_id), body.value); missing_headers::check( @@ -649,7 +649,7 @@ impl<'tcx> LateLintPass<'tcx> for Documentation { && !impl_item.span.in_external_macro(cx.tcx.sess.source_map()) && !is_trait_impl_item(cx, impl_item.hir_id()) { - let body = cx.tcx.hir().body(body_id); + let body = cx.tcx.hir_body(body_id); let panic_span = FindPanicUnwrap::find_span(cx, cx.tcx.typeck(impl_item.owner_id), body.value); missing_headers::check( @@ -1079,8 +1079,8 @@ impl<'tcx> Visitor<'tcx> for FindPanicUnwrap<'_, 'tcx> { // Panics in const blocks will cause compilation to fail. fn visit_anon_const(&mut self, _: &'tcx AnonConst) {} - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } } diff --git a/src/tools/clippy/clippy_lints/src/empty_drop.rs b/src/tools/clippy/clippy_lints/src/empty_drop.rs index 10a84b1b2ff..d557a36c7ac 100644 --- a/src/tools/clippy/clippy_lints/src/empty_drop.rs +++ b/src/tools/clippy/clippy_lints/src/empty_drop.rs @@ -44,7 +44,7 @@ impl LateLintPass<'_> for EmptyDrop { && let impl_item_hir = child.id.hir_id() && let Node::ImplItem(impl_item) = cx.tcx.hir_node(impl_item_hir) && let ImplItemKind::Fn(_, b) = &impl_item.kind - && let Body { value: func_expr, .. } = cx.tcx.hir().body(*b) + && let Body { value: func_expr, .. } = cx.tcx.hir_body(*b) && let func_expr = peel_blocks(func_expr) && let ExprKind::Block(block, _) = func_expr.kind && block.stmts.is_empty() diff --git a/src/tools/clippy/clippy_lints/src/eta_reduction.rs b/src/tools/clippy/clippy_lints/src/eta_reduction.rs index ae3acc1c4b1..d1782d582f4 100644 --- a/src/tools/clippy/clippy_lints/src/eta_reduction.rs +++ b/src/tools/clippy/clippy_lints/src/eta_reduction.rs @@ -97,7 +97,7 @@ fn check_closure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tcx && matches!(c.fn_decl.output, FnRetTy::DefaultReturn(_)) && !expr.span.from_expansion() { - cx.tcx.hir().body(c.body) + cx.tcx.hir_body(c.body) } else { return; }; diff --git a/src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs b/src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs index 5d93aceb33f..6a217b6182c 100644 --- a/src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs +++ b/src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs @@ -241,13 +241,13 @@ impl<'tcx> Visitor<'tcx> for TypeWalker<'_, 'tcx> { } } - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } } fn is_empty_body(cx: &LateContext<'_>, body: BodyId) -> bool { - matches!(cx.tcx.hir().body(body).value.kind, ExprKind::Block(b, _) if b.stmts.is_empty() && b.expr.is_none()) + matches!(cx.tcx.hir_body(body).value.kind, ExprKind::Block(b, _) if b.stmts.is_empty() && b.expr.is_none()) } impl<'tcx> LateLintPass<'tcx> for ExtraUnusedTypeParameters { diff --git a/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs b/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs index f822432cce6..f67d38d932b 100644 --- a/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs +++ b/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs @@ -98,10 +98,10 @@ fn lint_impl_body(cx: &LateContext<'_>, impl_span: Span, impl_items: &[hir::Impl for impl_item in impl_items { if impl_item.ident.name == sym::from - && let ImplItemKind::Fn(_, body_id) = cx.tcx.hir().impl_item(impl_item.id).kind + && let ImplItemKind::Fn(_, body_id) = cx.tcx.hir_impl_item(impl_item.id).kind { // check the body for `begin_panic` or `unwrap` - let body = cx.tcx.hir().body(body_id); + let body = cx.tcx.hir_body(body_id); let mut fpu = FindPanicUnwrap { lcx: cx, typeck_results: cx.tcx.typeck(impl_item.id.owner_id.def_id), diff --git a/src/tools/clippy/clippy_lints/src/format_impl.rs b/src/tools/clippy/clippy_lints/src/format_impl.rs index 5619cb0ab1b..ff75fcf2b41 100644 --- a/src/tools/clippy/clippy_lints/src/format_impl.rs +++ b/src/tools/clippy/clippy_lints/src/format_impl.rs @@ -262,7 +262,7 @@ fn is_format_trait_impl(cx: &LateContext<'_>, impl_item: &ImplItem<'_>) -> Optio && let Some(name) = cx.tcx.get_diagnostic_name(did) && matches!(name, sym::Debug | sym::Display) { - let body = cx.tcx.hir().body(body_id); + let body = cx.tcx.hir_body(body_id); let formatter_name = body .params .get(1) diff --git a/src/tools/clippy/clippy_lints/src/from_over_into.rs b/src/tools/clippy/clippy_lints/src/from_over_into.rs index 9a73d0c0993..41bf6e81916 100644 --- a/src/tools/clippy/clippy_lints/src/from_over_into.rs +++ b/src/tools/clippy/clippy_lints/src/from_over_into.rs @@ -134,8 +134,8 @@ impl<'tcx> Visitor<'tcx> for SelfFinder<'_, 'tcx> { type Result = ControlFlow<()>; type NestedFilter = OnlyBodies; - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } fn visit_path(&mut self, path: &Path<'tcx>, _id: HirId) -> Self::Result { @@ -175,11 +175,11 @@ fn convert_to_from( // bad suggestion/fix. return None; } - let impl_item = cx.tcx.hir().impl_item(impl_item_ref.id); + let impl_item = cx.tcx.hir_impl_item(impl_item_ref.id); let ImplItemKind::Fn(ref sig, body_id) = impl_item.kind else { return None; }; - let body = cx.tcx.hir().body(body_id); + let body = cx.tcx.hir_body(body_id); let [input] = body.params else { return None }; let PatKind::Binding(.., self_ident, None) = input.pat.kind else { return None; diff --git a/src/tools/clippy/clippy_lints/src/functions/impl_trait_in_params.rs b/src/tools/clippy/clippy_lints/src/functions/impl_trait_in_params.rs index 752dbc0db4d..6d1c55d0693 100644 --- a/src/tools/clippy/clippy_lints/src/functions/impl_trait_in_params.rs +++ b/src/tools/clippy/clippy_lints/src/functions/impl_trait_in_params.rs @@ -56,7 +56,7 @@ pub(super) fn check_impl_item(cx: &LateContext<'_>, impl_item: &ImplItem<'_>) { && let hir::ItemKind::Impl(impl_) = item.kind && let hir::Impl { of_trait, .. } = *impl_ && of_trait.is_none() - && let body = cx.tcx.hir().body(body_id) + && let body = cx.tcx.hir_body(body_id) && cx.tcx.visibility(cx.tcx.hir().body_owner_def_id(body.id())).is_public() && !is_in_test(cx.tcx, impl_item.hir_id()) { diff --git a/src/tools/clippy/clippy_lints/src/functions/must_use.rs b/src/tools/clippy/clippy_lints/src/functions/must_use.rs index e480805cac2..e6e3ea59a9f 100644 --- a/src/tools/clippy/clippy_lints/src/functions/must_use.rs +++ b/src/tools/clippy/clippy_lints/src/functions/must_use.rs @@ -37,7 +37,7 @@ pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_> check_must_use_candidate( cx, sig.decl, - cx.tcx.hir().body(*body_id), + cx.tcx.hir_body(*body_id), item.span, item.owner_id, item.span.with_hi(sig.decl.output.span().hi()), @@ -59,7 +59,7 @@ pub(super) fn check_impl_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Imp check_must_use_candidate( cx, sig.decl, - cx.tcx.hir().body(*body_id), + cx.tcx.hir_body(*body_id), item.span, item.owner_id, item.span.with_hi(sig.decl.output.span().hi()), @@ -79,7 +79,7 @@ pub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Tr if let Some(attr) = attr { check_needless_must_use(cx, sig.decl, item.owner_id, item.span, fn_header_span, attr, attrs, sig); } else if let hir::TraitFn::Provided(eid) = *eid { - let body = cx.tcx.hir().body(eid); + let body = cx.tcx.hir_body(eid); if attr.is_none() && is_public && !is_proc_macro(attrs) { check_must_use_candidate( cx, diff --git a/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs b/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs index 8a74951ef63..906bbd006d4 100644 --- a/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs +++ b/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs @@ -30,7 +30,7 @@ pub(super) fn check_fn<'tcx>( pub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::TraitItem<'_>) { if let hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(eid)) = item.kind { - let body = cx.tcx.hir().body(eid); + let body = cx.tcx.hir_body(eid); check_raw_ptr(cx, sig.header.safety(), sig.decl, body, item.owner_id.def_id); } } diff --git a/src/tools/clippy/clippy_lints/src/implicit_hasher.rs b/src/tools/clippy/clippy_lints/src/implicit_hasher.rs index 47a5c19215b..d2545e57652 100644 --- a/src/tools/clippy/clippy_lints/src/implicit_hasher.rs +++ b/src/tools/clippy/clippy_lints/src/implicit_hasher.rs @@ -130,7 +130,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitHasher { }); let mut ctr_vis = ImplicitHasherConstructorVisitor::new(cx, target); - for item in impl_.items.iter().map(|item| cx.tcx.hir().impl_item(item.id)) { + for item in impl_.items.iter().map(|item| cx.tcx.hir_impl_item(item.id)) { ctr_vis.visit_impl_item(item); } @@ -154,7 +154,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitHasher { body: body_id, .. } => { - let body = cx.tcx.hir().body(body_id); + let body = cx.tcx.hir_body(body_id); for ty in sig.decl.inputs { let mut vis = ImplicitHasherTypeVisitor::new(cx); @@ -363,7 +363,7 @@ impl<'tcx> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'_, '_, 'tcx> { walk_expr(self, e); } - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } } diff --git a/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs b/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs index 15650c4f732..deac51ab4c4 100644 --- a/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs +++ b/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs @@ -223,8 +223,8 @@ struct SliceIndexLintingVisitor<'a, 'tcx> { impl<'tcx> Visitor<'tcx> for SliceIndexLintingVisitor<'_, 'tcx> { type NestedFilter = nested_filter::OnlyBodies; - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) { diff --git a/src/tools/clippy/clippy_lints/src/infinite_iter.rs b/src/tools/clippy/clippy_lints/src/infinite_iter.rs index d3aade31f14..3cb47d8ef91 100644 --- a/src/tools/clippy/clippy_lints/src/infinite_iter.rs +++ b/src/tools/clippy/clippy_lints/src/infinite_iter.rs @@ -159,7 +159,7 @@ fn is_infinite(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness { } if method.ident.name.as_str() == "flat_map" && args.len() == 1 { if let ExprKind::Closure(&Closure { body, .. }) = args[0].kind { - let body = cx.tcx.hir().body(body); + let body = cx.tcx.hir_body(body); return is_infinite(cx, body.value); } } diff --git a/src/tools/clippy/clippy_lints/src/items_after_statements.rs b/src/tools/clippy/clippy_lints/src/items_after_statements.rs index f5ad79a0027..021d43cefdd 100644 --- a/src/tools/clippy/clippy_lints/src/items_after_statements.rs +++ b/src/tools/clippy/clippy_lints/src/items_after_statements.rs @@ -59,7 +59,7 @@ impl LateLintPass<'_> for ItemsAfterStatements { .iter() .skip_while(|stmt| matches!(stmt.kind, StmtKind::Item(..))) .filter_map(|stmt| match stmt.kind { - StmtKind::Item(id) => Some(cx.tcx.hir().item(id)), + StmtKind::Item(id) => Some(cx.tcx.hir_item(id)), _ => None, }) // Ignore macros since they can only see previously defined locals. diff --git a/src/tools/clippy/clippy_lints/src/items_after_test_module.rs b/src/tools/clippy/clippy_lints/src/items_after_test_module.rs index 1ac549b74ac..9df044f25eb 100644 --- a/src/tools/clippy/clippy_lints/src/items_after_test_module.rs +++ b/src/tools/clippy/clippy_lints/src/items_after_test_module.rs @@ -58,7 +58,7 @@ fn cfg_test_module<'tcx>(cx: &LateContext<'tcx>, item: &Item<'tcx>) -> bool { impl LateLintPass<'_> for ItemsAfterTestModule { fn check_mod(&mut self, cx: &LateContext<'_>, module: &Mod<'_>, _: HirId) { - let mut items = module.item_ids.iter().map(|&id| cx.tcx.hir().item(id)); + let mut items = module.item_ids.iter().map(|&id| cx.tcx.hir_item(id)); let Some((mod_pos, test_mod)) = items.by_ref().enumerate().find(|(_, item)| cfg_test_module(cx, item)) else { return; @@ -91,7 +91,7 @@ impl LateLintPass<'_> for ItemsAfterTestModule { "items after a test module", |diag| { if let Some(prev) = mod_pos.checked_sub(1) - && let prev = cx.tcx.hir().item(module.item_ids[prev]) + && let prev = cx.tcx.hir_item(module.item_ids[prev]) && let items_span = last.span.with_lo(test_mod.span.hi()) && let Some(items) = items_span.get_source_text(cx) { diff --git a/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs b/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs index 238f66d6675..173232c511a 100644 --- a/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs +++ b/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs @@ -142,7 +142,7 @@ impl LateLintPass<'_> for IterWithoutIntoIter { }) && let Some(iter_assoc_span) = imp.items.iter().find_map(|item| { if item.ident.name.as_str() == "IntoIter" { - Some(cx.tcx.hir().impl_item(item.id).expect_type().span) + Some(cx.tcx.hir_impl_item(item.id).expect_type().span) } else { None } diff --git a/src/tools/clippy/clippy_lints/src/len_zero.rs b/src/tools/clippy/clippy_lints/src/len_zero.rs index 26bea8d633a..98ba52f1270 100644 --- a/src/tools/clippy/clippy_lints/src/len_zero.rs +++ b/src/tools/clippy/clippy_lints/src/len_zero.rs @@ -316,7 +316,7 @@ enum LenOutput { fn extract_future_output<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<&'tcx PathSegment<'tcx>> { if let ty::Alias(_, alias_ty) = ty.kind() - && let Some(Node::OpaqueTy(opaque)) = cx.tcx.hir().get_if_local(alias_ty.def_id) + && let Some(Node::OpaqueTy(opaque)) = cx.tcx.hir_get_if_local(alias_ty.def_id) && let OpaqueTyOrigin::AsyncFn { .. } = opaque.origin && let [GenericBound::Trait(trait_ref)] = &opaque.bounds && let Some(segment) = trait_ref.trait_ref.path.segments.last() diff --git a/src/tools/clippy/clippy_lints/src/lifetimes.rs b/src/tools/clippy/clippy_lints/src/lifetimes.rs index 860c0584acc..f08812017b9 100644 --- a/src/tools/clippy/clippy_lints/src/lifetimes.rs +++ b/src/tools/clippy/clippy_lints/src/lifetimes.rs @@ -19,8 +19,8 @@ use rustc_hir::{ WherePredicateKind, lang_items, }; use rustc_lint::{LateContext, LateLintPass, LintContext}; -use rustc_middle::hir::map::Map; use rustc_middle::hir::nested_filter as middle_nested_filter; +use rustc_middle::ty::TyCtxt; use rustc_session::impl_lint_pass; use rustc_span::Span; use rustc_span::def_id::LocalDefId; @@ -275,7 +275,7 @@ fn could_use_elision<'tcx>( } if let Some(body_id) = body { - let body = cx.tcx.hir().body(body_id); + let body = cx.tcx.hir_body(body_id); let first_ident = body.params.first().and_then(|param| param.pat.simple_ident()); if non_elidable_self_type(cx, func, first_ident, msrv) { @@ -582,7 +582,7 @@ impl<'tcx, F> Visitor<'tcx> for LifetimeChecker<'_, 'tcx, F> where F: NestedFilter<'tcx>, { - type Map = Map<'tcx>; + type MaybeTyCtxt = TyCtxt<'tcx>; type NestedFilter = F; // for lifetimes as parameters of generics @@ -628,8 +628,8 @@ where self.lifetime_elision_impossible = false; } - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } } diff --git a/src/tools/clippy/clippy_lints/src/lines_filter_map_ok.rs b/src/tools/clippy/clippy_lints/src/lines_filter_map_ok.rs index 8206c75927b..f022598651b 100644 --- a/src/tools/clippy/clippy_lints/src/lines_filter_map_ok.rs +++ b/src/tools/clippy/clippy_lints/src/lines_filter_map_ok.rs @@ -101,7 +101,7 @@ fn should_lint(cx: &LateContext<'_>, args: &[Expr<'_>], method_str: &str) -> boo ExprKind::Closure(Closure { body, .. }) => { if let Body { params: [param], value, .. - } = cx.tcx.hir().body(*body) + } = cx.tcx.hir_body(*body) && let ExprKind::MethodCall(method, receiver, [], _) = value.kind && path_to_local_id(receiver, param.pat.hir_id) && let Some(method_did) = cx.typeck_results().type_dependent_def_id(value.hir_id) diff --git a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs index 2e6442156ef..e98c3c9698b 100644 --- a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs +++ b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs @@ -370,7 +370,7 @@ impl<'tcx> Visitor<'tcx> for VarVisitor<'_, 'tcx> { } }, ExprKind::Closure(&Closure { body, .. }) => { - let body = self.cx.tcx.hir().body(body); + let body = self.cx.tcx.hir_body(body); self.visit_expr(body.value); }, _ => walk_expr(self, expr), diff --git a/src/tools/clippy/clippy_lints/src/loops/utils.rs b/src/tools/clippy/clippy_lints/src/loops/utils.rs index 51fde5288ab..a5185d38e7c 100644 --- a/src/tools/clippy/clippy_lints/src/loops/utils.rs +++ b/src/tools/clippy/clippy_lints/src/loops/utils.rs @@ -240,8 +240,8 @@ impl<'tcx> Visitor<'tcx> for InitializeVisitor<'_, 'tcx> { } } - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } } diff --git a/src/tools/clippy/clippy_lints/src/loops/while_let_on_iterator.rs b/src/tools/clippy/clippy_lints/src/loops/while_let_on_iterator.rs index b7e37c1a876..6000ff7a360 100644 --- a/src/tools/clippy/clippy_lints/src/loops/while_let_on_iterator.rs +++ b/src/tools/clippy/clippy_lints/src/loops/while_let_on_iterator.rs @@ -245,8 +245,8 @@ fn needs_mutable_borrow(cx: &LateContext<'_>, iter_expr: &IterExpr, loop_expr: & impl<'tcx> Visitor<'tcx> for AfterLoopVisitor<'_, '_, 'tcx> { type NestedFilter = OnlyBodies; type Result = ControlFlow<()>; - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } fn visit_expr(&mut self, e: &'tcx Expr<'_>) -> Self::Result { @@ -288,8 +288,8 @@ fn needs_mutable_borrow(cx: &LateContext<'_>, iter_expr: &IterExpr, loop_expr: & } impl<'tcx> Visitor<'tcx> for NestedLoopVisitor<'_, '_, 'tcx> { type NestedFilter = OnlyBodies; - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } fn visit_local(&mut self, l: &'tcx LetStmt<'_>) { @@ -351,7 +351,7 @@ fn needs_mutable_borrow(cx: &LateContext<'_>, iter_expr: &IterExpr, loop_expr: & loop_id: loop_expr.hir_id, after_loop: false, }; - v.visit_expr(cx.tcx.hir().body(cx.enclosing_body.unwrap()).value) + v.visit_expr(cx.tcx.hir_body(cx.enclosing_body.unwrap()).value) .is_break() } } diff --git a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs index 9f3b0957eab..6f3a7d8cccc 100644 --- a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs +++ b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs @@ -168,7 +168,7 @@ fn desugared_async_block<'tcx>(cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) && let ClosureKind::Coroutine(CoroutineKind::Desugared(CoroutineDesugaring::Async, CoroutineSource::Block)) = kind { - return Some(cx.tcx.hir().body(body)); + return Some(cx.tcx.hir_body(body)); } None diff --git a/src/tools/clippy/clippy_lints/src/manual_option_as_slice.rs b/src/tools/clippy/clippy_lints/src/manual_option_as_slice.rs index 5c40c945c69..e4360518b66 100644 --- a/src/tools/clippy/clippy_lints/src/manual_option_as_slice.rs +++ b/src/tools/clippy/clippy_lints/src/manual_option_as_slice.rs @@ -191,7 +191,7 @@ fn check_arms(cx: &LateContext<'_>, none_arm: &Arm<'_>, some_arm: &Arm<'_>) -> b fn returns_empty_slice(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { match expr.kind { ExprKind::Path(_) => clippy_utils::is_path_diagnostic_item(cx, expr, sym::default_fn), - ExprKind::Closure(cl) => is_empty_slice(cx, cx.tcx.hir().body(cl.body).value), + ExprKind::Closure(cl) => is_empty_slice(cx, cx.tcx.hir_body(cl.body).value), _ => false, } } diff --git a/src/tools/clippy/clippy_lints/src/manual_retain.rs b/src/tools/clippy/clippy_lints/src/manual_retain.rs index 708980ac503..0a4e756096e 100644 --- a/src/tools/clippy/clippy_lints/src/manual_retain.rs +++ b/src/tools/clippy/clippy_lints/src/manual_retain.rs @@ -92,7 +92,7 @@ fn check_into_iter( && SpanlessEq::new(cx).eq_expr(left_expr, struct_expr) && let hir::ExprKind::MethodCall(_, _, [closure_expr], _) = target_expr.kind && let hir::ExprKind::Closure(closure) = closure_expr.kind - && let filter_body = cx.tcx.hir().body(closure.body) + && let filter_body = cx.tcx.hir_body(closure.body) && let [filter_params] = filter_body.params { if match_map_type(cx, left_expr) { @@ -139,7 +139,7 @@ fn check_iter( && SpanlessEq::new(cx).eq_expr(left_expr, struct_expr) && let hir::ExprKind::MethodCall(_, _, [closure_expr], _) = filter_expr.kind && let hir::ExprKind::Closure(closure) = closure_expr.kind - && let filter_body = cx.tcx.hir().body(closure.body) + && let filter_body = cx.tcx.hir_body(closure.body) && let [filter_params] = filter_body.params { match filter_params.pat.kind { @@ -198,7 +198,7 @@ fn check_to_owned( && SpanlessEq::new(cx).eq_expr(left_expr, str_expr) && let hir::ExprKind::MethodCall(_, _, [closure_expr], _) = filter_expr.kind && let hir::ExprKind::Closure(closure) = closure_expr.kind - && let filter_body = cx.tcx.hir().body(closure.body) + && let filter_body = cx.tcx.hir_body(closure.body) && let [filter_params] = filter_body.params { if let hir::PatKind::Ref(pat, _) = filter_params.pat.kind { diff --git a/src/tools/clippy/clippy_lints/src/map_unit_fn.rs b/src/tools/clippy/clippy_lints/src/map_unit_fn.rs index 3221a04d2d0..56aead85e7c 100644 --- a/src/tools/clippy/clippy_lints/src/map_unit_fn.rs +++ b/src/tools/clippy/clippy_lints/src/map_unit_fn.rs @@ -163,7 +163,7 @@ fn unit_closure<'tcx>( expr: &hir::Expr<'_>, ) -> Option<(&'tcx hir::Param<'tcx>, &'tcx hir::Expr<'tcx>)> { if let hir::ExprKind::Closure(&hir::Closure { fn_decl, body, .. }) = expr.kind - && let body = cx.tcx.hir().body(body) + && let body = cx.tcx.hir_body(body) && let body_expr = &body.value && fn_decl.inputs.len() == 1 && is_unit_expression(cx, body_expr) diff --git a/src/tools/clippy/clippy_lints/src/methods/bind_instead_of_map.rs b/src/tools/clippy/clippy_lints/src/methods/bind_instead_of_map.rs index 91a5de16e96..1e9b29f567f 100644 --- a/src/tools/clippy/clippy_lints/src/methods/bind_instead_of_map.rs +++ b/src/tools/clippy/clippy_lints/src/methods/bind_instead_of_map.rs @@ -163,7 +163,7 @@ impl BindInsteadOfMap { match arg.kind { hir::ExprKind::Closure(&hir::Closure { body, fn_decl_span, .. }) => { - let closure_body = cx.tcx.hir().body(body); + let closure_body = cx.tcx.hir_body(body); let closure_expr = peel_blocks(closure_body.value); if self.lint_closure_autofixable(cx, expr, recv, closure_expr, fn_decl_span) { diff --git a/src/tools/clippy/clippy_lints/src/methods/bytecount.rs b/src/tools/clippy/clippy_lints/src/methods/bytecount.rs index 687272e550b..0498f317442 100644 --- a/src/tools/clippy/clippy_lints/src/methods/bytecount.rs +++ b/src/tools/clippy/clippy_lints/src/methods/bytecount.rs @@ -18,7 +18,7 @@ pub(super) fn check<'tcx>( filter_arg: &'tcx Expr<'_>, ) { if let ExprKind::Closure(&Closure { body, .. }) = filter_arg.kind - && let body = cx.tcx.hir().body(body) + && let body = cx.tcx.hir_body(body) && let [param] = body.params && let PatKind::Binding(_, arg_id, _, _) = strip_pat_refs(param.pat).kind && let ExprKind::Binary(ref op, l, r) = body.value.kind diff --git a/src/tools/clippy/clippy_lints/src/methods/filter_map.rs b/src/tools/clippy/clippy_lints/src/methods/filter_map.rs index c1653b65e98..5b9df6c2bfd 100644 --- a/src/tools/clippy/clippy_lints/src/methods/filter_map.rs +++ b/src/tools/clippy/clippy_lints/src/methods/filter_map.rs @@ -22,7 +22,7 @@ fn is_method(cx: &LateContext<'_>, expr: &Expr<'_>, method_name: Symbol) -> bool ExprKind::Path(QPath::Resolved(_, segments)) => segments.segments.last().unwrap().ident.name == method_name, ExprKind::MethodCall(segment, _, _, _) => segment.ident.name == method_name, ExprKind::Closure(Closure { body, .. }) => { - let body = cx.tcx.hir().body(*body); + let body = cx.tcx.hir_body(*body); let closure_expr = peel_blocks(body.value); match closure_expr.kind { ExprKind::MethodCall(PathSegment { ident, .. }, receiver, ..) => { @@ -404,7 +404,7 @@ fn is_find_or_filter<'a>( if is_trait_method(cx, map_recv, sym::Iterator) // filter(|x| ...is_some())... && let ExprKind::Closure(&Closure { body: filter_body_id, .. }) = filter_arg.kind - && let filter_body = cx.tcx.hir().body(filter_body_id) + && let filter_body = cx.tcx.hir_body(filter_body_id) && let [filter_param] = filter_body.params // optional ref pattern: `filter(|&x| ..)` && let (filter_pat, is_filter_param_ref) = if let PatKind::Ref(ref_pat, _) = filter_param.pat.kind { @@ -417,7 +417,7 @@ fn is_find_or_filter<'a>( && let Some(mut offending_expr) = OffendingFilterExpr::hir(cx, filter_body.value, filter_param_id) && let ExprKind::Closure(&Closure { body: map_body_id, .. }) = map_arg.kind - && let map_body = cx.tcx.hir().body(map_body_id) + && let map_body = cx.tcx.hir_body(map_body_id) && let [map_param] = map_body.params && let PatKind::Binding(_, map_param_id, map_param_ident, None) = map_param.pat.kind diff --git a/src/tools/clippy/clippy_lints/src/methods/filter_map_bool_then.rs b/src/tools/clippy/clippy_lints/src/methods/filter_map_bool_then.rs index d550c145466..f7e116c5310 100644 --- a/src/tools/clippy/clippy_lints/src/methods/filter_map_bool_then.rs +++ b/src/tools/clippy/clippy_lints/src/methods/filter_map_bool_then.rs @@ -14,7 +14,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, arg: & if !expr.span.in_external_macro(cx.sess().source_map()) && is_trait_method(cx, expr, sym::Iterator) && let ExprKind::Closure(closure) = arg.kind - && let body = cx.tcx.hir().body(closure.body) + && let body = cx.tcx.hir_body(closure.body) && let value = peel_blocks(body.value) // Indexing should be fine as `filter_map` always has 1 input, we unfortunately need both // `inputs` and `params` here as we need both the type and the span @@ -31,7 +31,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, arg: & && is_copy(cx, param_ty) && let ExprKind::MethodCall(_, recv, [then_arg], _) = value.kind && let ExprKind::Closure(then_closure) = then_arg.kind - && let then_body = peel_blocks(cx.tcx.hir().body(then_closure.body).value) + && let then_body = peel_blocks(cx.tcx.hir_body(then_closure.body).value) && let Some(def_id) = cx.typeck_results().type_dependent_def_id(value.hir_id) && cx.tcx.is_diagnostic_item(sym::bool_then, def_id) && !is_from_proc_macro(cx, expr) diff --git a/src/tools/clippy/clippy_lints/src/methods/format_collect.rs b/src/tools/clippy/clippy_lints/src/methods/format_collect.rs index 3e5162ef458..1b28596d50d 100644 --- a/src/tools/clippy/clippy_lints/src/methods/format_collect.rs +++ b/src/tools/clippy/clippy_lints/src/methods/format_collect.rs @@ -19,7 +19,7 @@ fn peel_non_expn_blocks<'tcx>(expr: &'tcx Expr<'tcx>) -> Option<&'tcx Expr<'tcx> pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, map_arg: &Expr<'_>, map_span: Span) { if is_type_lang_item(cx, cx.typeck_results().expr_ty(expr), LangItem::String) && let ExprKind::Closure(closure) = map_arg.kind - && let body = cx.tcx.hir().body(closure.body) + && let body = cx.tcx.hir_body(closure.body) && let Some(value) = peel_non_expn_blocks(body.value) && let Some(mac) = root_macro_call_first_node(cx, value) && is_format_macro(cx, mac.def_id) diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_filter.rs b/src/tools/clippy/clippy_lints/src/methods/iter_filter.rs index 30387ba62a7..76a0c0061e5 100644 --- a/src/tools/clippy/clippy_lints/src/methods/iter_filter.rs +++ b/src/tools/clippy/clippy_lints/src/methods/iter_filter.rs @@ -95,7 +95,7 @@ fn is_method( false }, ExprKind::Closure(&hir::Closure { body, .. }) => { - let body = cx.tcx.hir().body(body); + let body = cx.tcx.hir_body(body); let closure_expr = peel_blocks(body.value); let params = body.params.iter().map(|param| param.pat).collect::<Vec<_>>(); is_method(cx, closure_expr, type_symbol, method_name, params.as_slice()) diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_kv_map.rs b/src/tools/clippy/clippy_lints/src/methods/iter_kv_map.rs index 299f6d10112..518041177e9 100644 --- a/src/tools/clippy/clippy_lints/src/methods/iter_kv_map.rs +++ b/src/tools/clippy/clippy_lints/src/methods/iter_kv_map.rs @@ -30,7 +30,7 @@ pub(super) fn check<'tcx>( && let Body { params: [p], value: body_expr, - } = cx.tcx.hir().body(c.body) + } = cx.tcx.hir_body(c.body) && let PatKind::Tuple([key_pat, val_pat], _) = p.pat.kind && let (replacement_kind, annotation, bound_ident) = match (&key_pat.kind, &val_pat.kind) { (key, PatKind::Binding(ann, _, value, _)) if pat_is_wild(cx, key, m_arg) => ("value", ann, value), diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs b/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs index 5ccb5243e90..a80977459f2 100644 --- a/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs +++ b/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs @@ -62,7 +62,7 @@ pub(super) fn check<'tcx>( let ExprKind::Closure(closure) = expr.kind else { return; }; - let body @ Body { params: [p], .. } = cx.tcx.hir().body(closure.body) else { + let body @ Body { params: [p], .. } = cx.tcx.hir_body(closure.body) else { return; }; let mut delegate = MoveDelegate { diff --git a/src/tools/clippy/clippy_lints/src/methods/manual_inspect.rs b/src/tools/clippy/clippy_lints/src/methods/manual_inspect.rs index 20e4d233525..de37df2394d 100644 --- a/src/tools/clippy/clippy_lints/src/methods/manual_inspect.rs +++ b/src/tools/clippy/clippy_lints/src/methods/manual_inspect.rs @@ -22,7 +22,7 @@ pub(crate) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, arg: &Expr<'_>, name: && (is_diag_trait_item(cx, fn_id, sym::Iterator) || (msrv.meets(msrvs::OPTION_RESULT_INSPECT) && (is_diag_item_method(cx, fn_id, sym::Option) || is_diag_item_method(cx, fn_id, sym::Result)))) - && let body = cx.tcx.hir().body(c.body) + && let body = cx.tcx.hir_body(c.body) && let [param] = body.params && let PatKind::Binding(BindingMode(ByRef::No, Mutability::Not), arg_id, _, None) = param.pat.kind && let arg_ty = typeck.node_type(arg_id) @@ -45,7 +45,7 @@ pub(crate) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, arg: &Expr<'_>, name: let can_lint = for_each_expr_without_closures(block.stmts, |e| { if let ExprKind::Closure(c) = e.kind { // Nested closures don't need to treat returns specially. - let _: Option<!> = for_each_expr(cx, cx.tcx.hir().body(c.body).value, |e| { + let _: Option<!> = for_each_expr(cx, cx.tcx.hir_body(c.body).value, |e| { if path_to_local_id(e, arg_id) { let (kind, same_ctxt) = check_use(cx, e); match (kind, same_ctxt && e.span.ctxt() == ctxt) { diff --git a/src/tools/clippy/clippy_lints/src/methods/manual_ok_or.rs b/src/tools/clippy/clippy_lints/src/methods/manual_ok_or.rs index 4321dd6b0e0..8265c93bfe9 100644 --- a/src/tools/clippy/clippy_lints/src/methods/manual_ok_or.rs +++ b/src/tools/clippy/clippy_lints/src/methods/manual_ok_or.rs @@ -44,7 +44,7 @@ fn is_ok_wrapping(cx: &LateContext<'_>, map_expr: &Expr<'_>) -> bool { match map_expr.kind { ExprKind::Path(ref qpath) if is_res_lang_ctor(cx, cx.qpath_res(qpath, map_expr.hir_id), ResultOk) => true, ExprKind::Closure(closure) => { - let body = cx.tcx.hir().body(closure.body); + let body = cx.tcx.hir_body(closure.body); if let PatKind::Binding(_, param_id, ..) = body.params[0].pat.kind && let ExprKind::Call(callee, [ok_arg]) = body.value.kind && is_res_lang_ctor(cx, path_res(cx, callee), ResultOk) diff --git a/src/tools/clippy/clippy_lints/src/methods/map_clone.rs b/src/tools/clippy/clippy_lints/src/methods/map_clone.rs index 1252f7ccd35..b2705e1ffc2 100644 --- a/src/tools/clippy/clippy_lints/src/methods/map_clone.rs +++ b/src/tools/clippy/clippy_lints/src/methods/map_clone.rs @@ -47,7 +47,7 @@ pub(super) fn check(cx: &LateContext<'_>, e: &hir::Expr<'_>, recv: &hir::Expr<'_ { match arg.kind { hir::ExprKind::Closure(&hir::Closure { body, .. }) => { - let closure_body = cx.tcx.hir().body(body); + let closure_body = cx.tcx.hir_body(body); let closure_expr = peel_blocks(closure_body.value); match closure_body.params[0].pat.kind { hir::PatKind::Ref(inner, Mutability::Not) => { diff --git a/src/tools/clippy/clippy_lints/src/methods/map_err_ignore.rs b/src/tools/clippy/clippy_lints/src/methods/map_err_ignore.rs index 162f0ac564d..5d0d4dae35f 100644 --- a/src/tools/clippy/clippy_lints/src/methods/map_err_ignore.rs +++ b/src/tools/clippy/clippy_lints/src/methods/map_err_ignore.rs @@ -16,7 +16,7 @@ pub(super) fn check(cx: &LateContext<'_>, e: &Expr<'_>, arg: &Expr<'_>) { fn_decl_span, .. }) = arg.kind - && let closure_body = cx.tcx.hir().body(body) + && let closure_body = cx.tcx.hir_body(body) && let [param] = closure_body.params && let PatKind::Wild = param.pat.kind { diff --git a/src/tools/clippy/clippy_lints/src/methods/map_with_unused_argument_over_ranges.rs b/src/tools/clippy/clippy_lints/src/methods/map_with_unused_argument_over_ranges.rs index 78656ace831..35dd7c082c9 100644 --- a/src/tools/clippy/clippy_lints/src/methods/map_with_unused_argument_over_ranges.rs +++ b/src/tools/clippy/clippy_lints/src/methods/map_with_unused_argument_over_ranges.rs @@ -68,7 +68,7 @@ pub(super) fn check( let mut applicability = Applicability::MaybeIncorrect; if let Some(range) = higher::Range::hir(receiver) && let ExprKind::Closure(Closure { body, .. }) = arg.kind - && let body_hir = cx.tcx.hir().body(*body) + && let body_hir = cx.tcx.hir_body(*body) && let Body { params: [param], value: body_expr, diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs index 0a8eafad0e8..ccc5cd4fa41 100644 --- a/src/tools/clippy/clippy_lints/src/methods/mod.rs +++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs @@ -4716,7 +4716,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { if sig.decl.implicit_self.has_implicit_self() && !(self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(impl_item.owner_id.def_id)) - && let Some(first_arg) = iter_input_pats(sig.decl, cx.tcx.hir().body(id)).next() + && let Some(first_arg) = iter_input_pats(sig.decl, cx.tcx.hir_body(id)).next() && let Some(first_arg_ty) = first_arg_ty_opt { wrong_self_convention::check( @@ -4852,7 +4852,7 @@ impl Methods { ), Some(("chars", recv, _, _, _)) if let ExprKind::Closure(arg) = arg.kind - && let body = cx.tcx.hir().body(arg.body) + && let body = cx.tcx.hir_body(arg.body) && let [param] = body.params => { string_lit_chars_any::check(cx, expr, recv, param, peel_blocks(body.value), &self.msrv); diff --git a/src/tools/clippy/clippy_lints/src/methods/needless_character_iteration.rs b/src/tools/clippy/clippy_lints/src/methods/needless_character_iteration.rs index 6993150fb57..743aacf0588 100644 --- a/src/tools/clippy/clippy_lints/src/methods/needless_character_iteration.rs +++ b/src/tools/clippy/clippy_lints/src/methods/needless_character_iteration.rs @@ -99,7 +99,7 @@ fn handle_expr( pub(super) fn check(cx: &LateContext<'_>, call_expr: &Expr<'_>, recv: &Expr<'_>, closure_arg: &Expr<'_>, is_all: bool) { if let ExprKind::Closure(&Closure { body, .. }) = closure_arg.kind - && let body = cx.tcx.hir().body(body) + && let body = cx.tcx.hir_body(body) && let Some(first_param) = body.params.first() && let ExprKind::MethodCall(method, mut recv, [], _) = recv.kind && method.ident.name.as_str() == "chars" 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 2780c3f8af5..45f79dd44f2 100644 --- a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs +++ b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs @@ -456,8 +456,8 @@ impl<'tcx> Visitor<'tcx> for UsedCountVisitor<'_, 'tcx> { } } - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } } @@ -498,7 +498,7 @@ fn get_captured_ids(cx: &LateContext<'_>, ty: Ty<'_>) -> HirIdSet { } }, ty::Closure(def_id, _) => { - let closure_hir_node = cx.tcx.hir().get_if_local(*def_id).unwrap(); + let closure_hir_node = cx.tcx.hir_get_if_local(*def_id).unwrap(); if let Node::Expr(closure_expr) = closure_hir_node { can_move_expr_to_closure(cx, closure_expr) .unwrap() diff --git a/src/tools/clippy/clippy_lints/src/methods/obfuscated_if_else.rs b/src/tools/clippy/clippy_lints/src/methods/obfuscated_if_else.rs index b71f79f8482..e0905374dda 100644 --- a/src/tools/clippy/clippy_lints/src/methods/obfuscated_if_else.rs +++ b/src/tools/clippy/clippy_lints/src/methods/obfuscated_if_else.rs @@ -27,7 +27,7 @@ pub(super) fn check<'tcx>( let if_then = match then_method_name { "then" if let ExprKind::Closure(closure) = then_arg.kind => { - let body = cx.tcx.hir().body(closure.body); + let body = cx.tcx.hir_body(closure.body); snippet_with_applicability(cx, body.value.span, "..", &mut applicability) }, "then_some" => snippet_with_applicability(cx, then_arg.span, "..", &mut applicability), diff --git a/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs b/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs index 8d97d1c72a6..469fcccbe4f 100644 --- a/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs +++ b/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs @@ -54,7 +54,7 @@ pub(super) fn check( }) }, hir::ExprKind::Closure(&hir::Closure { body, .. }) => { - let closure_body = cx.tcx.hir().body(body); + let closure_body = cx.tcx.hir_body(body); let closure_expr = peel_blocks(closure_body.value); match &closure_expr.kind { diff --git a/src/tools/clippy/clippy_lints/src/methods/option_map_or_none.rs b/src/tools/clippy/clippy_lints/src/methods/option_map_or_none.rs index 193deafccf6..1a273f77fb7 100644 --- a/src/tools/clippy/clippy_lints/src/methods/option_map_or_none.rs +++ b/src/tools/clippy/clippy_lints/src/methods/option_map_or_none.rs @@ -60,7 +60,7 @@ pub(super) fn check<'tcx>( let self_snippet = snippet(cx, recv.span, ".."); if let hir::ExprKind::Closure(&hir::Closure { body, fn_decl_span, .. }) = map_arg.kind && let arg_snippet = snippet(cx, fn_decl_span, "..") - && let body = cx.tcx.hir().body(body) + && let body = cx.tcx.hir_body(body) && let Some((func, [arg_char])) = reduce_unit_expression(body.value) && let Some(id) = path_def_id(cx, func).map(|ctor_id| cx.tcx.parent(ctor_id)) && Some(id) == cx.tcx.lang_items().option_some_variant() diff --git a/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs b/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs index 7c4dc4ffb20..4a8a221e8c3 100644 --- a/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs +++ b/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs @@ -143,8 +143,8 @@ impl<'tcx> Visitor<'tcx> for UnwrapVisitor<'_, 'tcx> { walk_path(self, path); } - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } } @@ -174,7 +174,7 @@ impl<'tcx> Visitor<'tcx> for ReferenceVisitor<'_, 'tcx> { rustc_hir::intravisit::walk_expr(self, expr) } - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } } diff --git a/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs b/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs index 6b39b753885..f5f404070ca 100644 --- a/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs +++ b/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs @@ -253,7 +253,7 @@ pub(super) fn check<'tcx>( fn closure_body_returns_empty_to_string(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> bool { if let hir::ExprKind::Closure(&hir::Closure { body, .. }) = e.kind { - let body = cx.tcx.hir().body(body); + let body = cx.tcx.hir_body(body); if body.params.is_empty() && let hir::Expr { kind, .. } = &body.value diff --git a/src/tools/clippy/clippy_lints/src/methods/result_map_or_else_none.rs b/src/tools/clippy/clippy_lints/src/methods/result_map_or_else_none.rs index 3b0dc506305..af619c9e3bb 100644 --- a/src/tools/clippy/clippy_lints/src/methods/result_map_or_else_none.rs +++ b/src/tools/clippy/clippy_lints/src/methods/result_map_or_else_none.rs @@ -23,7 +23,7 @@ pub(super) fn check<'tcx>( // We check that it is mapped as `Some`. && is_res_lang_ctor(cx, path_res(cx, map_arg), OptionSome) && let hir::ExprKind::Closure(&hir::Closure { body, .. }) = def_arg.kind - && let body = cx.tcx.hir().body(body) + && let body = cx.tcx.hir_body(body) // And finally we check that we return a `None` in the "else case". && is_res_lang_ctor(cx, path_res(cx, peel_blocks(body.value)), OptionNone) { diff --git a/src/tools/clippy/clippy_lints/src/methods/return_and_then.rs b/src/tools/clippy/clippy_lints/src/methods/return_and_then.rs index 7b1199ad1e2..68ffa81a278 100644 --- a/src/tools/clippy/clippy_lints/src/methods/return_and_then.rs +++ b/src/tools/clippy/clippy_lints/src/methods/return_and_then.rs @@ -44,7 +44,7 @@ pub(super) fn check<'tcx>( }; let closure_arg = fn_decl.inputs[0]; - let closure_expr = peel_blocks(cx.tcx.hir().body(body).value); + let closure_expr = peel_blocks(cx.tcx.hir_body(body).value); let mut applicability = Applicability::MachineApplicable; let arg_snip = snippet_with_applicability(cx, closure_arg.span, "_", &mut applicability); diff --git a/src/tools/clippy/clippy_lints/src/methods/search_is_some.rs b/src/tools/clippy/clippy_lints/src/methods/search_is_some.rs index 4ab165a5528..97c8ce2bcdd 100644 --- a/src/tools/clippy/clippy_lints/src/methods/search_is_some.rs +++ b/src/tools/clippy/clippy_lints/src/methods/search_is_some.rs @@ -37,7 +37,7 @@ pub(super) fn check<'tcx>( let mut applicability = Applicability::MachineApplicable; let any_search_snippet = if search_method == "find" && let ExprKind::Closure(&hir::Closure { body, .. }) = search_arg.kind - && let closure_body = cx.tcx.hir().body(body) + && let closure_body = cx.tcx.hir_body(body) && let Some(closure_arg) = closure_body.params.first() { if let PatKind::Ref(..) = closure_arg.pat.kind { diff --git a/src/tools/clippy/clippy_lints/src/methods/suspicious_map.rs b/src/tools/clippy/clippy_lints/src/methods/suspicious_map.rs index ed49233acb7..1bd48525f12 100644 --- a/src/tools/clippy/clippy_lints/src/methods/suspicious_map.rs +++ b/src/tools/clippy/clippy_lints/src/methods/suspicious_map.rs @@ -10,7 +10,7 @@ use super::SUSPICIOUS_MAP; pub fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, count_recv: &hir::Expr<'_>, map_arg: &hir::Expr<'_>) { if is_trait_method(cx, count_recv, sym::Iterator) && let hir::ExprKind::Closure(closure) = expr_or_init(cx, map_arg).kind - && let closure_body = cx.tcx.hir().body(closure.body) + && let closure_body = cx.tcx.hir_body(closure.body) && !cx.typeck_results().expr_ty(closure_body.value).is_unit() { if let Some(map_mutated_vars) = mutated_variables(closure_body.value, cx) { diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs index 5b9e9e70e47..ca42a9ac04e 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs @@ -20,7 +20,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>, a } if let hir::ExprKind::Closure(&hir::Closure { body, .. }) = arg.kind { - let body = cx.tcx.hir().body(body); + let body = cx.tcx.hir_body(body); let arg_id = body.params[0].pat.hir_id; let mutates_arg = mutated_variables(body.value, cx).is_none_or(|used_mutably| used_mutably.contains(&arg_id)); let (clone_or_copy_needed, _) = clone_or_copy_needed(cx, body.params[0].pat, body.value); diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_fold.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_fold.rs index e7adf3b43ba..8e3cc9abe83 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_fold.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_fold.rs @@ -62,7 +62,7 @@ fn check_fold_with_op( ) { if let hir::ExprKind::Closure(&hir::Closure { body, .. }) = acc.kind // Extract the body of the closure passed to fold - && let closure_body = cx.tcx.hir().body(body) + && let closure_body = cx.tcx.hir_body(body) && let closure_expr = peel_blocks(closure_body.value) // Check if the closure body is of the form `acc <op> some_expr(x)` diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_lazy_eval.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_lazy_eval.rs index 7af550fa7c6..9f4080100da 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_lazy_eval.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_lazy_eval.rs @@ -25,7 +25,7 @@ pub(super) fn check<'tcx>( if is_option || is_result || is_bool { if let hir::ExprKind::Closure(&hir::Closure { body, fn_decl, .. }) = arg.kind { - let body = cx.tcx.hir().body(body); + let body = cx.tcx.hir_body(body); let body_expr = &body.value; if usage::BindingUsageFinder::are_params_used(cx, body) || is_from_proc_macro(cx, expr) { diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_literal_unwrap.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_literal_unwrap.rs index 10112b62878..00690aca6d1 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_literal_unwrap.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_literal_unwrap.rs @@ -99,7 +99,7 @@ pub(super) fn check( ("None", "unwrap_or_else", _) => match args[0].kind { hir::ExprKind::Closure(hir::Closure { body, .. }) => Some(vec![ ( - expr.span.with_hi(cx.tcx.hir().body(*body).value.span.lo()), + expr.span.with_hi(cx.tcx.hir_body(*body).value.span.lo()), String::new(), ), (expr.span.with_lo(args[0].span.hi()), String::new()), diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_map_or.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_map_or.rs index 6dea1506d0e..5f88a7fd31f 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_map_or.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_map_or.rs @@ -63,7 +63,7 @@ pub(super) fn check<'a>( let ext_def_span = def.span.until(map.span); let (sugg, method, applicability) = if let ExprKind::Closure(map_closure) = map.kind - && let closure_body = cx.tcx.hir().body(map_closure.body) + && let closure_body = cx.tcx.hir_body(map_closure.body) && let closure_body_value = closure_body.value.peel_blocks() && let ExprKind::Binary(op, l, r) = closure_body_value.kind && let Some(param) = closure_body.params.first() diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_result_map_or_else.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_result_map_or_else.rs index dc50717112d..f84d0d6dff0 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_result_map_or_else.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_result_map_or_else.rs @@ -53,7 +53,7 @@ pub(super) fn check<'tcx>( // lint if the caller of `map_or_else()` is a `Result` if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), sym::Result) && let ExprKind::Closure(&Closure { body, .. }) = map_arg.kind - && let body = cx.tcx.hir().body(body) + && let body = cx.tcx.hir_body(body) && let Some(first_param) = body.params.first() { let body_expr = peel_blocks(body.value); diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs index f0b29213e1e..fb4984914eb 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs @@ -117,7 +117,7 @@ fn detect_lint(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, arg: &Exp && let Some(impl_id) = cx.tcx.impl_of_method(method_id) && cx.tcx.type_of(impl_id).instantiate_identity().is_slice() && let ExprKind::Closure(&Closure { body, .. }) = arg.kind - && let closure_body = cx.tcx.hir().body(body) + && let closure_body = cx.tcx.hir_body(body) && let &[ Param { pat: 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 7d72310c1c4..e80d99dca56 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 @@ -506,7 +506,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty< if has_lifetime(output_ty) && has_lifetime(ty) { return false; } - let body = cx.tcx.hir().body(*body_id); + let body = cx.tcx.hir_body(*body_id); let body_expr = &body.value; let mut count = 0; return find_all_ret_expressions(cx, body_expr, |_| { diff --git a/src/tools/clippy/clippy_lints/src/methods/unused_enumerate_index.rs b/src/tools/clippy/clippy_lints/src/methods/unused_enumerate_index.rs index 0aec26f1011..af466fe091c 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unused_enumerate_index.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unused_enumerate_index.rs @@ -46,7 +46,7 @@ pub(super) fn check(cx: &LateContext<'_>, call_expr: &Expr<'_>, recv: &Expr<'_>, && is_trait_method(cx, call_expr, sym::Iterator) // And the map argument is a closure && let ExprKind::Closure(closure) = closure_arg.kind - && let closure_body = cx.tcx.hir().body(closure.body) + && let closure_body = cx.tcx.hir_body(closure.body) // And that closure has one argument ... && let [closure_param] = closure_body.params // .. which is a tuple of 2 elements diff --git a/src/tools/clippy/clippy_lints/src/methods/useless_asref.rs b/src/tools/clippy/clippy_lints/src/methods/useless_asref.rs index 82313257e5c..19152362fb5 100644 --- a/src/tools/clippy/clippy_lints/src/methods/useless_asref.rs +++ b/src/tools/clippy/clippy_lints/src/methods/useless_asref.rs @@ -113,7 +113,7 @@ fn is_calling_clone(cx: &LateContext<'_>, arg: &hir::Expr<'_>) -> bool { match arg.kind { hir::ExprKind::Closure(&hir::Closure { body, .. }) // If it's a closure, we need to check what is called. - if let closure_body = cx.tcx.hir().body(body) + if let closure_body = cx.tcx.hir_body(body) && let [param] = closure_body.params && let hir::PatKind::Binding(_, local_id, ..) = strip_pat_refs(param.pat).kind => { diff --git a/src/tools/clippy/clippy_lints/src/methods/utils.rs b/src/tools/clippy/clippy_lints/src/methods/utils.rs index 6e39e7be2c4..3611b341897 100644 --- a/src/tools/clippy/clippy_lints/src/methods/utils.rs +++ b/src/tools/clippy/clippy_lints/src/methods/utils.rs @@ -89,8 +89,8 @@ struct CloneOrCopyVisitor<'cx, 'tcx> { impl<'tcx> Visitor<'tcx> for CloneOrCopyVisitor<'_, 'tcx> { type NestedFilter = nested_filter::OnlyBodies; - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) { diff --git a/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs b/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs index e9ec23b1efa..675989156ca 100644 --- a/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs +++ b/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs @@ -213,8 +213,8 @@ impl<'tcx> LateLintPass<'tcx> for MissingFieldsInDebug { && !item.span.from_expansion() // find `Debug::fmt` function && let Some(fmt_item) = items.iter().find(|i| i.ident.name == sym::fmt) - && let ImplItem { kind: ImplItemKind::Fn(_, body_id), .. } = cx.tcx.hir().impl_item(fmt_item.id) - && let body = cx.tcx.hir().body(*body_id) + && let ImplItem { kind: ImplItemKind::Fn(_, body_id), .. } = cx.tcx.hir_impl_item(fmt_item.id) + && let body = cx.tcx.hir_body(*body_id) && let ExprKind::Block(block, _) = body.value.kind // inspect `self` && let self_ty = cx.tcx.type_of(self_path_did).skip_binder().peel_refs() diff --git a/src/tools/clippy/clippy_lints/src/missing_inline.rs b/src/tools/clippy/clippy_lints/src/missing_inline.rs index 18385ac9269..fdc0930e957 100644 --- a/src/tools/clippy/clippy_lints/src/missing_inline.rs +++ b/src/tools/clippy/clippy_lints/src/missing_inline.rs @@ -105,7 +105,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline { // note: we need to check if the trait is exported so we can't use // `LateLintPass::check_trait_item` here. for tit in trait_items { - let tit_ = cx.tcx.hir().trait_item(tit.id); + let tit_ = cx.tcx.hir_trait_item(tit.id); match tit_.kind { hir::TraitItemKind::Const(..) | hir::TraitItemKind::Type(..) => {}, hir::TraitItemKind::Fn(..) => { @@ -113,7 +113,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline { // trait method with default body needs inline in case // an impl is not provided let desc = "a default trait method"; - let item = cx.tcx.hir().trait_item(tit.id); + let item = cx.tcx.hir_trait_item(tit.id); let attrs = cx.tcx.hir().attrs(item.hir_id()); check_missing_inline_attrs(cx, attrs, item.span, desc); } diff --git a/src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs b/src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs index 9acede4f32d..2adc27c0b70 100644 --- a/src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs +++ b/src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs @@ -122,7 +122,7 @@ fn collect_unsafe_exprs<'tcx>( unsafe_ops.push(("access of a mutable static occurs here", expr.span)); }, - ExprKind::Unary(UnOp::Deref, e) if cx.typeck_results().expr_ty_adjusted(e).is_unsafe_ptr() => { + ExprKind::Unary(UnOp::Deref, e) if cx.typeck_results().expr_ty_adjusted(e).is_raw_ptr() => { unsafe_ops.push(("raw pointer dereference occurs here", expr.span)); }, diff --git a/src/tools/clippy/clippy_lints/src/mutable_debug_assertion.rs b/src/tools/clippy/clippy_lints/src/mutable_debug_assertion.rs index 152635a5c35..13a23a13b9c 100644 --- a/src/tools/clippy/clippy_lints/src/mutable_debug_assertion.rs +++ b/src/tools/clippy/clippy_lints/src/mutable_debug_assertion.rs @@ -119,7 +119,7 @@ impl<'tcx> Visitor<'tcx> for MutArgVisitor<'_, 'tcx> { walk_expr(self, expr); } - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } } diff --git a/src/tools/clippy/clippy_lints/src/needless_for_each.rs b/src/tools/clippy/clippy_lints/src/needless_for_each.rs index 93e20f37ef8..90b27f5dbac 100644 --- a/src/tools/clippy/clippy_lints/src/needless_for_each.rs +++ b/src/tools/clippy/clippy_lints/src/needless_for_each.rs @@ -71,7 +71,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessForEach { // Skip the lint if the body is not block because this is simpler than `for` loop. // e.g. `v.iter().for_each(f)` is simpler and clearer than using `for` loop. && let ExprKind::Closure(&Closure { body, .. }) = for_each_arg.kind - && let body = cx.tcx.hir().body(body) + && let body = cx.tcx.hir_body(body) // Skip the lint if the body is not safe, so as not to suggest `for … in … unsafe {}` // and suggesting `for … in … { unsafe { } }` is a little ugly. && let ExprKind::Block(Block { rules: BlockCheckMode::DefaultBlock, .. }, ..) = body.value.kind diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs index 996251fdf16..6a1dc5e41a0 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs @@ -103,7 +103,6 @@ fn check_closures<'tcx>( checked_closures: &mut FxHashSet<LocalDefId>, closures: FxIndexSet<LocalDefId>, ) { - let hir = cx.tcx.hir(); for closure in closures { if !checked_closures.insert(closure) { continue; @@ -114,7 +113,7 @@ fn check_closures<'tcx>( .tcx .hir_node_by_def_id(closure) .associated_body() - .map(|(_, body_id)| hir.body(body_id)) + .map(|(_, body_id)| cx.tcx.hir_body(body_id)) { euv::ExprUseVisitor::for_clippy(cx, closure, &mut *ctx) .consume_body(body) diff --git a/src/tools/clippy/clippy_lints/src/new_without_default.rs b/src/tools/clippy/clippy_lints/src/new_without_default.rs index cc56df3a23d..cf407e51f7a 100644 --- a/src/tools/clippy/clippy_lints/src/new_without_default.rs +++ b/src/tools/clippy/clippy_lints/src/new_without_default.rs @@ -67,7 +67,7 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault { { for assoc_item in *items { if assoc_item.kind == (hir::AssocItemKind::Fn { has_self: false }) { - let impl_item = cx.tcx.hir().impl_item(assoc_item.id); + let impl_item = cx.tcx.hir_impl_item(assoc_item.id); if impl_item.span.in_external_macro(cx.sess().source_map()) { return; } diff --git a/src/tools/clippy/clippy_lints/src/non_canonical_impls.rs b/src/tools/clippy/clippy_lints/src/non_canonical_impls.rs index dad1e8a3d6a..448bb603cf2 100644 --- a/src/tools/clippy/clippy_lints/src/non_canonical_impls.rs +++ b/src/tools/clippy/clippy_lints/src/non_canonical_impls.rs @@ -121,10 +121,10 @@ impl LateLintPass<'_> for NonCanonicalImpls { if cx.tcx.is_automatically_derived(item.owner_id.to_def_id()) { return; } - let ImplItemKind::Fn(_, impl_item_id) = cx.tcx.hir().impl_item(impl_item.impl_item_id()).kind else { + let ImplItemKind::Fn(_, impl_item_id) = cx.tcx.hir_impl_item(impl_item.impl_item_id()).kind else { return; }; - let body = cx.tcx.hir().body(impl_item_id); + let body = cx.tcx.hir_body(impl_item_id); let ExprKind::Block(block, ..) = body.value.kind else { return; }; diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs index 405bbfc9c6f..f965ab90da2 100644 --- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs +++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs @@ -179,8 +179,8 @@ impl<'tcx> NonCopyConst<'tcx> { } fn is_value_unfrozen_raw_inner(cx: &LateContext<'tcx>, val: ty::ValTree<'tcx>, ty: Ty<'tcx>) -> bool { - // No branch that we check (yet) should continue if val isn't a ValTree::Branch - let ty::ValTree::Branch(val) = val else { return false }; + // No branch that we check (yet) should continue if val isn't a branch + let Some(val) = val.try_to_branch() else { return false }; match *ty.kind() { // the fact that we have to dig into every structs to search enums // leads us to the point checking `UnsafeCell` directly is the only option. @@ -192,9 +192,10 @@ impl<'tcx> NonCopyConst<'tcx> { .iter() .any(|field| Self::is_value_unfrozen_raw_inner(cx, *field, ty)), ty::Adt(def, args) if def.is_enum() => { - let Some((&ty::ValTree::Leaf(variant_index), fields)) = val.split_first() else { + let Some((&variant_valtree, fields)) = val.split_first() else { return false; }; + let variant_index = variant_valtree.unwrap_leaf(); let variant_index = VariantIdx::from_u32(variant_index.to_u32()); fields .iter() diff --git a/src/tools/clippy/clippy_lints/src/non_std_lazy_statics.rs b/src/tools/clippy/clippy_lints/src/non_std_lazy_statics.rs index 22116505a1c..774a182d089 100644 --- a/src/tools/clippy/clippy_lints/src/non_std_lazy_statics.rs +++ b/src/tools/clippy/clippy_lints/src/non_std_lazy_statics.rs @@ -214,7 +214,7 @@ impl LazyInfo { && state.once_cell_sync_lazy.contains(&path_def_id) { let ty_span_no_args = path_span_without_args(path); - let body = cx.tcx.hir().body(body_id); + let body = cx.tcx.hir_body(body_id); // visit body to collect `Lazy::new` calls let mut new_fn_calls = FxIndexMap::default(); diff --git a/src/tools/clippy/clippy_lints/src/operators/ptr_eq.rs b/src/tools/clippy/clippy_lints/src/operators/ptr_eq.rs index 861564d5456..8118ad59bb7 100644 --- a/src/tools/clippy/clippy_lints/src/operators/ptr_eq.rs +++ b/src/tools/clippy/clippy_lints/src/operators/ptr_eq.rs @@ -53,7 +53,7 @@ fn expr_as_cast_to_usize<'tcx>(cx: &LateContext<'tcx>, cast_expr: &'tcx Expr<'_> // If the given expression is a cast to a `*const` pointer, return the lhs of the cast // E.g., `foo as *const _` returns `foo`. fn expr_as_cast_to_raw_pointer<'tcx>(cx: &LateContext<'tcx>, cast_expr: &'tcx Expr<'_>) -> Option<&'tcx Expr<'tcx>> { - if cx.typeck_results().expr_ty(cast_expr).is_unsafe_ptr() { + if cx.typeck_results().expr_ty(cast_expr).is_raw_ptr() { if let ExprKind::Cast(expr, _) = cast_expr.kind { return Some(expr); } diff --git a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs index a3e89671eec..73c31b83b51 100644 --- a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs +++ b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs @@ -136,7 +136,7 @@ impl PassByRefOrValue { } let fn_sig = cx.tcx.fn_sig(def_id).instantiate_identity(); - let fn_body = cx.enclosing_body.map(|id| cx.tcx.hir().body(id)); + let fn_body = cx.enclosing_body.map(|id| cx.tcx.hir_body(id)); // Gather all the lifetimes found in the output type which may affect whether // `TRIVIALLY_COPY_PASS_BY_REF` should be linted. @@ -179,10 +179,10 @@ impl PassByRefOrValue { && let hir::TyKind::Ref(_, MutTy { ty: decl_ty, .. }) = input.kind { if let Some(typeck) = cx.maybe_typeck_results() { - // Don't lint if an unsafe pointer is created. - // TODO: Limit the check only to unsafe pointers to the argument (or part of the argument) + // Don't lint if a raw pointer is created. + // TODO: Limit the check only to raw pointers to the argument (or part of the argument) // which escape the current function. - if typeck.node_types().items().any(|(_, &ty)| ty.is_unsafe_ptr()) + if typeck.node_types().items().any(|(_, &ty)| ty.is_raw_ptr()) || typeck .adjustments() .items() diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs index 7fba4b6a6c8..9b241edf4cc 100644 --- a/src/tools/clippy/clippy_lints/src/ptr.rs +++ b/src/tools/clippy/clippy_lints/src/ptr.rs @@ -583,8 +583,8 @@ fn check_ptr_arg_usage<'tcx>(cx: &LateContext<'tcx>, body: &Body<'tcx>, args: &[ } impl<'tcx> Visitor<'tcx> for V<'_, 'tcx> { type NestedFilter = nested_filter::OnlyBodies; - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } fn visit_anon_const(&mut self, _: &'tcx AnonConst) {} diff --git a/src/tools/clippy/clippy_lints/src/ptr_offset_with_cast.rs b/src/tools/clippy/clippy_lints/src/ptr_offset_with_cast.rs index 808a7e005c6..68ae575c906 100644 --- a/src/tools/clippy/clippy_lints/src/ptr_offset_with_cast.rs +++ b/src/tools/clippy/clippy_lints/src/ptr_offset_with_cast.rs @@ -111,7 +111,7 @@ fn is_expr_ty_usize(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { // Is the type of the expression a raw pointer? fn is_expr_ty_raw_ptr(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { - cx.typeck_results().expr_ty(expr).is_unsafe_ptr() + cx.typeck_results().expr_ty(expr).is_raw_ptr() } fn build_suggestion( diff --git a/src/tools/clippy/clippy_lints/src/redundant_async_block.rs b/src/tools/clippy/clippy_lints/src/redundant_async_block.rs index 65fd312b3a0..bc5e8fd2c25 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_async_block.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_async_block.rs @@ -75,7 +75,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantAsyncBlock { /// any variable by ref. fn desugar_async_block<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<&'tcx Expr<'tcx>> { if let ExprKind::Closure(Closure { body, def_id, kind, .. }) = expr.kind - && let body = cx.tcx.hir().body(*body) + && let body = cx.tcx.hir_body(*body) && matches!( kind, ClosureKind::Coroutine(CoroutineKind::Desugared( diff --git a/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs b/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs index 91d023500ca..1498a49a7a4 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs @@ -90,7 +90,7 @@ fn find_innermost_closure<'tcx>( let mut data = None; while let ExprKind::Closure(closure) = expr.kind - && let body = cx.tcx.hir().body(closure.body) + && let body = cx.tcx.hir_body(closure.body) && { let mut visitor = ReturnVisitor; !visitor.visit_expr(body.value).is_break() @@ -179,7 +179,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall { // Like `async fn`, async closures are wrapped in an additional block // to move all of the closure's arguments into the future. - let async_closure_body = cx.tcx.hir().body(closure.body).value; + let async_closure_body = cx.tcx.hir_body(closure.body).value; let ExprKind::Block(block, _) = async_closure_body.kind else { return; }; @@ -241,8 +241,8 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall { hir_visit::walk_expr(self, expr); } - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } } let mut closure_usage_count = ClosureUsageCount { cx, path, count: 0 }; diff --git a/src/tools/clippy/clippy_lints/src/returns.rs b/src/tools/clippy/clippy_lints/src/returns.rs index a1cf16e6ce9..9f0ea84246d 100644 --- a/src/tools/clippy/clippy_lints/src/returns.rs +++ b/src/tools/clippy/clippy_lints/src/returns.rs @@ -205,7 +205,7 @@ impl<'tcx> LateLintPass<'tcx> for Return { // Ensure this is not the final stmt, otherwise removing it would cause a compile error && let OwnerNode::Item(item) = cx.tcx.hir_owner_node(cx.tcx.hir().get_parent_item(expr.hir_id)) && let ItemKind::Fn { body, .. } = item.kind - && let block = cx.tcx.hir().body(body).value + && let block = cx.tcx.hir_body(body).value && let ExprKind::Block(block, _) = block.kind && !is_inside_let_else(cx.tcx, expr) && let [.., final_stmt] = block.stmts diff --git a/src/tools/clippy/clippy_lints/src/same_name_method.rs b/src/tools/clippy/clippy_lints/src/same_name_method.rs index 29914d4379f..552135b15fd 100644 --- a/src/tools/clippy/clippy_lints/src/same_name_method.rs +++ b/src/tools/clippy/clippy_lints/src/same_name_method.rs @@ -50,9 +50,9 @@ impl<'tcx> LateLintPass<'tcx> for SameNameMethod { fn check_crate_post(&mut self, cx: &LateContext<'tcx>) { let mut map = FxHashMap::<Res, ExistingName>::default(); - for id in cx.tcx.hir().items() { + for id in cx.tcx.hir_free_items() { if matches!(cx.tcx.def_kind(id.owner_id), DefKind::Impl { .. }) - && let item = cx.tcx.hir().item(id) + && let item = cx.tcx.hir_item(id) && let ItemKind::Impl(Impl { items, of_trait, diff --git a/src/tools/clippy/clippy_lints/src/string_patterns.rs b/src/tools/clippy/clippy_lints/src/string_patterns.rs index 3834087f797..694ad4f6347 100644 --- a/src/tools/clippy/clippy_lints/src/string_patterns.rs +++ b/src/tools/clippy/clippy_lints/src/string_patterns.rs @@ -138,7 +138,7 @@ fn get_char_span<'tcx>(cx: &'_ LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Optio fn check_manual_pattern_char_comparison(cx: &LateContext<'_>, method_arg: &Expr<'_>, msrv: &Msrv) { if let ExprKind::Closure(closure) = method_arg.kind - && let body = cx.tcx.hir().body(closure.body) + && let body = cx.tcx.hir_body(closure.body) && let Some(PatKind::Binding(_, binding, ..)) = body.params.first().map(|p| p.pat.kind) { let mut set_char_spans: Vec<Span> = Vec::new(); diff --git a/src/tools/clippy/clippy_lints/src/strings.rs b/src/tools/clippy/clippy_lints/src/strings.rs index 6164a6191db..4a5f143a2d3 100644 --- a/src/tools/clippy/clippy_lints/src/strings.rs +++ b/src/tools/clippy/clippy_lints/src/strings.rs @@ -2,8 +2,8 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_the use clippy_utils::source::{snippet, snippet_with_applicability}; use clippy_utils::ty::is_type_lang_item; use clippy_utils::{ - SpanlessEq, get_expr_use_or_unification_node, get_parent_expr, is_lint_allowed, is_path_diagnostic_item, - method_calls, peel_blocks, + SpanlessEq, get_expr_use_or_unification_node, get_parent_expr, is_lint_allowed, method_calls, path_def_id, + peel_blocks, }; use rustc_errors::Applicability; use rustc_hir::def_id::DefId; @@ -253,8 +253,9 @@ impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes { use rustc_ast::LitKind; if let ExprKind::Call(fun, [bytes_arg]) = e.kind - // Find std::str::converts::from_utf8 - && is_path_diagnostic_item(cx, fun, sym::str_from_utf8) + // Find `std::str::converts::from_utf8` or `std::primitive::str::from_utf8` + && let Some(sym::str_from_utf8 | sym::str_inherent_from_utf8) = + path_def_id(cx, fun).and_then(|id| cx.tcx.get_diagnostic_name(id)) // Find string::as_bytes && let ExprKind::AddrOf(BorrowKind::Ref, _, args) = bytes_arg.kind diff --git a/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs b/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs index e9779d437d4..9326b2adaff 100644 --- a/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs +++ b/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs @@ -66,7 +66,7 @@ impl<'tcx> LateLintPass<'tcx> for SuspiciousImpl { && let parent_fn = cx.tcx.hir().get_parent_item(expr.hir_id).def_id && let hir::Node::ImplItem(impl_item) = cx.tcx.hir_node_by_def_id(parent_fn) && let hir::ImplItemKind::Fn(_, body_id) = impl_item.kind - && let body = cx.tcx.hir().body(body_id) + && let body = cx.tcx.hir_body(body_id) && let parent_fn = cx.tcx.hir().get_parent_item(expr.hir_id).def_id && let Some(trait_ref) = trait_ref_of_method(cx, parent_fn) && let trait_id = trait_ref.path.res.def_id() diff --git a/src/tools/clippy/clippy_lints/src/swap_ptr_to_ref.rs b/src/tools/clippy/clippy_lints/src/swap_ptr_to_ref.rs index 8c5cf93ab6e..ff196355a2e 100644 --- a/src/tools/clippy/clippy_lints/src/swap_ptr_to_ref.rs +++ b/src/tools/clippy/clippy_lints/src/swap_ptr_to_ref.rs @@ -76,7 +76,7 @@ impl LateLintPass<'_> for SwapPtrToRef { fn is_ptr_to_ref(cx: &LateContext<'_>, e: &Expr<'_>, ctxt: SyntaxContext) -> (bool, Option<Span>) { if let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Mut, borrowed_expr) = e.kind && let ExprKind::Unary(UnOp::Deref, derefed_expr) = borrowed_expr.kind - && cx.typeck_results().expr_ty(derefed_expr).is_unsafe_ptr() + && cx.typeck_results().expr_ty(derefed_expr).is_raw_ptr() { ( true, diff --git a/src/tools/clippy/clippy_lints/src/trait_bounds.rs b/src/tools/clippy/clippy_lints/src/trait_bounds.rs index 790e0965198..cbf7b126632 100644 --- a/src/tools/clippy/clippy_lints/src/trait_bounds.rs +++ b/src/tools/clippy/clippy_lints/src/trait_bounds.rs @@ -135,7 +135,7 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds { && let Some(Node::Item(Item { kind: ItemKind::Trait(_, _, _, self_bounds, _), .. - })) = cx.tcx.hir().get_if_local(*def_id) + })) = cx.tcx.hir_get_if_local(*def_id) { if self_bounds_map.is_empty() { for bound in *self_bounds { diff --git a/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs b/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs index 2e97772407f..004ad03e708 100644 --- a/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs +++ b/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs @@ -96,10 +96,10 @@ fn is_any_trait(cx: &LateContext<'_>, t: &hir::Ty<'_>) -> bool { fn get_bounds_if_impl_trait<'tcx>(cx: &LateContext<'tcx>, qpath: &QPath<'_>, id: HirId) -> Option<GenericBounds<'tcx>> { if let Some(did) = cx.qpath_res(qpath, id).opt_def_id() - && let Some(Node::GenericParam(generic_param)) = cx.tcx.hir().get_if_local(did) + && let Some(Node::GenericParam(generic_param)) = cx.tcx.hir_get_if_local(did) && let GenericParamKind::Type { synthetic, .. } = generic_param.kind && synthetic - && let Some(generics) = cx.tcx.hir().get_generics(id.owner.def_id) + && let Some(generics) = cx.tcx.hir_get_generics(id.owner.def_id) && let Some(pred) = generics.bounds_for_param(did.expect_local()).next() { Some(pred.bounds) diff --git a/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs b/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs index 207f2ef4563..529f85be372 100644 --- a/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs +++ b/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs @@ -9,7 +9,6 @@ use rustc_hir::intravisit::{FnKind, Visitor, walk_body, walk_expr}; use rustc_hir::{Body, Expr, ExprKind, FnDecl, HirId, Item, ItemKind, Node, QPath, TyKind}; use rustc_hir_analysis::lower_ty; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::hir::map::Map; use rustc_middle::hir::nested_filter; use rustc_middle::ty::{self, AssocKind, Ty, TyCtxt}; use rustc_session::impl_lint_pass; @@ -275,7 +274,6 @@ fn is_default_method_on_current_ty<'tcx>(tcx: TyCtxt<'tcx>, qpath: QPath<'tcx>, struct CheckCalls<'a, 'tcx> { cx: &'a LateContext<'tcx>, - map: Map<'tcx>, implemented_ty_id: DefId, method_span: Span, } @@ -287,8 +285,8 @@ where type NestedFilter = nested_filter::OnlyBodies; type Result = ControlFlow<()>; - fn nested_visit_map(&mut self) -> Self::Map { - self.map + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) -> ControlFlow<()> { @@ -326,9 +324,9 @@ impl UnconditionalRecursion { .find(|item| { item.kind == AssocKind::Fn && item.def_id.is_local() && item.name == kw::Default }) - && let Some(body_node) = cx.tcx.hir().get_if_local(assoc_item.def_id) + && let Some(body_node) = cx.tcx.hir_get_if_local(assoc_item.def_id) && let Some(body_id) = body_node.body_id() - && let body = cx.tcx.hir().body(body_id) + && let body = cx.tcx.hir_body(body_id) // We don't want to keep it if it has conditional return. && let [return_expr] = get_return_calls_in_body(body).as_slice() && let ExprKind::Call(call_expr, _) = return_expr.kind @@ -380,7 +378,6 @@ impl UnconditionalRecursion { { let mut c = CheckCalls { cx, - map: cx.tcx.hir(), implemented_ty_id, method_span, }; diff --git a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs index b3d26908093..c8e3c46f2f6 100644 --- a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs +++ b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs @@ -245,7 +245,7 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks { // const and static items only need a safety comment if their body is an unsafe block, lint otherwise (&ItemKind::Const(.., body) | &ItemKind::Static(.., body), HasSafetyComment::Yes(pos)) => { if !is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, body.hir_id) { - let body = cx.tcx.hir().body(body); + let body = cx.tcx.hir_body(body); if !matches!( body.value.kind, hir::ExprKind::Block(block, _) if block.rules == BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided) @@ -558,7 +558,7 @@ fn comment_start_before_item_in_mod( // some_item /* comment */ unsafe impl T {} // ^-------^ returns the end of this span // ^---------------^ finally checks comments in this range - let prev_item = cx.tcx.hir().item(parent_mod.item_ids[idx - 1]); + let prev_item = cx.tcx.hir_item(parent_mod.item_ids[idx - 1]); if let Some(sp) = walk_span_to_context(prev_item.span, SyntaxContext::root()) { return Some(sp.hi()); } @@ -605,7 +605,7 @@ fn span_from_macro_expansion_has_safety_comment(cx: &LateContext<'_>, span: Span fn get_body_search_span(cx: &LateContext<'_>) -> Option<Span> { let body = cx.enclosing_body?; let map = cx.tcx.hir(); - let mut span = map.body(body).value.span; + let mut span = cx.tcx.hir_body(body).value.span; let mut maybe_global_var = false; for (_, node) in map.parent_iter(body.hir_id) { match node { diff --git a/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs b/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs index 87478a120dd..67ceac92dbc 100644 --- a/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs +++ b/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs @@ -123,7 +123,7 @@ fn check_arg<'tcx>(cx: &LateContext<'tcx>, arg: &'tcx Expr<'tcx>) -> Option<(Spa && let ty = cx.tcx.instantiate_bound_regions_with_erased(ret_ty) && ty.is_unit() { - let body = cx.tcx.hir().body(body); + let body = cx.tcx.hir_body(body); if let ExprKind::Block(block, _) = body.value.kind && block.expr.is_none() && let Some(stmt) = block.stmts.last() diff --git a/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs b/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs index 00b80e827d8..87f184e13ce 100644 --- a/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs +++ b/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs @@ -84,7 +84,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, local: &'tcx LetStmt<'_>) { if let PatKind::Binding(_, binding_hir_id, ..) = local.pat.kind && let Some(body_id) = cx.enclosing_body.as_ref() { - let body = cx.tcx.hir().body(*body_id); + let body = cx.tcx.hir_body(*body_id); // Collect variable usages let mut visitor = UnitVariableCollector::new(binding_hir_id); diff --git a/src/tools/clippy/clippy_lints/src/unused_async.rs b/src/tools/clippy/clippy_lints/src/unused_async.rs index d00bd7f2b3d..1c1c841e964 100644 --- a/src/tools/clippy/clippy_lints/src/unused_async.rs +++ b/src/tools/clippy/clippy_lints/src/unused_async.rs @@ -101,8 +101,8 @@ impl<'tcx> Visitor<'tcx> for AsyncFnVisitor<'_, 'tcx> { } } - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } } diff --git a/src/tools/clippy/clippy_lints/src/unused_peekable.rs b/src/tools/clippy/clippy_lints/src/unused_peekable.rs index 71aa57e0a14..0f9b05c84d4 100644 --- a/src/tools/clippy/clippy_lints/src/unused_peekable.rs +++ b/src/tools/clippy/clippy_lints/src/unused_peekable.rs @@ -112,8 +112,8 @@ impl<'tcx> Visitor<'tcx> for PeekableVisitor<'_, 'tcx> { type NestedFilter = OnlyBodies; type Result = ControlFlow<()>; - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) -> ControlFlow<()> { diff --git a/src/tools/clippy/clippy_lints/src/unused_self.rs b/src/tools/clippy/clippy_lints/src/unused_self.rs index 781f51aa9b0..d8305a62829 100644 --- a/src/tools/clippy/clippy_lints/src/unused_self.rs +++ b/src/tools/clippy/clippy_lints/src/unused_self.rs @@ -77,7 +77,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedSelf { && assoc_item.fn_has_self_parameter && let ImplItemKind::Fn(.., body_id) = &impl_item.kind && (!cx.effective_visibilities.is_exported(impl_item.owner_id.def_id) || !self.avoid_breaking_exported_api) - && let body = cx.tcx.hir().body(*body_id) + && let body = cx.tcx.hir_body(*body_id) && let [self_param, ..] = body.params && !is_local_used(cx, body, self_param.pat.hir_id) && !contains_todo(cx, body) diff --git a/src/tools/clippy/clippy_lints/src/unwrap.rs b/src/tools/clippy/clippy_lints/src/unwrap.rs index 6a952c0d97a..76b9bbbd32f 100644 --- a/src/tools/clippy/clippy_lints/src/unwrap.rs +++ b/src/tools/clippy/clippy_lints/src/unwrap.rs @@ -374,8 +374,8 @@ impl<'tcx> Visitor<'tcx> for UnwrappableVariablesVisitor<'_, 'tcx> { } } - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } } diff --git a/src/tools/clippy/clippy_lints/src/unwrap_in_result.rs b/src/tools/clippy/clippy_lints/src/unwrap_in_result.rs index 9b9a2ffbbc8..f870eb71e19 100644 --- a/src/tools/clippy/clippy_lints/src/unwrap_in_result.rs +++ b/src/tools/clippy/clippy_lints/src/unwrap_in_result.rs @@ -74,7 +74,7 @@ impl<'tcx> LateLintPass<'tcx> for UnwrapInResult { fn lint_impl_body<'tcx>(cx: &LateContext<'tcx>, impl_span: Span, impl_item: &'tcx hir::ImplItem<'_>) { if let ImplItemKind::Fn(_, body_id) = impl_item.kind { - let body = cx.tcx.hir().body(body_id); + let body = cx.tcx.hir_body(body_id); let typeck = cx.tcx.typeck(impl_item.owner_id.def_id); let mut result = Vec::new(); let _: Option<!> = for_each_expr(cx, body.value, |e| { diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs index 6bad78cf871..ce489054e16 100644 --- a/src/tools/clippy/clippy_lints/src/utils/author.rs +++ b/src/tools/clippy/clippy_lints/src/utils/author.rs @@ -637,9 +637,9 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { } fn body(&self, body_id: &Binding<hir::BodyId>) { - let expr = self.cx.tcx.hir().body(body_id.value).value; + let expr = self.cx.tcx.hir_body(body_id.value).value; bind!(self, expr); - chain!(self, "{expr} = &cx.tcx.hir().body({body_id}).value"); + chain!(self, "{expr} = &cx.tcx.hir_body({body_id}).value"); self.expr(expr); } diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/collapsible_calls.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/collapsible_calls.rs index eaeb754a23f..2e6fb7c4ce4 100644 --- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/collapsible_calls.rs +++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/collapsible_calls.rs @@ -80,7 +80,7 @@ impl<'tcx> LateLintPass<'tcx> for CollapsibleCalls { if let ExprKind::Call(func, [call_cx, call_lint, call_sp, call_msg, call_f]) = expr.kind && is_expr_path_def_path(cx, func, &["clippy_utils", "diagnostics", "span_lint_and_then"]) && let ExprKind::Closure(&Closure { body, .. }) = call_f.kind - && let body = cx.tcx.hir().body(body) + && let body = cx.tcx.hir_body(body) && let only_expr = peel_blocks_with_stmt(body.value) && let ExprKind::MethodCall(ps, recv, span_call_args, _) = &only_expr.kind && let ExprKind::Path(..) = recv.kind diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs index 08c178ed229..252ac5e6768 100644 --- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs +++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs @@ -37,7 +37,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidPaths { ty::TypingEnv::post_analysis(cx.tcx, item.owner_id), cx.tcx.typeck(item.owner_id), ) - .eval_simple(cx.tcx.hir().body(body_id).value) + .eval_simple(cx.tcx.hir_body(body_id).value) && let Some(path) = path .iter() .map(|x| { diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs index dac1951489c..e31da9e9f61 100644 --- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs +++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs @@ -108,7 +108,7 @@ impl<'tcx> LateLintPass<'tcx> for LintWithoutLintPass { if is_lint_ref_type(cx, ty) { check_invalid_clippy_version_attribute(cx, item); - let expr = &cx.tcx.hir().body(body_id).value; + let expr = &cx.tcx.hir_body(body_id).value; let fields = if let ExprKind::AddrOf(_, _, inner_exp) = expr.kind && let ExprKind::Struct(_, struct_fields, _) = inner_exp.kind { @@ -277,7 +277,7 @@ impl<'tcx> Visitor<'tcx> for LintCollector<'_, 'tcx> { } } - fn nested_visit_map(&mut self) -> Self::Map { + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { self.cx.tcx.hir() } } diff --git a/src/tools/clippy/clippy_lints/src/zero_repeat_side_effects.rs b/src/tools/clippy/clippy_lints/src/zero_repeat_side_effects.rs index 05f85650769..30fdf22fdbb 100644 --- a/src/tools/clippy/clippy_lints/src/zero_repeat_side_effects.rs +++ b/src/tools/clippy/clippy_lints/src/zero_repeat_side_effects.rs @@ -47,7 +47,6 @@ declare_lint_pass!(ZeroRepeatSideEffects => [ZERO_REPEAT_SIDE_EFFECTS]); impl LateLintPass<'_> for ZeroRepeatSideEffects { fn check_expr(&mut self, cx: &LateContext<'_>, expr: &rustc_hir::Expr<'_>) { - let hir_map = cx.tcx.hir(); if let Some(args) = VecArgs::hir(cx, expr) && let VecArgs::Repeat(inner_expr, len) = args && let ExprKind::Lit(l) = len.kind @@ -62,7 +61,7 @@ impl LateLintPass<'_> for ZeroRepeatSideEffects { // sessions). else if let ExprKind::Repeat(inner_expr, const_arg) = expr.kind && let ConstArgKind::Anon(anon_const) = const_arg.kind - && let length_expr = hir_map.body(anon_const.body).value + && let length_expr = cx.tcx.hir_body(anon_const.body).value && !length_expr.span.from_expansion() && let ExprKind::Lit(literal) = length_expr.kind && let LitKind::Int(Pu128(0), _) = literal.node diff --git a/src/tools/clippy/clippy_lints/src/zombie_processes.rs b/src/tools/clippy/clippy_lints/src/zombie_processes.rs index 4df34891a2b..9bd00b1e5c8 100644 --- a/src/tools/clippy/clippy_lints/src/zombie_processes.rs +++ b/src/tools/clippy/clippy_lints/src/zombie_processes.rs @@ -249,8 +249,8 @@ impl<'tcx> Visitor<'tcx> for WaitFinder<'_, 'tcx> { walk_expr(self, ex) } - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } } diff --git a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs index 59aaaa3d9fb..4f48fb3b8a9 100644 --- a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs +++ b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs @@ -192,7 +192,7 @@ fn expr_search_pat(tcx: TyCtxt<'_>, e: &Expr<'_>) -> (Pat, Pat) { }, ExprKind::Closure(&Closure { body, .. }) => ( Pat::Str(""), - expr_search_pat_inner(tcx, tcx.hir().body(body).value, outer_span).1, + expr_search_pat_inner(tcx, tcx.hir_body(body).value, outer_span).1, ), ExprKind::Block( Block { diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index db82c458f70..4f707e34abf 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -455,7 +455,7 @@ impl<'tcx> ConstEvalCtxt<'tcx> { Some(val) } }, - PatExprKind::ConstBlock(ConstBlock { body, .. }) => self.expr(self.tcx.hir().body(*body).value), + PatExprKind::ConstBlock(ConstBlock { body, .. }) => self.expr(self.tcx.hir_body(*body).value), PatExprKind::Path(qpath) => self.qpath(qpath, pat_expr.hir_id), } } @@ -483,7 +483,7 @@ impl<'tcx> ConstEvalCtxt<'tcx> { /// Simple constant folding: Insert an expression, get a constant or none. fn expr(&self, e: &Expr<'_>) -> Option<Constant<'tcx>> { match e.kind { - ExprKind::ConstBlock(ConstBlock { body, .. }) => self.expr(self.tcx.hir().body(body).value), + ExprKind::ConstBlock(ConstBlock { body, .. }) => self.expr(self.tcx.hir_body(body).value), ExprKind::DropTemps(e) => self.expr(e), ExprKind::Path(ref qpath) => self.qpath(qpath, e.hir_id), ExprKind::Block(block, _) => self.block(block), @@ -550,7 +550,7 @@ impl<'tcx> ConstEvalCtxt<'tcx> { /// leaves the local crate. pub fn eval_is_empty(&self, e: &Expr<'_>) -> Option<bool> { match e.kind { - ExprKind::ConstBlock(ConstBlock { body, .. }) => self.eval_is_empty(self.tcx.hir().body(body).value), + ExprKind::ConstBlock(ConstBlock { body, .. }) => self.eval_is_empty(self.tcx.hir_body(body).value), ExprKind::DropTemps(e) => self.eval_is_empty(e), ExprKind::Path(ref qpath) => { if !self @@ -645,7 +645,7 @@ impl<'tcx> ConstEvalCtxt<'tcx> { Res::Def(DefKind::Const | DefKind::AssocConst, def_id) => { // Check if this constant is based on `cfg!(..)`, // which is NOT constant for our purposes. - if let Some(node) = self.tcx.hir().get_if_local(def_id) + if let Some(node) = self.tcx.hir_get_if_local(def_id) && let Node::Item(Item { kind: ItemKind::Const(.., body_id), .. 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 b5bb174e737..aaea8d71efb 100644 --- a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs +++ b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs @@ -217,7 +217,7 @@ fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessS self.eagerness |= NoChange; }, // Dereferences should be cheap, but dereferencing a raw pointer earlier may not be safe. - ExprKind::Unary(UnOp::Deref, e) if !self.cx.typeck_results().expr_ty(e).is_unsafe_ptr() => (), + ExprKind::Unary(UnOp::Deref, e) if !self.cx.typeck_results().expr_ty(e).is_raw_ptr() => (), ExprKind::Unary(UnOp::Deref, _) => self.eagerness |= NoChange, ExprKind::Unary(_, e) if matches!( diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index 4bbf28115a6..9ee30094d60 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -273,8 +273,8 @@ impl HirEqInterExpr<'_, '_, '_> { self.inner.cx.tcx.typeck_body(right), )); let res = self.eq_expr( - self.inner.cx.tcx.hir().body(left).value, - self.inner.cx.tcx.hir().body(right).value, + self.inner.cx.tcx.hir_body(left).value, + self.inner.cx.tcx.hir_body(right).value, ); self.inner.maybe_typeck_results = old_maybe_typeck_results; res @@ -906,7 +906,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { }) => { std::mem::discriminant(&capture_clause).hash(&mut self.s); // closures inherit TypeckResults - self.hash_expr(self.cx.tcx.hir().body(body).value); + self.hash_expr(self.cx.tcx.hir_body(body).value); }, ExprKind::ConstBlock(ref l_id) => { self.hash_body(l_id.body); @@ -1316,7 +1316,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { pub fn hash_body(&mut self, body_id: BodyId) { // swap out TypeckResults when hashing a body let old_maybe_typeck_results = self.maybe_typeck_results.replace(self.cx.tcx.typeck_body(body_id)); - self.hash_expr(self.cx.tcx.hir().body(body_id).value); + self.hash_expr(self.cx.tcx.hir_body(body_id).value); self.maybe_typeck_results = old_maybe_typeck_results; } diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 79cc5066580..ccf32f42a47 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -652,8 +652,6 @@ fn non_local_item_children_by_name(tcx: TyCtxt<'_>, def_id: DefId, name: Symbol) } fn local_item_children_by_name(tcx: TyCtxt<'_>, local_id: LocalDefId, name: Symbol) -> Vec<Res> { - let hir = tcx.hir(); - let root_mod; let item_kind = match tcx.hir_node_by_def_id(local_id) { Node::Crate(r#mod) => { @@ -677,7 +675,7 @@ fn local_item_children_by_name(tcx: TyCtxt<'_>, local_id: LocalDefId, name: Symb ItemKind::Mod(r#mod) => r#mod .item_ids .iter() - .filter_map(|&item_id| res(hir.item(item_id).ident, item_id.owner_id)) + .filter_map(|&item_id| res(tcx.hir_item(item_id).ident, item_id.owner_id)) .collect(), ItemKind::Impl(r#impl) => r#impl .items @@ -944,7 +942,7 @@ pub fn is_default_equivalent(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { ExprKind::Tup(items) | ExprKind::Array(items) => items.iter().all(|x| is_default_equivalent(cx, x)), ExprKind::Repeat(x, len) => { if let ConstArgKind::Anon(anon_const) = len.kind - && let ExprKind::Lit(const_lit) = cx.tcx.hir().body(anon_const.body).value.kind + && let ExprKind::Lit(const_lit) = cx.tcx.hir_body(anon_const.body).value.kind && let LitKind::Int(v, _) = const_lit.node && v <= 32 && is_default_equivalent(cx, x) @@ -974,7 +972,7 @@ fn is_default_equivalent_from(cx: &LateContext<'_>, from_func: &Expr<'_>, arg: & ExprKind::Array([]) => return is_path_diagnostic_item(cx, ty, sym::Vec), ExprKind::Repeat(_, len) => { if let ConstArgKind::Anon(anon_const) = len.kind - && let ExprKind::Lit(const_lit) = cx.tcx.hir().body(anon_const.body).value.kind + && let ExprKind::Lit(const_lit) = cx.tcx.hir_body(anon_const.body).value.kind && let LitKind::Int(v, _) = const_lit.node { return v == 0 && is_path_diagnostic_item(cx, ty, sym::Vec); @@ -1372,8 +1370,8 @@ impl<'tcx> Visitor<'tcx> for ContainsName<'_, 'tcx> { } } - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } } @@ -1424,7 +1422,7 @@ pub fn get_enclosing_block<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Optio | Node::ImplItem(&ImplItem { kind: ImplItemKind::Fn(_, eid), .. - }) => match cx.tcx.hir().body(eid).value.kind { + }) => match cx.tcx.hir_body(eid).value.kind { ExprKind::Block(block, _) => Some(block), _ => None, }, @@ -2067,7 +2065,7 @@ pub fn get_async_fn_body<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'_>) -> Option<&'t .. }, _, - ) = tcx.hir().body(body).value.kind + ) = tcx.hir_body(body).value.kind { return Some(expr); } @@ -2175,7 +2173,7 @@ pub fn is_expr_untyped_identity_function(cx: &LateContext<'_>, expr: &Expr<'_>) ExprKind::Closure(&Closure { body, fn_decl, .. }) if fn_decl.inputs.iter().all(|ty| matches!(ty.kind, TyKind::Infer(()))) => { - is_body_identity_function(cx, cx.tcx.hir().body(body)) + is_body_identity_function(cx, cx.tcx.hir_body(body)) }, ExprKind::Path(QPath::Resolved(_, path)) if path.segments.iter().all(|seg| seg.infer_args) @@ -2197,7 +2195,7 @@ pub fn is_expr_untyped_identity_function(cx: &LateContext<'_>, expr: &Expr<'_>) /// errors. pub fn is_expr_identity_function(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { match expr.kind { - ExprKind::Closure(&Closure { body, .. }) => is_body_identity_function(cx, cx.tcx.hir().body(body)), + ExprKind::Closure(&Closure { body, .. }) => is_body_identity_function(cx, cx.tcx.hir_body(body)), _ => path_def_id(cx, expr).is_some_and(|id| cx.tcx.is_diagnostic_item(sym::convert_identity, id)), } } @@ -2552,9 +2550,9 @@ fn with_test_item_names(tcx: TyCtxt<'_>, module: LocalModDefId, f: impl Fn(&[Sym Entry::Occupied(entry) => f(entry.get()), Entry::Vacant(entry) => { let mut names = Vec::new(); - for id in tcx.hir().module_items(module) { + for id in tcx.hir_module_free_items(module) { if matches!(tcx.def_kind(id.owner_id), DefKind::Const) - && let item = tcx.hir().item(id) + && let item = tcx.hir_item(id) && let ItemKind::Const(ty, _generics, _body) = item.kind { if let TyKind::Path(QPath::Resolved(_, path)) = ty.kind { @@ -2932,7 +2930,7 @@ pub fn expr_use_ctxt<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> ExprU #[allow(unreachable_patterns)] Some(ControlFlow::Break(_)) => unreachable!("type of node is ControlFlow<!>"), None => ExprUseCtxt { - node: Node::Crate(cx.tcx.hir().root_module()), + node: Node::Crate(cx.tcx.hir_root_module()), child_id: HirId::INVALID, adjustments: &[], is_ty_unified: true, diff --git a/src/tools/clippy/clippy_utils/src/ptr.rs b/src/tools/clippy/clippy_utils/src/ptr.rs index 273c1b0defa..360c6251a57 100644 --- a/src/tools/clippy/clippy_utils/src/ptr.rs +++ b/src/tools/clippy/clippy_utils/src/ptr.rs @@ -13,7 +13,7 @@ pub fn get_spans( idx: usize, replacements: &[(&'static str, &'static str)], ) -> Option<Vec<(Span, Cow<'static, str>)>> { - if let Some(body) = opt_body_id.map(|id| cx.tcx.hir().body(id)) { + if let Some(body) = opt_body_id.map(|id| cx.tcx.hir_body(id)) { if let PatKind::Binding(_, binding_id, _, _) = strip_pat_refs(body.params[idx].pat).kind { extract_clone_suggestions(cx, binding_id, replacements, body) } else { diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs index 088abd7c479..d5e0e2e3436 100644 --- a/src/tools/clippy/clippy_utils/src/sugg.rs +++ b/src/tools/clippy/clippy_utils/src/sugg.rs @@ -809,7 +809,7 @@ pub fn deref_closure_args(cx: &LateContext<'_>, closure: &hir::Expr<'_>) -> Opti fn_decl, def_id, body, .. }) = closure.kind { - let closure_body = cx.tcx.hir().body(body); + let closure_body = cx.tcx.hir_body(body); // is closure arg a type annotated double reference (i.e.: `|x: &&i32| ...`) // a type annotation is present if param `kind` is different from `TyKind::Infer` let closure_arg_is_type_annotated_double_ref = if let TyKind::Ref(_, MutTy { ty, .. }) = fn_decl.inputs[0].kind diff --git a/src/tools/clippy/clippy_utils/src/usage.rs b/src/tools/clippy/clippy_utils/src/usage.rs index 37f72966892..3bf518f7fe7 100644 --- a/src/tools/clippy/clippy_utils/src/usage.rs +++ b/src/tools/clippy/clippy_utils/src/usage.rs @@ -133,8 +133,8 @@ impl<'tcx> Visitor<'tcx> for BindingUsageFinder<'_, 'tcx> { ControlFlow::Continue(()) } - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } } diff --git a/src/tools/clippy/clippy_utils/src/visitors.rs b/src/tools/clippy/clippy_utils/src/visitors.rs index 99984c41714..2ac0efd7e39 100644 --- a/src/tools/clippy/clippy_utils/src/visitors.rs +++ b/src/tools/clippy/clippy_utils/src/visitors.rs @@ -154,8 +154,8 @@ pub fn for_each_expr<'tcx, B, C: Continue>( type NestedFilter = nested_filter::OnlyBodies; type Result = ControlFlow<B>; - fn nested_visit_map(&mut self) -> Self::Map { - self.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.tcx } fn visit_expr(&mut self, e: &'tcx Expr<'tcx>) -> Self::Result { @@ -296,7 +296,7 @@ where /// Checks if the given resolved path is used in the given body. pub fn is_res_used(cx: &LateContext<'_>, res: Res, body: BodyId) -> bool { - for_each_expr(cx, cx.tcx.hir().body(body).value, |e| { + for_each_expr(cx, cx.tcx.hir_body(body).value, |e| { if let ExprKind::Path(p) = &e.kind { if cx.qpath_res(p, e.hir_id) == res { return ControlFlow::Break(()); @@ -412,12 +412,12 @@ pub fn is_expr_unsafe<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> bool { type NestedFilter = nested_filter::OnlyBodies; type Result = ControlFlow<()>; - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } fn visit_expr(&mut self, e: &'tcx Expr<'_>) -> Self::Result { match e.kind { - ExprKind::Unary(UnOp::Deref, e) if self.cx.typeck_results().expr_ty(e).is_unsafe_ptr() => { + ExprKind::Unary(UnOp::Deref, e) if self.cx.typeck_results().expr_ty(e).is_raw_ptr() => { ControlFlow::Break(()) }, ExprKind::MethodCall(..) @@ -456,7 +456,7 @@ pub fn is_expr_unsafe<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> bool { } } fn visit_nested_item(&mut self, id: ItemId) -> Self::Result { - if let ItemKind::Impl(i) = &self.cx.tcx.hir().item(id).kind + if let ItemKind::Impl(i) = &self.cx.tcx.hir_item(id).kind && i.safety.is_unsafe() { ControlFlow::Break(()) @@ -477,8 +477,8 @@ pub fn contains_unsafe_block<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) impl<'tcx> Visitor<'tcx> for V<'_, 'tcx> { type Result = ControlFlow<()>; type NestedFilter = nested_filter::OnlyBodies; - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } fn visit_block(&mut self, b: &'tcx Block<'_>) -> Self::Result { @@ -544,8 +544,8 @@ pub fn for_each_local_use_after_expr<'tcx, B>( } impl<'tcx, F: FnMut(&'tcx Expr<'tcx>) -> ControlFlow<B>, B> Visitor<'tcx> for V<'_, 'tcx, F, B> { type NestedFilter = nested_filter::OnlyBodies; - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } fn visit_expr(&mut self, e: &'tcx Expr<'tcx>) { @@ -729,8 +729,8 @@ pub fn for_each_local_assignment<'tcx, B>( } impl<'tcx, F: FnMut(&'tcx Expr<'tcx>) -> ControlFlow<B>, B> Visitor<'tcx> for V<'_, 'tcx, F, B> { type NestedFilter = nested_filter::OnlyBodies; - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } fn visit_expr(&mut self, e: &'tcx Expr<'tcx>) { diff --git a/src/tools/clippy/tests/ui-toml/dbg_macro/dbg_macro.stderr b/src/tools/clippy/tests/ui-toml/dbg_macro/dbg_macro.stderr index 129fab5ff97..f0d7104a57d 100644 --- a/src/tools/clippy/tests/ui-toml/dbg_macro/dbg_macro.stderr +++ b/src/tools/clippy/tests/ui-toml/dbg_macro/dbg_macro.stderr @@ -8,8 +8,9 @@ LL | if let Some(n) = dbg!(n.checked_sub(4)) { n } else { n } = help: to override `-D warnings` add `#[allow(clippy::dbg_macro)]` help: remove the invocation before committing it to a version control system | -LL | if let Some(n) = n.checked_sub(4) { n } else { n } - | ~~~~~~~~~~~~~~~~ +LL - if let Some(n) = dbg!(n.checked_sub(4)) { n } else { n } +LL + if let Some(n) = n.checked_sub(4) { n } else { n } + | error: the `dbg!` macro is intended as a debugging tool --> tests/ui-toml/dbg_macro/dbg_macro.rs:10:8 @@ -19,8 +20,9 @@ LL | if dbg!(n <= 1) { | help: remove the invocation before committing it to a version control system | -LL | if n <= 1 { - | ~~~~~~ +LL - if dbg!(n <= 1) { +LL + if n <= 1 { + | error: the `dbg!` macro is intended as a debugging tool --> tests/ui-toml/dbg_macro/dbg_macro.rs:11:9 @@ -30,7 +32,8 @@ LL | dbg!(1) | help: remove the invocation before committing it to a version control system | -LL | 1 +LL - dbg!(1) +LL + 1 | error: the `dbg!` macro is intended as a debugging tool @@ -41,7 +44,8 @@ LL | dbg!(n * factorial(n - 1)) | help: remove the invocation before committing it to a version control system | -LL | n * factorial(n - 1) +LL - dbg!(n * factorial(n - 1)) +LL + n * factorial(n - 1) | error: the `dbg!` macro is intended as a debugging tool @@ -52,8 +56,9 @@ LL | dbg!(42); | help: remove the invocation before committing it to a version control system | -LL | 42; - | ~~ +LL - dbg!(42); +LL + 42; + | error: the `dbg!` macro is intended as a debugging tool --> tests/ui-toml/dbg_macro/dbg_macro.rs:19:14 @@ -63,8 +68,9 @@ LL | foo(3) + dbg!(factorial(4)); | help: remove the invocation before committing it to a version control system | -LL | foo(3) + factorial(4); - | ~~~~~~~~~~~~ +LL - foo(3) + dbg!(factorial(4)); +LL + foo(3) + factorial(4); + | error: the `dbg!` macro is intended as a debugging tool --> tests/ui-toml/dbg_macro/dbg_macro.rs:20:5 @@ -74,8 +80,9 @@ LL | dbg!(1, 2, 3, 4, 5); | help: remove the invocation before committing it to a version control system | -LL | (1, 2, 3, 4, 5); - | ~~~~~~~~~~~~~~~ +LL - dbg!(1, 2, 3, 4, 5); +LL + (1, 2, 3, 4, 5); + | error: aborting due to 7 previous errors diff --git a/src/tools/clippy/tests/ui-toml/doc_valid_idents_append/doc_markdown.stderr b/src/tools/clippy/tests/ui-toml/doc_valid_idents_append/doc_markdown.stderr index a6e0ad0f804..8ba237ee75c 100644 --- a/src/tools/clippy/tests/ui-toml/doc_valid_idents_append/doc_markdown.stderr +++ b/src/tools/clippy/tests/ui-toml/doc_valid_idents_append/doc_markdown.stderr @@ -8,8 +8,9 @@ LL | /// TestItemThingyOfCoolness might sound cool but is not on the list and sh = help: to override `-D warnings` add `#[allow(clippy::doc_markdown)]` help: try | -LL | /// `TestItemThingyOfCoolness` might sound cool but is not on the list and should be linted. - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - /// TestItemThingyOfCoolness might sound cool but is not on the list and should be linted. +LL + /// `TestItemThingyOfCoolness` might sound cool but is not on the list and should be linted. + | error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui-toml/doc_valid_idents_replace/doc_markdown.stderr b/src/tools/clippy/tests/ui-toml/doc_valid_idents_replace/doc_markdown.stderr index d4d8a579798..9f2d7cf54e0 100644 --- a/src/tools/clippy/tests/ui-toml/doc_valid_idents_replace/doc_markdown.stderr +++ b/src/tools/clippy/tests/ui-toml/doc_valid_idents_replace/doc_markdown.stderr @@ -8,8 +8,9 @@ LL | /// OAuth and LaTeX are inside Clippy's default list. = help: to override `-D warnings` add `#[allow(clippy::doc_markdown)]` help: try | -LL | /// `OAuth` and LaTeX are inside Clippy's default list. - | ~~~~~~~ +LL - /// OAuth and LaTeX are inside Clippy's default list. +LL + /// `OAuth` and LaTeX are inside Clippy's default list. + | error: item in documentation is missing backticks --> tests/ui-toml/doc_valid_idents_replace/doc_markdown.rs:6:15 @@ -19,8 +20,9 @@ LL | /// OAuth and LaTeX are inside Clippy's default list. | help: try | -LL | /// OAuth and `LaTeX` are inside Clippy's default list. - | ~~~~~~~ +LL - /// OAuth and LaTeX are inside Clippy's default list. +LL + /// OAuth and `LaTeX` are inside Clippy's default list. + | error: item in documentation is missing backticks --> tests/ui-toml/doc_valid_idents_replace/doc_markdown.rs:9:5 @@ -30,8 +32,9 @@ LL | /// TestItemThingyOfCoolness might sound cool but is not on the list and sh | help: try | -LL | /// `TestItemThingyOfCoolness` might sound cool but is not on the list and should be linted. - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - /// TestItemThingyOfCoolness might sound cool but is not on the list and should be linted. +LL + /// `TestItemThingyOfCoolness` might sound cool but is not on the list and should be linted. + | error: aborting due to 3 previous errors diff --git a/src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.stderr b/src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.stderr index 8f7ebbd9546..020b3cc7878 100644 --- a/src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.stderr +++ b/src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.stderr @@ -14,8 +14,9 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::large_enum_variant)]` help: consider boxing the large fields to reduce the total size of the enum | -LL | B(Box<[u8; 501]>), - | ~~~~~~~~~~~~~~ +LL - B([u8; 501]), +LL + B(Box<[u8; 501]>), + | error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui-toml/renamed_function_params/renamed_function_params.default.stderr b/src/tools/clippy/tests/ui-toml/renamed_function_params/renamed_function_params.default.stderr index 2d700f60759..de9f17520ff 100644 --- a/src/tools/clippy/tests/ui-toml/renamed_function_params/renamed_function_params.default.stderr +++ b/src/tools/clippy/tests/ui-toml/renamed_function_params/renamed_function_params.default.stderr @@ -33,8 +33,9 @@ LL | fn hash_slice<H: Hasher>(date: &[Self], states: &mut H) { | help: consider using the default names | -LL | fn hash_slice<H: Hasher>(data: &[Self], state: &mut H) { - | ~~~~ ~~~~~ +LL - fn hash_slice<H: Hasher>(date: &[Self], states: &mut H) { +LL + fn hash_slice<H: Hasher>(data: &[Self], state: &mut H) { + | error: renamed function parameter of trait impl --> tests/ui-toml/renamed_function_params/renamed_function_params.rs:80:18 diff --git a/src/tools/clippy/tests/ui-toml/renamed_function_params/renamed_function_params.extend.stderr b/src/tools/clippy/tests/ui-toml/renamed_function_params/renamed_function_params.extend.stderr index e57554fa613..bdc4eeaad80 100644 --- a/src/tools/clippy/tests/ui-toml/renamed_function_params/renamed_function_params.extend.stderr +++ b/src/tools/clippy/tests/ui-toml/renamed_function_params/renamed_function_params.extend.stderr @@ -27,8 +27,9 @@ LL | fn hash_slice<H: Hasher>(date: &[Self], states: &mut H) { | help: consider using the default names | -LL | fn hash_slice<H: Hasher>(data: &[Self], state: &mut H) { - | ~~~~ ~~~~~ +LL - fn hash_slice<H: Hasher>(date: &[Self], states: &mut H) { +LL + fn hash_slice<H: Hasher>(data: &[Self], state: &mut H) { + | error: aborting due to 4 previous errors diff --git a/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.stderr b/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.stderr index b58ce9b8af3..2aff276a4a1 100644 --- a/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.stderr +++ b/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.stderr @@ -8,8 +8,9 @@ LL | let _ = boxed_slice.get(1).unwrap(); = help: to override `-D warnings` add `#[allow(clippy::get_unwrap)]` help: using `[]` is clearer and more concise | -LL | let _ = &boxed_slice[1]; - | ~~~~~~~~~~~~~~~ +LL - let _ = boxed_slice.get(1).unwrap(); +LL + let _ = &boxed_slice[1]; + | error: used `unwrap()` on an `Option` value --> tests/ui-toml/unwrap_used/unwrap_used.rs:38:17 @@ -30,8 +31,9 @@ LL | let _ = some_slice.get(0).unwrap(); | help: using `[]` is clearer and more concise | -LL | let _ = &some_slice[0]; - | ~~~~~~~~~~~~~~ +LL - let _ = some_slice.get(0).unwrap(); +LL + let _ = &some_slice[0]; + | error: used `unwrap()` on an `Option` value --> tests/ui-toml/unwrap_used/unwrap_used.rs:39:17 @@ -50,8 +52,9 @@ LL | let _ = some_vec.get(0).unwrap(); | help: using `[]` is clearer and more concise | -LL | let _ = &some_vec[0]; - | ~~~~~~~~~~~~ +LL - let _ = some_vec.get(0).unwrap(); +LL + let _ = &some_vec[0]; + | error: used `unwrap()` on an `Option` value --> tests/ui-toml/unwrap_used/unwrap_used.rs:40:17 @@ -70,8 +73,9 @@ LL | let _ = some_vecdeque.get(0).unwrap(); | help: using `[]` is clearer and more concise | -LL | let _ = &some_vecdeque[0]; - | ~~~~~~~~~~~~~~~~~ +LL - let _ = some_vecdeque.get(0).unwrap(); +LL + let _ = &some_vecdeque[0]; + | error: used `unwrap()` on an `Option` value --> tests/ui-toml/unwrap_used/unwrap_used.rs:41:17 @@ -90,8 +94,9 @@ LL | let _ = some_hashmap.get(&1).unwrap(); | help: using `[]` is clearer and more concise | -LL | let _ = &some_hashmap[&1]; - | ~~~~~~~~~~~~~~~~~ +LL - let _ = some_hashmap.get(&1).unwrap(); +LL + let _ = &some_hashmap[&1]; + | error: used `unwrap()` on an `Option` value --> tests/ui-toml/unwrap_used/unwrap_used.rs:42:17 @@ -110,8 +115,9 @@ LL | let _ = some_btreemap.get(&1).unwrap(); | help: using `[]` is clearer and more concise | -LL | let _ = &some_btreemap[&1]; - | ~~~~~~~~~~~~~~~~~~ +LL - let _ = some_btreemap.get(&1).unwrap(); +LL + let _ = &some_btreemap[&1]; + | error: used `unwrap()` on an `Option` value --> tests/ui-toml/unwrap_used/unwrap_used.rs:43:17 @@ -130,8 +136,9 @@ LL | let _: u8 = *boxed_slice.get(1).unwrap(); | help: using `[]` is clearer and more concise | -LL | let _: u8 = boxed_slice[1]; - | ~~~~~~~~~~~~~~ +LL - let _: u8 = *boxed_slice.get(1).unwrap(); +LL + let _: u8 = boxed_slice[1]; + | error: used `unwrap()` on an `Option` value --> tests/ui-toml/unwrap_used/unwrap_used.rs:47:22 @@ -150,8 +157,9 @@ LL | *boxed_slice.get_mut(0).unwrap() = 1; | help: using `[]` is clearer and more concise | -LL | boxed_slice[0] = 1; - | ~~~~~~~~~~~~~~ +LL - *boxed_slice.get_mut(0).unwrap() = 1; +LL + boxed_slice[0] = 1; + | error: used `unwrap()` on an `Option` value --> tests/ui-toml/unwrap_used/unwrap_used.rs:52:10 @@ -170,8 +178,9 @@ LL | *some_slice.get_mut(0).unwrap() = 1; | help: using `[]` is clearer and more concise | -LL | some_slice[0] = 1; - | ~~~~~~~~~~~~~ +LL - *some_slice.get_mut(0).unwrap() = 1; +LL + some_slice[0] = 1; + | error: used `unwrap()` on an `Option` value --> tests/ui-toml/unwrap_used/unwrap_used.rs:53:10 @@ -190,8 +199,9 @@ LL | *some_vec.get_mut(0).unwrap() = 1; | help: using `[]` is clearer and more concise | -LL | some_vec[0] = 1; - | ~~~~~~~~~~~ +LL - *some_vec.get_mut(0).unwrap() = 1; +LL + some_vec[0] = 1; + | error: used `unwrap()` on an `Option` value --> tests/ui-toml/unwrap_used/unwrap_used.rs:54:10 @@ -210,8 +220,9 @@ LL | *some_vecdeque.get_mut(0).unwrap() = 1; | help: using `[]` is clearer and more concise | -LL | some_vecdeque[0] = 1; - | ~~~~~~~~~~~~~~~~ +LL - *some_vecdeque.get_mut(0).unwrap() = 1; +LL + some_vecdeque[0] = 1; + | error: used `unwrap()` on an `Option` value --> tests/ui-toml/unwrap_used/unwrap_used.rs:55:10 @@ -230,8 +241,9 @@ LL | let _ = some_vec.get(0..1).unwrap().to_vec(); | help: using `[]` is clearer and more concise | -LL | let _ = some_vec[0..1].to_vec(); - | ~~~~~~~~~~~~~~ +LL - let _ = some_vec.get(0..1).unwrap().to_vec(); +LL + let _ = some_vec[0..1].to_vec(); + | error: used `unwrap()` on an `Option` value --> tests/ui-toml/unwrap_used/unwrap_used.rs:67:17 @@ -250,8 +262,9 @@ LL | let _ = some_vec.get_mut(0..1).unwrap().to_vec(); | help: using `[]` is clearer and more concise | -LL | let _ = some_vec[0..1].to_vec(); - | ~~~~~~~~~~~~~~ +LL - let _ = some_vec.get_mut(0..1).unwrap().to_vec(); +LL + let _ = some_vec[0..1].to_vec(); + | error: used `unwrap()` on an `Option` value --> tests/ui-toml/unwrap_used/unwrap_used.rs:68:17 @@ -270,8 +283,9 @@ LL | let _ = boxed_slice.get(1).unwrap(); | help: using `[]` is clearer and more concise | -LL | let _ = &boxed_slice[1]; - | ~~~~~~~~~~~~~~~ +LL - let _ = boxed_slice.get(1).unwrap(); +LL + let _ = &boxed_slice[1]; + | error: called `.get().unwrap()` on a slice --> tests/ui-toml/unwrap_used/unwrap_used.rs:94:17 @@ -281,8 +295,9 @@ LL | let _ = Box::new([0]).get(1).unwrap(); | help: using `[]` is clearer and more concise | -LL | let _ = &Box::new([0])[1]; - | ~~~~~~~~~~~~~~~~~ +LL - let _ = Box::new([0]).get(1).unwrap(); +LL + let _ = &Box::new([0])[1]; + | error: aborting due to 28 previous errors diff --git a/src/tools/clippy/tests/ui/assign_ops2.stderr b/src/tools/clippy/tests/ui/assign_ops2.stderr index ddeba2b2ff8..09b101b216a 100644 --- a/src/tools/clippy/tests/ui/assign_ops2.stderr +++ b/src/tools/clippy/tests/ui/assign_ops2.stderr @@ -8,12 +8,14 @@ LL | a += a + 1; = help: to override `-D warnings` add `#[allow(clippy::misrefactored_assign_op)]` help: did you mean `a = a + 1` or `a = a + a + 1`? Consider replacing it with | -LL | a += 1; - | ~~~~~~ +LL - a += a + 1; +LL + a += 1; + | help: or | -LL | a = a + a + 1; - | ~~~~~~~~~~~~~ +LL - a += a + 1; +LL + a = a + a + 1; + | error: variable appears on both sides of an assignment operation --> tests/ui/assign_ops2.rs:11:5 @@ -23,12 +25,14 @@ LL | a += 1 + a; | help: did you mean `a = a + 1` or `a = a + 1 + a`? Consider replacing it with | -LL | a += 1; - | ~~~~~~ +LL - a += 1 + a; +LL + a += 1; + | help: or | -LL | a = a + 1 + a; - | ~~~~~~~~~~~~~ +LL - a += 1 + a; +LL + a = a + 1 + a; + | error: variable appears on both sides of an assignment operation --> tests/ui/assign_ops2.rs:13:5 @@ -38,12 +42,14 @@ LL | a -= a - 1; | help: did you mean `a = a - 1` or `a = a - (a - 1)`? Consider replacing it with | -LL | a -= 1; - | ~~~~~~ +LL - a -= a - 1; +LL + a -= 1; + | help: or | -LL | a = a - (a - 1); - | ~~~~~~~~~~~~~~~ +LL - a -= a - 1; +LL + a = a - (a - 1); + | error: variable appears on both sides of an assignment operation --> tests/ui/assign_ops2.rs:15:5 @@ -53,12 +59,14 @@ LL | a *= a * 99; | help: did you mean `a = a * 99` or `a = a * a * 99`? Consider replacing it with | -LL | a *= 99; - | ~~~~~~~ +LL - a *= a * 99; +LL + a *= 99; + | help: or | -LL | a = a * a * 99; - | ~~~~~~~~~~~~~~ +LL - a *= a * 99; +LL + a = a * a * 99; + | error: variable appears on both sides of an assignment operation --> tests/ui/assign_ops2.rs:17:5 @@ -68,12 +76,14 @@ LL | a *= 42 * a; | help: did you mean `a = a * 42` or `a = a * 42 * a`? Consider replacing it with | -LL | a *= 42; - | ~~~~~~~ +LL - a *= 42 * a; +LL + a *= 42; + | help: or | -LL | a = a * 42 * a; - | ~~~~~~~~~~~~~~ +LL - a *= 42 * a; +LL + a = a * 42 * a; + | error: variable appears on both sides of an assignment operation --> tests/ui/assign_ops2.rs:19:5 @@ -83,12 +93,14 @@ LL | a /= a / 2; | help: did you mean `a = a / 2` or `a = a / (a / 2)`? Consider replacing it with | -LL | a /= 2; - | ~~~~~~ +LL - a /= a / 2; +LL + a /= 2; + | help: or | -LL | a = a / (a / 2); - | ~~~~~~~~~~~~~~~ +LL - a /= a / 2; +LL + a = a / (a / 2); + | error: variable appears on both sides of an assignment operation --> tests/ui/assign_ops2.rs:21:5 @@ -98,12 +110,14 @@ LL | a %= a % 5; | help: did you mean `a = a % 5` or `a = a % (a % 5)`? Consider replacing it with | -LL | a %= 5; - | ~~~~~~ +LL - a %= a % 5; +LL + a %= 5; + | help: or | -LL | a = a % (a % 5); - | ~~~~~~~~~~~~~~~ +LL - a %= a % 5; +LL + a = a % (a % 5); + | error: variable appears on both sides of an assignment operation --> tests/ui/assign_ops2.rs:23:5 @@ -113,12 +127,14 @@ LL | a &= a & 1; | help: did you mean `a = a & 1` or `a = a & a & 1`? Consider replacing it with | -LL | a &= 1; - | ~~~~~~ +LL - a &= a & 1; +LL + a &= 1; + | help: or | -LL | a = a & a & 1; - | ~~~~~~~~~~~~~ +LL - a &= a & 1; +LL + a = a & a & 1; + | error: variable appears on both sides of an assignment operation --> tests/ui/assign_ops2.rs:25:5 @@ -128,12 +144,14 @@ LL | a *= a * a; | help: did you mean `a = a * a` or `a = a * a * a`? Consider replacing it with | -LL | a *= a; - | ~~~~~~ +LL - a *= a * a; +LL + a *= a; + | help: or | -LL | a = a * a * a; - | ~~~~~~~~~~~~~ +LL - a *= a * a; +LL + a = a * a * a; + | error: manual implementation of an assign operation --> tests/ui/assign_ops2.rs:63:5 diff --git a/src/tools/clippy/tests/ui/author/blocks.stdout b/src/tools/clippy/tests/ui/author/blocks.stdout index 6bf48d5ba4e..54325f9776c 100644 --- a/src/tools/clippy/tests/ui/author/blocks.stdout +++ b/src/tools/clippy/tests/ui/author/blocks.stdout @@ -42,10 +42,10 @@ if let ExprKind::Block(block, None) = expr.kind } if let ExprKind::Closure { capture_clause: CaptureBy::Value { .. }, fn_decl: fn_decl, body: body_id, closure_kind: ClosureKind::CoroutineClosure(CoroutineDesugaring::Async), .. } = expr.kind && let FnRetTy::DefaultReturn(_) = fn_decl.output - && expr1 = &cx.tcx.hir().body(body_id).value + && expr1 = &cx.tcx.hir_body(body_id).value && let ExprKind::Closure { capture_clause: CaptureBy::Ref, fn_decl: fn_decl1, body: body_id1, closure_kind: ClosureKind::Coroutine(CoroutineKind::Desugared(CoroutineDesugaring::Async, CoroutineSource::Closure)), .. } = expr1.kind && let FnRetTy::DefaultReturn(_) = fn_decl1.output - && expr2 = &cx.tcx.hir().body(body_id1).value + && expr2 = &cx.tcx.hir_body(body_id1).value && let ExprKind::Block(block, None) = expr2.kind && block.stmts.is_empty() && let Some(trailing_expr) = block.expr diff --git a/src/tools/clippy/tests/ui/author/macro_in_closure.stdout b/src/tools/clippy/tests/ui/author/macro_in_closure.stdout index 66caf382d89..3186d0cbc27 100644 --- a/src/tools/clippy/tests/ui/author/macro_in_closure.stdout +++ b/src/tools/clippy/tests/ui/author/macro_in_closure.stdout @@ -2,7 +2,7 @@ if let StmtKind::Let(local) = stmt.kind && let Some(init) = local.init && let ExprKind::Closure { capture_clause: CaptureBy::Ref, fn_decl: fn_decl, body: body_id, closure_kind: ClosureKind::Closure, .. } = init.kind && let FnRetTy::DefaultReturn(_) = fn_decl.output - && expr = &cx.tcx.hir().body(body_id).value + && expr = &cx.tcx.hir_body(body_id).value && let ExprKind::Block(block, None) = expr.kind && block.stmts.len() == 1 && let StmtKind::Semi(e) = block.stmts[0].kind diff --git a/src/tools/clippy/tests/ui/author/repeat.stdout b/src/tools/clippy/tests/ui/author/repeat.stdout index 1a608734ada..f2c6b3f807f 100644 --- a/src/tools/clippy/tests/ui/author/repeat.stdout +++ b/src/tools/clippy/tests/ui/author/repeat.stdout @@ -2,7 +2,7 @@ if let ExprKind::Repeat(value, length) = expr.kind && let ExprKind::Lit(ref lit) = value.kind && let LitKind::Int(1, LitIntType::Unsigned(UintTy::U8)) = lit.node && let ConstArgKind::Anon(anon_const) = length.kind - && expr1 = &cx.tcx.hir().body(anon_const.body).value + && expr1 = &cx.tcx.hir_body(anon_const.body).value && let ExprKind::Lit(ref lit1) = expr1.kind && let LitKind::Int(5, LitIntType::Unsuffixed) = lit1.node { diff --git a/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.stderr b/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.stderr index d271381adea..7c5882d4296 100644 --- a/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.stderr +++ b/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.stderr @@ -11,8 +11,9 @@ LL | #![deny(clippy::bind_instead_of_map)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `map` instead | -LL | let _ = Some("42").map(|s| if s.len() < 42 { 0 } else { s.len() }); - | ~~~ ~ ~~~~~~~ +LL - let _ = Some("42").and_then(|s| if s.len() < 42 { Some(0) } else { Some(s.len()) }); +LL + let _ = Some("42").map(|s| if s.len() < 42 { 0 } else { s.len() }); + | error: using `Result.and_then(|x| Ok(y))`, which is more succinctly expressed as `map(|x| y)` --> tests/ui/bind_instead_of_map_multipart.rs:8:13 @@ -22,8 +23,9 @@ LL | let _ = Ok::<_, ()>("42").and_then(|s| if s.len() < 42 { Ok(0) } else { | help: use `map` instead | -LL | let _ = Ok::<_, ()>("42").map(|s| if s.len() < 42 { 0 } else { s.len() }); - | ~~~ ~ ~~~~~~~ +LL - let _ = Ok::<_, ()>("42").and_then(|s| if s.len() < 42 { Ok(0) } else { Ok(s.len()) }); +LL + let _ = Ok::<_, ()>("42").map(|s| if s.len() < 42 { 0 } else { s.len() }); + | error: using `Result.or_else(|x| Err(y))`, which is more succinctly expressed as `map_err(|x| y)` --> tests/ui/bind_instead_of_map_multipart.rs:11:13 @@ -33,8 +35,9 @@ LL | let _ = Err::<(), _>("42").or_else(|s| if s.len() < 42 { Err(s.len() + | help: use `map_err` instead | -LL | let _ = Err::<(), _>("42").map_err(|s| if s.len() < 42 { s.len() + 20 } else { s.len() }); - | ~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~ +LL - let _ = Err::<(), _>("42").or_else(|s| if s.len() < 42 { Err(s.len() + 20) } else { Err(s.len()) }); +LL + let _ = Err::<(), _>("42").map_err(|s| if s.len() < 42 { s.len() + 20 } else { s.len() }); + | error: using `Option.and_then(|x| Some(y))`, which is more succinctly expressed as `map(|x| y)` --> tests/ui/bind_instead_of_map_multipart.rs:19:5 @@ -83,8 +86,9 @@ LL | let _ = Some("").and_then(|s| if s.len() == 20 { Some(m!()) } else { So | help: use `map` instead | -LL | let _ = Some("").map(|s| if s.len() == 20 { m!() } else { Some(20) }); - | ~~~ ~~~~ ~~~~~~~~ +LL - let _ = Some("").and_then(|s| if s.len() == 20 { Some(m!()) } else { Some(Some(20)) }); +LL + let _ = Some("").map(|s| if s.len() == 20 { m!() } else { Some(20) }); + | error: aborting due to 5 previous errors diff --git a/src/tools/clippy/tests/ui/borrow_deref_ref_unfixable.stderr b/src/tools/clippy/tests/ui/borrow_deref_ref_unfixable.stderr index 7d3a5c84a82..71f43af46c2 100644 --- a/src/tools/clippy/tests/ui/borrow_deref_ref_unfixable.stderr +++ b/src/tools/clippy/tests/ui/borrow_deref_ref_unfixable.stderr @@ -8,12 +8,14 @@ LL | let x: &str = &*s; = help: to override `-D warnings` add `#[allow(clippy::borrow_deref_ref)]` help: if you would like to reborrow, try removing `&*` | -LL | let x: &str = s; - | ~ +LL - let x: &str = &*s; +LL + let x: &str = s; + | help: if you would like to deref, try using `&**` | -LL | let x: &str = &**s; - | ~~~~ +LL - let x: &str = &*s; +LL + let x: &str = &**s; + | error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/cast.stderr b/src/tools/clippy/tests/ui/cast.stderr index 452482fc88e..901447c738e 100644 --- a/src/tools/clippy/tests/ui/cast.stderr +++ b/src/tools/clippy/tests/ui/cast.stderr @@ -81,8 +81,9 @@ LL | 1i32 as i8; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | i8::try_from(1i32); - | ~~~~~~~~~~~~~~~~~~ +LL - 1i32 as i8; +LL + i8::try_from(1i32); + | error: casting `i32` to `u8` may truncate the value --> tests/ui/cast.rs:52:5 @@ -93,8 +94,9 @@ LL | 1i32 as u8; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | u8::try_from(1i32); - | ~~~~~~~~~~~~~~~~~~ +LL - 1i32 as u8; +LL + u8::try_from(1i32); + | error: casting `f64` to `isize` may truncate the value --> tests/ui/cast.rs:54:5 @@ -127,8 +129,9 @@ LL | 1f32 as u32 as u16; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | u16::try_from(1f32 as u32); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - 1f32 as u32 as u16; +LL + u16::try_from(1f32 as u32); + | error: casting `f32` to `u32` may truncate the value --> tests/ui/cast.rs:59:5 @@ -153,8 +156,9 @@ LL | let _x: i8 = 1i32 as _; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | let _x: i8 = 1i32.try_into(); - | ~~~~~~~~~~~~~~~ +LL - let _x: i8 = 1i32 as _; +LL + let _x: i8 = 1i32.try_into(); + | error: casting `f32` to `i32` may truncate the value --> tests/ui/cast.rs:66:9 @@ -228,8 +232,9 @@ LL | 1usize as i8; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | i8::try_from(1usize); - | ~~~~~~~~~~~~~~~~~~~~ +LL - 1usize as i8; +LL + i8::try_from(1usize); + | error: casting `usize` to `i16` may truncate the value --> tests/ui/cast.rs:90:5 @@ -240,8 +245,9 @@ LL | 1usize as i16; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | i16::try_from(1usize); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - 1usize as i16; +LL + i16::try_from(1usize); + | error: casting `usize` to `i16` may wrap around the value on targets with 16-bit wide pointers --> tests/ui/cast.rs:90:5 @@ -261,8 +267,9 @@ LL | 1usize as i32; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | i32::try_from(1usize); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - 1usize as i32; +LL + i32::try_from(1usize); + | error: casting `usize` to `i32` may wrap around the value on targets with 32-bit wide pointers --> tests/ui/cast.rs:95:5 @@ -300,8 +307,9 @@ LL | 1u64 as isize; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | isize::try_from(1u64); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - 1u64 as isize; +LL + isize::try_from(1u64); + | error: casting `u64` to `isize` may wrap around the value on targets with 64-bit wide pointers --> tests/ui/cast.rs:111:5 @@ -360,8 +368,9 @@ LL | (-99999999999i64).min(1) as i8; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | i8::try_from((-99999999999i64).min(1)); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - (-99999999999i64).min(1) as i8; +LL + i8::try_from((-99999999999i64).min(1)); + | error: casting `u64` to `u8` may truncate the value --> tests/ui/cast.rs:222:5 @@ -372,8 +381,9 @@ LL | 999999u64.clamp(0, 256) as u8; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | u8::try_from(999999u64.clamp(0, 256)); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - 999999u64.clamp(0, 256) as u8; +LL + u8::try_from(999999u64.clamp(0, 256)); + | error: casting `main::E2` to `u8` may truncate the value --> tests/ui/cast.rs:245:21 @@ -384,8 +394,9 @@ LL | let _ = self as u8; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | let _ = u8::try_from(self); - | ~~~~~~~~~~~~~~~~~~ +LL - let _ = self as u8; +LL + let _ = u8::try_from(self); + | error: casting `main::E2::B` to `u8` will truncate the value --> tests/ui/cast.rs:247:21 @@ -405,8 +416,9 @@ LL | let _ = self as i8; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | let _ = i8::try_from(self); - | ~~~~~~~~~~~~~~~~~~ +LL - let _ = self as i8; +LL + let _ = i8::try_from(self); + | error: casting `main::E5::A` to `i8` will truncate the value --> tests/ui/cast.rs:291:21 @@ -423,8 +435,9 @@ LL | let _ = self as i16; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | let _ = i16::try_from(self); - | ~~~~~~~~~~~~~~~~~~~ +LL - let _ = self as i16; +LL + let _ = i16::try_from(self); + | error: casting `main::E7` to `usize` may truncate the value on targets with 32-bit wide pointers --> tests/ui/cast.rs:327:21 @@ -435,8 +448,9 @@ LL | let _ = self as usize; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | let _ = usize::try_from(self); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - let _ = self as usize; +LL + let _ = usize::try_from(self); + | error: casting `main::E10` to `u16` may truncate the value --> tests/ui/cast.rs:374:21 @@ -447,8 +461,9 @@ LL | let _ = self as u16; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | let _ = u16::try_from(self); - | ~~~~~~~~~~~~~~~~~~~ +LL - let _ = self as u16; +LL + let _ = u16::try_from(self); + | error: casting `u32` to `u8` may truncate the value --> tests/ui/cast.rs:385:13 @@ -459,8 +474,9 @@ LL | let c = (q >> 16) as u8; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | let c = u8::try_from(q >> 16); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - let c = (q >> 16) as u8; +LL + let c = u8::try_from(q >> 16); + | error: casting `u32` to `u8` may truncate the value --> tests/ui/cast.rs:389:13 @@ -471,8 +487,9 @@ LL | let c = (q / 1000) as u8; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | let c = u8::try_from(q / 1000); - | ~~~~~~~~~~~~~~~~~~~~~~ +LL - let c = (q / 1000) as u8; +LL + let c = u8::try_from(q / 1000); + | error: casting `i32` to `u32` may lose the sign of the value --> tests/ui/cast.rs:401:9 @@ -674,8 +691,9 @@ LL | m!(); = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) help: ... or use `try_from` and handle the error accordingly | -LL | let _ = u8::try_from(u32::MAX); // cast_possible_truncation - | ~~~~~~~~~~~~~~~~~~~~~~ +LL - let _ = u32::MAX as u8; // cast_possible_truncation +LL + let _ = u8::try_from(u32::MAX); // cast_possible_truncation + | error: casting `f64` to `f32` may truncate the value --> tests/ui/cast.rs:474:21 @@ -698,7 +716,8 @@ LL | bar.unwrap().unwrap() as usize = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | usize::try_from(bar.unwrap().unwrap()) +LL - bar.unwrap().unwrap() as usize +LL + usize::try_from(bar.unwrap().unwrap()) | error: casting `i64` to `usize` may lose the sign of the value @@ -716,8 +735,9 @@ LL | (256 & 999999u64) as u8; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | u8::try_from(256 & 999999u64); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - (256 & 999999u64) as u8; +LL + u8::try_from(256 & 999999u64); + | error: casting `u64` to `u8` may truncate the value --> tests/ui/cast.rs:500:5 @@ -728,8 +748,9 @@ LL | (255 % 999999u64) as u8; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | u8::try_from(255 % 999999u64); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - (255 % 999999u64) as u8; +LL + u8::try_from(255 % 999999u64); + | error: aborting due to 92 previous errors diff --git a/src/tools/clippy/tests/ui/cast_lossless_bool.stderr b/src/tools/clippy/tests/ui/cast_lossless_bool.stderr index 82d6b2e4b8e..68992271762 100644 --- a/src/tools/clippy/tests/ui/cast_lossless_bool.stderr +++ b/src/tools/clippy/tests/ui/cast_lossless_bool.stderr @@ -9,8 +9,9 @@ LL | let _ = true as u8; = help: to override `-D warnings` add `#[allow(clippy::cast_lossless)]` help: use `u8::from` instead | -LL | let _ = u8::from(true); - | ~~~~~~~~~~~~~~ +LL - let _ = true as u8; +LL + let _ = u8::from(true); + | error: casts from `bool` to `u16` can be expressed infallibly using `From` --> tests/ui/cast_lossless_bool.rs:9:13 @@ -21,8 +22,9 @@ LL | let _ = true as u16; = help: an `as` cast can become silently lossy if the types change in the future help: use `u16::from` instead | -LL | let _ = u16::from(true); - | ~~~~~~~~~~~~~~~ +LL - let _ = true as u16; +LL + let _ = u16::from(true); + | error: casts from `bool` to `u32` can be expressed infallibly using `From` --> tests/ui/cast_lossless_bool.rs:10:13 @@ -33,8 +35,9 @@ LL | let _ = true as u32; = help: an `as` cast can become silently lossy if the types change in the future help: use `u32::from` instead | -LL | let _ = u32::from(true); - | ~~~~~~~~~~~~~~~ +LL - let _ = true as u32; +LL + let _ = u32::from(true); + | error: casts from `bool` to `u64` can be expressed infallibly using `From` --> tests/ui/cast_lossless_bool.rs:11:13 @@ -45,8 +48,9 @@ LL | let _ = true as u64; = help: an `as` cast can become silently lossy if the types change in the future help: use `u64::from` instead | -LL | let _ = u64::from(true); - | ~~~~~~~~~~~~~~~ +LL - let _ = true as u64; +LL + let _ = u64::from(true); + | error: casts from `bool` to `u128` can be expressed infallibly using `From` --> tests/ui/cast_lossless_bool.rs:12:13 @@ -57,8 +61,9 @@ LL | let _ = true as u128; = help: an `as` cast can become silently lossy if the types change in the future help: use `u128::from` instead | -LL | let _ = u128::from(true); - | ~~~~~~~~~~~~~~~~ +LL - let _ = true as u128; +LL + let _ = u128::from(true); + | error: casts from `bool` to `usize` can be expressed infallibly using `From` --> tests/ui/cast_lossless_bool.rs:13:13 @@ -69,8 +74,9 @@ LL | let _ = true as usize; = help: an `as` cast can become silently lossy if the types change in the future help: use `usize::from` instead | -LL | let _ = usize::from(true); - | ~~~~~~~~~~~~~~~~~ +LL - let _ = true as usize; +LL + let _ = usize::from(true); + | error: casts from `bool` to `i8` can be expressed infallibly using `From` --> tests/ui/cast_lossless_bool.rs:15:13 @@ -81,8 +87,9 @@ LL | let _ = true as i8; = help: an `as` cast can become silently lossy if the types change in the future help: use `i8::from` instead | -LL | let _ = i8::from(true); - | ~~~~~~~~~~~~~~ +LL - let _ = true as i8; +LL + let _ = i8::from(true); + | error: casts from `bool` to `i16` can be expressed infallibly using `From` --> tests/ui/cast_lossless_bool.rs:16:13 @@ -93,8 +100,9 @@ LL | let _ = true as i16; = help: an `as` cast can become silently lossy if the types change in the future help: use `i16::from` instead | -LL | let _ = i16::from(true); - | ~~~~~~~~~~~~~~~ +LL - let _ = true as i16; +LL + let _ = i16::from(true); + | error: casts from `bool` to `i32` can be expressed infallibly using `From` --> tests/ui/cast_lossless_bool.rs:17:13 @@ -105,8 +113,9 @@ LL | let _ = true as i32; = help: an `as` cast can become silently lossy if the types change in the future help: use `i32::from` instead | -LL | let _ = i32::from(true); - | ~~~~~~~~~~~~~~~ +LL - let _ = true as i32; +LL + let _ = i32::from(true); + | error: casts from `bool` to `i64` can be expressed infallibly using `From` --> tests/ui/cast_lossless_bool.rs:18:13 @@ -117,8 +126,9 @@ LL | let _ = true as i64; = help: an `as` cast can become silently lossy if the types change in the future help: use `i64::from` instead | -LL | let _ = i64::from(true); - | ~~~~~~~~~~~~~~~ +LL - let _ = true as i64; +LL + let _ = i64::from(true); + | error: casts from `bool` to `i128` can be expressed infallibly using `From` --> tests/ui/cast_lossless_bool.rs:19:13 @@ -129,8 +139,9 @@ LL | let _ = true as i128; = help: an `as` cast can become silently lossy if the types change in the future help: use `i128::from` instead | -LL | let _ = i128::from(true); - | ~~~~~~~~~~~~~~~~ +LL - let _ = true as i128; +LL + let _ = i128::from(true); + | error: casts from `bool` to `isize` can be expressed infallibly using `From` --> tests/ui/cast_lossless_bool.rs:20:13 @@ -141,8 +152,9 @@ LL | let _ = true as isize; = help: an `as` cast can become silently lossy if the types change in the future help: use `isize::from` instead | -LL | let _ = isize::from(true); - | ~~~~~~~~~~~~~~~~~ +LL - let _ = true as isize; +LL + let _ = isize::from(true); + | error: casts from `bool` to `u16` can be expressed infallibly using `From` --> tests/ui/cast_lossless_bool.rs:23:13 @@ -153,8 +165,9 @@ LL | let _ = (true | false) as u16; = help: an `as` cast can become silently lossy if the types change in the future help: use `u16::from` instead | -LL | let _ = u16::from(true | false); - | ~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _ = (true | false) as u16; +LL + let _ = u16::from(true | false); + | error: casts from `bool` to `u8` can be expressed infallibly using `From` --> tests/ui/cast_lossless_bool.rs:25:13 @@ -165,8 +178,9 @@ LL | let _ = true as U8; = help: an `as` cast can become silently lossy if the types change in the future help: use `U8::from` instead | -LL | let _ = U8::from(true); - | ~~~~~~~~~~~~~~ +LL - let _ = true as U8; +LL + let _ = U8::from(true); + | error: casts from `bool` to `u8` can be expressed infallibly using `From` --> tests/ui/cast_lossless_bool.rs:53:13 @@ -177,8 +191,9 @@ LL | let _ = true as u8; = help: an `as` cast can become silently lossy if the types change in the future help: use `u8::from` instead | -LL | let _ = u8::from(true); - | ~~~~~~~~~~~~~~ +LL - let _ = true as u8; +LL + let _ = u8::from(true); + | error: aborting due to 15 previous errors diff --git a/src/tools/clippy/tests/ui/cast_lossless_float.stderr b/src/tools/clippy/tests/ui/cast_lossless_float.stderr index b36f8bcecf5..3f405e3f402 100644 --- a/src/tools/clippy/tests/ui/cast_lossless_float.stderr +++ b/src/tools/clippy/tests/ui/cast_lossless_float.stderr @@ -9,8 +9,9 @@ LL | let _ = x0 as f32; = help: to override `-D warnings` add `#[allow(clippy::cast_lossless)]` help: use `f32::from` instead | -LL | let _ = f32::from(x0); - | ~~~~~~~~~~~~~ +LL - let _ = x0 as f32; +LL + let _ = f32::from(x0); + | error: casts from `i8` to `f64` can be expressed infallibly using `From` --> tests/ui/cast_lossless_float.rs:13:13 @@ -21,8 +22,9 @@ LL | let _ = x0 as f64; = help: an `as` cast can become silently lossy if the types change in the future help: use `f64::from` instead | -LL | let _ = f64::from(x0); - | ~~~~~~~~~~~~~ +LL - let _ = x0 as f64; +LL + let _ = f64::from(x0); + | error: casts from `i8` to `f32` can be expressed infallibly using `From` --> tests/ui/cast_lossless_float.rs:14:13 @@ -33,8 +35,9 @@ LL | let _ = x0 as F32; = help: an `as` cast can become silently lossy if the types change in the future help: use `F32::from` instead | -LL | let _ = F32::from(x0); - | ~~~~~~~~~~~~~ +LL - let _ = x0 as F32; +LL + let _ = F32::from(x0); + | error: casts from `i8` to `f64` can be expressed infallibly using `From` --> tests/ui/cast_lossless_float.rs:15:13 @@ -45,8 +48,9 @@ LL | let _ = x0 as F64; = help: an `as` cast can become silently lossy if the types change in the future help: use `F64::from` instead | -LL | let _ = F64::from(x0); - | ~~~~~~~~~~~~~ +LL - let _ = x0 as F64; +LL + let _ = F64::from(x0); + | error: casts from `u8` to `f32` can be expressed infallibly using `From` --> tests/ui/cast_lossless_float.rs:17:13 @@ -57,8 +61,9 @@ LL | let _ = x1 as f32; = help: an `as` cast can become silently lossy if the types change in the future help: use `f32::from` instead | -LL | let _ = f32::from(x1); - | ~~~~~~~~~~~~~ +LL - let _ = x1 as f32; +LL + let _ = f32::from(x1); + | error: casts from `u8` to `f64` can be expressed infallibly using `From` --> tests/ui/cast_lossless_float.rs:18:13 @@ -69,8 +74,9 @@ LL | let _ = x1 as f64; = help: an `as` cast can become silently lossy if the types change in the future help: use `f64::from` instead | -LL | let _ = f64::from(x1); - | ~~~~~~~~~~~~~ +LL - let _ = x1 as f64; +LL + let _ = f64::from(x1); + | error: casts from `i16` to `f32` can be expressed infallibly using `From` --> tests/ui/cast_lossless_float.rs:20:13 @@ -81,8 +87,9 @@ LL | let _ = x2 as f32; = help: an `as` cast can become silently lossy if the types change in the future help: use `f32::from` instead | -LL | let _ = f32::from(x2); - | ~~~~~~~~~~~~~ +LL - let _ = x2 as f32; +LL + let _ = f32::from(x2); + | error: casts from `i16` to `f64` can be expressed infallibly using `From` --> tests/ui/cast_lossless_float.rs:21:13 @@ -93,8 +100,9 @@ LL | let _ = x2 as f64; = help: an `as` cast can become silently lossy if the types change in the future help: use `f64::from` instead | -LL | let _ = f64::from(x2); - | ~~~~~~~~~~~~~ +LL - let _ = x2 as f64; +LL + let _ = f64::from(x2); + | error: casts from `u16` to `f32` can be expressed infallibly using `From` --> tests/ui/cast_lossless_float.rs:23:13 @@ -105,8 +113,9 @@ LL | let _ = x3 as f32; = help: an `as` cast can become silently lossy if the types change in the future help: use `f32::from` instead | -LL | let _ = f32::from(x3); - | ~~~~~~~~~~~~~ +LL - let _ = x3 as f32; +LL + let _ = f32::from(x3); + | error: casts from `u16` to `f64` can be expressed infallibly using `From` --> tests/ui/cast_lossless_float.rs:24:13 @@ -117,8 +126,9 @@ LL | let _ = x3 as f64; = help: an `as` cast can become silently lossy if the types change in the future help: use `f64::from` instead | -LL | let _ = f64::from(x3); - | ~~~~~~~~~~~~~ +LL - let _ = x3 as f64; +LL + let _ = f64::from(x3); + | error: casts from `i32` to `f64` can be expressed infallibly using `From` --> tests/ui/cast_lossless_float.rs:26:13 @@ -129,8 +139,9 @@ LL | let _ = x4 as f64; = help: an `as` cast can become silently lossy if the types change in the future help: use `f64::from` instead | -LL | let _ = f64::from(x4); - | ~~~~~~~~~~~~~ +LL - let _ = x4 as f64; +LL + let _ = f64::from(x4); + | error: casts from `u32` to `f64` can be expressed infallibly using `From` --> tests/ui/cast_lossless_float.rs:28:13 @@ -141,8 +152,9 @@ LL | let _ = x5 as f64; = help: an `as` cast can become silently lossy if the types change in the future help: use `f64::from` instead | -LL | let _ = f64::from(x5); - | ~~~~~~~~~~~~~ +LL - let _ = x5 as f64; +LL + let _ = f64::from(x5); + | error: casts from `f32` to `f64` can be expressed infallibly using `From` --> tests/ui/cast_lossless_float.rs:31:13 @@ -153,8 +165,9 @@ LL | let _ = 1.0f32 as f64; = help: an `as` cast can become silently lossy if the types change in the future help: use `f64::from` instead | -LL | let _ = f64::from(1.0f32); - | ~~~~~~~~~~~~~~~~~ +LL - let _ = 1.0f32 as f64; +LL + let _ = f64::from(1.0f32); + | error: aborting due to 13 previous errors diff --git a/src/tools/clippy/tests/ui/cast_lossless_integer.stderr b/src/tools/clippy/tests/ui/cast_lossless_integer.stderr index c93ecb8fb56..d2580913bb5 100644 --- a/src/tools/clippy/tests/ui/cast_lossless_integer.stderr +++ b/src/tools/clippy/tests/ui/cast_lossless_integer.stderr @@ -9,8 +9,9 @@ LL | 0u8 as u16; = help: to override `-D warnings` add `#[allow(clippy::cast_lossless)]` help: use `u16::from` instead | -LL | u16::from(0u8); - | ~~~~~~~~~~~~~~ +LL - 0u8 as u16; +LL + u16::from(0u8); + | error: casts from `u8` to `i16` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:10:5 @@ -21,8 +22,9 @@ LL | 0u8 as i16; = help: an `as` cast can become silently lossy if the types change in the future help: use `i16::from` instead | -LL | i16::from(0u8); - | ~~~~~~~~~~~~~~ +LL - 0u8 as i16; +LL + i16::from(0u8); + | error: casts from `u8` to `u32` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:12:5 @@ -33,8 +35,9 @@ LL | 0u8 as u32; = help: an `as` cast can become silently lossy if the types change in the future help: use `u32::from` instead | -LL | u32::from(0u8); - | ~~~~~~~~~~~~~~ +LL - 0u8 as u32; +LL + u32::from(0u8); + | error: casts from `u8` to `i32` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:14:5 @@ -45,8 +48,9 @@ LL | 0u8 as i32; = help: an `as` cast can become silently lossy if the types change in the future help: use `i32::from` instead | -LL | i32::from(0u8); - | ~~~~~~~~~~~~~~ +LL - 0u8 as i32; +LL + i32::from(0u8); + | error: casts from `u8` to `u64` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:16:5 @@ -57,8 +61,9 @@ LL | 0u8 as u64; = help: an `as` cast can become silently lossy if the types change in the future help: use `u64::from` instead | -LL | u64::from(0u8); - | ~~~~~~~~~~~~~~ +LL - 0u8 as u64; +LL + u64::from(0u8); + | error: casts from `u8` to `i64` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:18:5 @@ -69,8 +74,9 @@ LL | 0u8 as i64; = help: an `as` cast can become silently lossy if the types change in the future help: use `i64::from` instead | -LL | i64::from(0u8); - | ~~~~~~~~~~~~~~ +LL - 0u8 as i64; +LL + i64::from(0u8); + | error: casts from `u8` to `u128` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:20:5 @@ -81,8 +87,9 @@ LL | 0u8 as u128; = help: an `as` cast can become silently lossy if the types change in the future help: use `u128::from` instead | -LL | u128::from(0u8); - | ~~~~~~~~~~~~~~~ +LL - 0u8 as u128; +LL + u128::from(0u8); + | error: casts from `u8` to `i128` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:22:5 @@ -93,8 +100,9 @@ LL | 0u8 as i128; = help: an `as` cast can become silently lossy if the types change in the future help: use `i128::from` instead | -LL | i128::from(0u8); - | ~~~~~~~~~~~~~~~ +LL - 0u8 as i128; +LL + i128::from(0u8); + | error: casts from `u16` to `u32` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:25:5 @@ -105,8 +113,9 @@ LL | 0u16 as u32; = help: an `as` cast can become silently lossy if the types change in the future help: use `u32::from` instead | -LL | u32::from(0u16); - | ~~~~~~~~~~~~~~~ +LL - 0u16 as u32; +LL + u32::from(0u16); + | error: casts from `u16` to `i32` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:27:5 @@ -117,8 +126,9 @@ LL | 0u16 as i32; = help: an `as` cast can become silently lossy if the types change in the future help: use `i32::from` instead | -LL | i32::from(0u16); - | ~~~~~~~~~~~~~~~ +LL - 0u16 as i32; +LL + i32::from(0u16); + | error: casts from `u16` to `u64` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:29:5 @@ -129,8 +139,9 @@ LL | 0u16 as u64; = help: an `as` cast can become silently lossy if the types change in the future help: use `u64::from` instead | -LL | u64::from(0u16); - | ~~~~~~~~~~~~~~~ +LL - 0u16 as u64; +LL + u64::from(0u16); + | error: casts from `u16` to `i64` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:31:5 @@ -141,8 +152,9 @@ LL | 0u16 as i64; = help: an `as` cast can become silently lossy if the types change in the future help: use `i64::from` instead | -LL | i64::from(0u16); - | ~~~~~~~~~~~~~~~ +LL - 0u16 as i64; +LL + i64::from(0u16); + | error: casts from `u16` to `u128` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:33:5 @@ -153,8 +165,9 @@ LL | 0u16 as u128; = help: an `as` cast can become silently lossy if the types change in the future help: use `u128::from` instead | -LL | u128::from(0u16); - | ~~~~~~~~~~~~~~~~ +LL - 0u16 as u128; +LL + u128::from(0u16); + | error: casts from `u16` to `i128` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:35:5 @@ -165,8 +178,9 @@ LL | 0u16 as i128; = help: an `as` cast can become silently lossy if the types change in the future help: use `i128::from` instead | -LL | i128::from(0u16); - | ~~~~~~~~~~~~~~~~ +LL - 0u16 as i128; +LL + i128::from(0u16); + | error: casts from `u32` to `u64` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:38:5 @@ -177,8 +191,9 @@ LL | 0u32 as u64; = help: an `as` cast can become silently lossy if the types change in the future help: use `u64::from` instead | -LL | u64::from(0u32); - | ~~~~~~~~~~~~~~~ +LL - 0u32 as u64; +LL + u64::from(0u32); + | error: casts from `u32` to `i64` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:40:5 @@ -189,8 +204,9 @@ LL | 0u32 as i64; = help: an `as` cast can become silently lossy if the types change in the future help: use `i64::from` instead | -LL | i64::from(0u32); - | ~~~~~~~~~~~~~~~ +LL - 0u32 as i64; +LL + i64::from(0u32); + | error: casts from `u32` to `u128` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:42:5 @@ -201,8 +217,9 @@ LL | 0u32 as u128; = help: an `as` cast can become silently lossy if the types change in the future help: use `u128::from` instead | -LL | u128::from(0u32); - | ~~~~~~~~~~~~~~~~ +LL - 0u32 as u128; +LL + u128::from(0u32); + | error: casts from `u32` to `i128` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:44:5 @@ -213,8 +230,9 @@ LL | 0u32 as i128; = help: an `as` cast can become silently lossy if the types change in the future help: use `i128::from` instead | -LL | i128::from(0u32); - | ~~~~~~~~~~~~~~~~ +LL - 0u32 as i128; +LL + i128::from(0u32); + | error: casts from `u64` to `u128` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:47:5 @@ -225,8 +243,9 @@ LL | 0u64 as u128; = help: an `as` cast can become silently lossy if the types change in the future help: use `u128::from` instead | -LL | u128::from(0u64); - | ~~~~~~~~~~~~~~~~ +LL - 0u64 as u128; +LL + u128::from(0u64); + | error: casts from `u64` to `i128` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:49:5 @@ -237,8 +256,9 @@ LL | 0u64 as i128; = help: an `as` cast can become silently lossy if the types change in the future help: use `i128::from` instead | -LL | i128::from(0u64); - | ~~~~~~~~~~~~~~~~ +LL - 0u64 as i128; +LL + i128::from(0u64); + | error: casts from `i8` to `i16` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:52:5 @@ -249,8 +269,9 @@ LL | 0i8 as i16; = help: an `as` cast can become silently lossy if the types change in the future help: use `i16::from` instead | -LL | i16::from(0i8); - | ~~~~~~~~~~~~~~ +LL - 0i8 as i16; +LL + i16::from(0i8); + | error: casts from `i8` to `i32` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:54:5 @@ -261,8 +282,9 @@ LL | 0i8 as i32; = help: an `as` cast can become silently lossy if the types change in the future help: use `i32::from` instead | -LL | i32::from(0i8); - | ~~~~~~~~~~~~~~ +LL - 0i8 as i32; +LL + i32::from(0i8); + | error: casts from `i8` to `i64` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:56:5 @@ -273,8 +295,9 @@ LL | 0i8 as i64; = help: an `as` cast can become silently lossy if the types change in the future help: use `i64::from` instead | -LL | i64::from(0i8); - | ~~~~~~~~~~~~~~ +LL - 0i8 as i64; +LL + i64::from(0i8); + | error: casts from `i8` to `i128` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:58:5 @@ -285,8 +308,9 @@ LL | 0i8 as i128; = help: an `as` cast can become silently lossy if the types change in the future help: use `i128::from` instead | -LL | i128::from(0i8); - | ~~~~~~~~~~~~~~~ +LL - 0i8 as i128; +LL + i128::from(0i8); + | error: casts from `i16` to `i32` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:61:5 @@ -297,8 +321,9 @@ LL | 0i16 as i32; = help: an `as` cast can become silently lossy if the types change in the future help: use `i32::from` instead | -LL | i32::from(0i16); - | ~~~~~~~~~~~~~~~ +LL - 0i16 as i32; +LL + i32::from(0i16); + | error: casts from `i16` to `i64` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:63:5 @@ -309,8 +334,9 @@ LL | 0i16 as i64; = help: an `as` cast can become silently lossy if the types change in the future help: use `i64::from` instead | -LL | i64::from(0i16); - | ~~~~~~~~~~~~~~~ +LL - 0i16 as i64; +LL + i64::from(0i16); + | error: casts from `i16` to `i128` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:65:5 @@ -321,8 +347,9 @@ LL | 0i16 as i128; = help: an `as` cast can become silently lossy if the types change in the future help: use `i128::from` instead | -LL | i128::from(0i16); - | ~~~~~~~~~~~~~~~~ +LL - 0i16 as i128; +LL + i128::from(0i16); + | error: casts from `i32` to `i64` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:68:5 @@ -333,8 +360,9 @@ LL | 0i32 as i64; = help: an `as` cast can become silently lossy if the types change in the future help: use `i64::from` instead | -LL | i64::from(0i32); - | ~~~~~~~~~~~~~~~ +LL - 0i32 as i64; +LL + i64::from(0i32); + | error: casts from `i32` to `i128` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:70:5 @@ -345,8 +373,9 @@ LL | 0i32 as i128; = help: an `as` cast can become silently lossy if the types change in the future help: use `i128::from` instead | -LL | i128::from(0i32); - | ~~~~~~~~~~~~~~~~ +LL - 0i32 as i128; +LL + i128::from(0i32); + | error: casts from `i64` to `i128` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:73:5 @@ -357,8 +386,9 @@ LL | 0i64 as i128; = help: an `as` cast can become silently lossy if the types change in the future help: use `i128::from` instead | -LL | i128::from(0i64); - | ~~~~~~~~~~~~~~~~ +LL - 0i64 as i128; +LL + i128::from(0i64); + | error: casts from `u8` to `u16` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:77:13 @@ -369,8 +399,9 @@ LL | let _ = (1u8 + 1u8) as u16; = help: an `as` cast can become silently lossy if the types change in the future help: use `u16::from` instead | -LL | let _ = u16::from(1u8 + 1u8); - | ~~~~~~~~~~~~~~~~~~~~ +LL - let _ = (1u8 + 1u8) as u16; +LL + let _ = u16::from(1u8 + 1u8); + | error: casts from `i8` to `i64` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:80:13 @@ -381,8 +412,9 @@ LL | let _ = 1i8 as I64Alias; = help: an `as` cast can become silently lossy if the types change in the future help: use `I64Alias::from` instead | -LL | let _ = I64Alias::from(1i8); - | ~~~~~~~~~~~~~~~~~~~ +LL - let _ = 1i8 as I64Alias; +LL + let _ = I64Alias::from(1i8); + | error: casts from `u8` to `u16` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:83:18 @@ -393,8 +425,9 @@ LL | let _: u16 = 0u8 as _; = help: an `as` cast can become silently lossy if the types change in the future help: use `Into::into` instead | -LL | let _: u16 = 0u8.into(); - | ~~~~~~~~~~ +LL - let _: u16 = 0u8 as _; +LL + let _: u16 = 0u8.into(); + | error: casts from `i8` to `i16` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:85:18 @@ -405,8 +438,9 @@ LL | let _: i16 = -1i8 as _; = help: an `as` cast can become silently lossy if the types change in the future help: use `Into::into` instead | -LL | let _: i16 = (-1i8).into(); - | ~~~~~~~~~~~~~ +LL - let _: i16 = -1i8 as _; +LL + let _: i16 = (-1i8).into(); + | error: casts from `u8` to `u16` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:87:18 @@ -417,8 +451,9 @@ LL | let _: u16 = (1u8 + 2) as _; = help: an `as` cast can become silently lossy if the types change in the future help: use `Into::into` instead | -LL | let _: u16 = (1u8 + 2).into(); - | ~~~~~~~~~~~~~~~~ +LL - let _: u16 = (1u8 + 2) as _; +LL + let _: u16 = (1u8 + 2).into(); + | error: casts from `u16` to `u32` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:89:18 @@ -429,8 +464,9 @@ LL | let _: u32 = 1i8 as u16 as _; = help: an `as` cast can become silently lossy if the types change in the future help: use `Into::into` instead | -LL | let _: u32 = (1i8 as u16).into(); - | ~~~~~~~~~~~~~~~~~~~ +LL - let _: u32 = 1i8 as u16 as _; +LL + let _: u32 = (1i8 as u16).into(); + | error: casts from `i8` to `i32` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:124:13 @@ -441,8 +477,9 @@ LL | let _ = sign_cast!(x, u8, i8) as i32; = help: an `as` cast can become silently lossy if the types change in the future help: use `i32::from` instead | -LL | let _ = i32::from(sign_cast!(x, u8, i8)); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _ = sign_cast!(x, u8, i8) as i32; +LL + let _ = i32::from(sign_cast!(x, u8, i8)); + | error: casts from `i8` to `i32` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:126:13 @@ -453,8 +490,9 @@ LL | let _ = (sign_cast!(x, u8, i8) + 1) as i32; = help: an `as` cast can become silently lossy if the types change in the future help: use `i32::from` instead | -LL | let _ = i32::from(sign_cast!(x, u8, i8) + 1); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _ = (sign_cast!(x, u8, i8) + 1) as i32; +LL + let _ = i32::from(sign_cast!(x, u8, i8) + 1); + | error: casts from `u8` to `u32` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:133:13 @@ -469,7 +507,8 @@ LL | let _ = in_macro!(); = note: this error originates in the macro `in_macro` (in Nightly builds, run with -Z macro-backtrace for more info) help: use `u32::from` instead | -LL | u32::from(1u8) +LL - 1u8 as u32 +LL + u32::from(1u8) | error: casts from `u8` to `u32` can be expressed infallibly using `From` @@ -481,8 +520,9 @@ LL | let _ = 0u8 as ty!(); = help: an `as` cast can become silently lossy if the types change in the future help: use `<ty!()>::from` instead | -LL | let _ = <ty!()>::from(0u8); - | ~~~~~~~~~~~~~~~~~~ +LL - let _ = 0u8 as ty!(); +LL + let _ = <ty!()>::from(0u8); + | error: aborting due to 40 previous errors diff --git a/src/tools/clippy/tests/ui/cast_size.64bit.stderr b/src/tools/clippy/tests/ui/cast_size.64bit.stderr index bc37107d80e..6b9919f8a10 100644 --- a/src/tools/clippy/tests/ui/cast_size.64bit.stderr +++ b/src/tools/clippy/tests/ui/cast_size.64bit.stderr @@ -9,8 +9,9 @@ LL | 1isize as i8; = help: to override `-D warnings` add `#[allow(clippy::cast_possible_truncation)]` help: ... or use `try_from` and handle the error accordingly | -LL | i8::try_from(1isize); - | ~~~~~~~~~~~~~~~~~~~~ +LL - 1isize as i8; +LL + i8::try_from(1isize); + | error: casting `isize` to `f32` causes a loss of precision (`isize` is 32 or 64 bits wide, but `f32`'s mantissa is only 23 bits wide) --> tests/ui/cast_size.rs:21:5 @@ -48,8 +49,9 @@ LL | 1isize as i32; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | i32::try_from(1isize); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - 1isize as i32; +LL + i32::try_from(1isize); + | error: casting `isize` to `u32` may truncate the value on targets with 64-bit wide pointers --> tests/ui/cast_size.rs:29:5 @@ -60,8 +62,9 @@ LL | 1isize as u32; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | u32::try_from(1isize); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - 1isize as u32; +LL + u32::try_from(1isize); + | error: casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers --> tests/ui/cast_size.rs:30:5 @@ -72,8 +75,9 @@ LL | 1usize as u32; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | u32::try_from(1usize); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - 1usize as u32; +LL + u32::try_from(1usize); + | error: casting `usize` to `i32` may truncate the value on targets with 64-bit wide pointers --> tests/ui/cast_size.rs:31:5 @@ -84,8 +88,9 @@ LL | 1usize as i32; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | i32::try_from(1usize); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - 1usize as i32; +LL + i32::try_from(1usize); + | error: casting `usize` to `i32` may wrap around the value on targets with 32-bit wide pointers --> tests/ui/cast_size.rs:31:5 @@ -105,8 +110,9 @@ LL | 1i64 as isize; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | isize::try_from(1i64); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - 1i64 as isize; +LL + isize::try_from(1i64); + | error: casting `i64` to `usize` may truncate the value on targets with 32-bit wide pointers --> tests/ui/cast_size.rs:33:5 @@ -117,8 +123,9 @@ LL | 1i64 as usize; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | usize::try_from(1i64); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - 1i64 as usize; +LL + usize::try_from(1i64); + | error: casting `u64` to `isize` may truncate the value on targets with 32-bit wide pointers --> tests/ui/cast_size.rs:34:5 @@ -129,8 +136,9 @@ LL | 1u64 as isize; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | isize::try_from(1u64); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - 1u64 as isize; +LL + isize::try_from(1u64); + | error: casting `u64` to `isize` may wrap around the value on targets with 64-bit wide pointers --> tests/ui/cast_size.rs:34:5 @@ -147,8 +155,9 @@ LL | 1u64 as usize; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | usize::try_from(1u64); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - 1u64 as usize; +LL + usize::try_from(1u64); + | error: casting `u32` to `isize` may wrap around the value on targets with 32-bit wide pointers --> tests/ui/cast_size.rs:36:5 diff --git a/src/tools/clippy/tests/ui/create_dir.stderr b/src/tools/clippy/tests/ui/create_dir.stderr index ab51705bb55..9bb98a2606d 100644 --- a/src/tools/clippy/tests/ui/create_dir.stderr +++ b/src/tools/clippy/tests/ui/create_dir.stderr @@ -8,8 +8,9 @@ LL | std::fs::create_dir("foo"); = help: to override `-D warnings` add `#[allow(clippy::create_dir)]` help: consider calling `std::fs::create_dir_all` instead | -LL | create_dir_all("foo"); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - std::fs::create_dir("foo"); +LL + create_dir_all("foo"); + | error: calling `std::fs::create_dir` where there may be a better way --> tests/ui/create_dir.rs:11:5 @@ -19,8 +20,9 @@ LL | std::fs::create_dir("bar").unwrap(); | help: consider calling `std::fs::create_dir_all` instead | -LL | create_dir_all("bar").unwrap(); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - std::fs::create_dir("bar").unwrap(); +LL + create_dir_all("bar").unwrap(); + | error: aborting due to 2 previous errors diff --git a/src/tools/clippy/tests/ui/dbg_macro/dbg_macro.stderr b/src/tools/clippy/tests/ui/dbg_macro/dbg_macro.stderr index b3d74b9ff61..f218614fdd6 100644 --- a/src/tools/clippy/tests/ui/dbg_macro/dbg_macro.stderr +++ b/src/tools/clippy/tests/ui/dbg_macro/dbg_macro.stderr @@ -8,8 +8,9 @@ LL | if let Some(n) = dbg!(n.checked_sub(4)) { n } else { n } = help: to override `-D warnings` add `#[allow(clippy::dbg_macro)]` help: remove the invocation before committing it to a version control system | -LL | if let Some(n) = n.checked_sub(4) { n } else { n } - | ~~~~~~~~~~~~~~~~ +LL - if let Some(n) = dbg!(n.checked_sub(4)) { n } else { n } +LL + if let Some(n) = n.checked_sub(4) { n } else { n } + | error: the `dbg!` macro is intended as a debugging tool --> tests/ui/dbg_macro/dbg_macro.rs:11:8 @@ -19,8 +20,9 @@ LL | if dbg!(n <= 1) { | help: remove the invocation before committing it to a version control system | -LL | if n <= 1 { - | ~~~~~~ +LL - if dbg!(n <= 1) { +LL + if n <= 1 { + | error: the `dbg!` macro is intended as a debugging tool --> tests/ui/dbg_macro/dbg_macro.rs:13:9 @@ -30,7 +32,8 @@ LL | dbg!(1) | help: remove the invocation before committing it to a version control system | -LL | 1 +LL - dbg!(1) +LL + 1 | error: the `dbg!` macro is intended as a debugging tool @@ -41,7 +44,8 @@ LL | dbg!(n * factorial(n - 1)) | help: remove the invocation before committing it to a version control system | -LL | n * factorial(n - 1) +LL - dbg!(n * factorial(n - 1)) +LL + n * factorial(n - 1) | error: the `dbg!` macro is intended as a debugging tool @@ -52,8 +56,9 @@ LL | dbg!(42); | help: remove the invocation before committing it to a version control system | -LL | 42; - | ~~ +LL - dbg!(42); +LL + 42; + | error: the `dbg!` macro is intended as a debugging tool --> tests/ui/dbg_macro/dbg_macro.rs:24:14 @@ -63,8 +68,9 @@ LL | foo(3) + dbg!(factorial(4)); | help: remove the invocation before committing it to a version control system | -LL | foo(3) + factorial(4); - | ~~~~~~~~~~~~ +LL - foo(3) + dbg!(factorial(4)); +LL + foo(3) + factorial(4); + | error: the `dbg!` macro is intended as a debugging tool --> tests/ui/dbg_macro/dbg_macro.rs:26:5 @@ -74,8 +80,9 @@ LL | dbg!(1, 2, 3, 4, 5); | help: remove the invocation before committing it to a version control system | -LL | (1, 2, 3, 4, 5); - | ~~~~~~~~~~~~~~~ +LL - dbg!(1, 2, 3, 4, 5); +LL + (1, 2, 3, 4, 5); + | error: the `dbg!` macro is intended as a debugging tool --> tests/ui/dbg_macro/dbg_macro.rs:48:5 @@ -96,8 +103,9 @@ LL | let _ = dbg!(); | help: remove the invocation before committing it to a version control system | -LL | let _ = (); - | ~~ +LL - let _ = dbg!(); +LL + let _ = (); + | error: the `dbg!` macro is intended as a debugging tool --> tests/ui/dbg_macro/dbg_macro.rs:53:9 @@ -107,8 +115,9 @@ LL | bar(dbg!()); | help: remove the invocation before committing it to a version control system | -LL | bar(()); - | ~~ +LL - bar(dbg!()); +LL + bar(()); + | error: the `dbg!` macro is intended as a debugging tool --> tests/ui/dbg_macro/dbg_macro.rs:55:10 @@ -118,8 +127,9 @@ LL | foo!(dbg!()); | help: remove the invocation before committing it to a version control system | -LL | foo!(()); - | ~~ +LL - foo!(dbg!()); +LL + foo!(()); + | error: the `dbg!` macro is intended as a debugging tool --> tests/ui/dbg_macro/dbg_macro.rs:57:16 @@ -129,8 +139,9 @@ LL | foo2!(foo!(dbg!())); | help: remove the invocation before committing it to a version control system | -LL | foo2!(foo!(())); - | ~~ +LL - foo2!(foo!(dbg!())); +LL + foo2!(foo!(())); + | error: the `dbg!` macro is intended as a debugging tool --> tests/ui/dbg_macro/dbg_macro.rs:43:13 @@ -155,8 +166,9 @@ LL | dbg!(2); | help: remove the invocation before committing it to a version control system | -LL | 2; - | ~ +LL - dbg!(2); +LL + 2; + | error: the `dbg!` macro is intended as a debugging tool --> tests/ui/dbg_macro/dbg_macro.rs:86:5 @@ -166,8 +178,9 @@ LL | dbg!(1); | help: remove the invocation before committing it to a version control system | -LL | 1; - | ~ +LL - dbg!(1); +LL + 1; + | error: the `dbg!` macro is intended as a debugging tool --> tests/ui/dbg_macro/dbg_macro.rs:92:5 @@ -177,8 +190,9 @@ LL | dbg!(1); | help: remove the invocation before committing it to a version control system | -LL | 1; - | ~ +LL - dbg!(1); +LL + 1; + | error: the `dbg!` macro is intended as a debugging tool --> tests/ui/dbg_macro/dbg_macro.rs:99:9 @@ -188,8 +202,9 @@ LL | dbg!(1); | help: remove the invocation before committing it to a version control system | -LL | 1; - | ~ +LL - dbg!(1); +LL + 1; + | error: the `dbg!` macro is intended as a debugging tool --> tests/ui/dbg_macro/dbg_macro.rs:106:31 @@ -199,8 +214,9 @@ LL | println!("dbg: {:?}", dbg!(s)); | help: remove the invocation before committing it to a version control system | -LL | println!("dbg: {:?}", s); - | ~ +LL - println!("dbg: {:?}", dbg!(s)); +LL + println!("dbg: {:?}", s); + | error: the `dbg!` macro is intended as a debugging tool --> tests/ui/dbg_macro/dbg_macro.rs:108:22 @@ -210,8 +226,9 @@ LL | print!("{}", dbg!(s)); | help: remove the invocation before committing it to a version control system | -LL | print!("{}", s); - | ~ +LL - print!("{}", dbg!(s)); +LL + print!("{}", s); + | error: aborting due to 19 previous errors diff --git a/src/tools/clippy/tests/ui/dbg_macro/dbg_macro_unfixable.stderr b/src/tools/clippy/tests/ui/dbg_macro/dbg_macro_unfixable.stderr index b8e91906b93..e8d5f9f2f46 100644 --- a/src/tools/clippy/tests/ui/dbg_macro/dbg_macro_unfixable.stderr +++ b/src/tools/clippy/tests/ui/dbg_macro/dbg_macro_unfixable.stderr @@ -19,8 +19,9 @@ LL | dbg!(dbg!(dbg!(42))); | help: remove the invocation before committing it to a version control system | -LL | dbg!(dbg!(42)); - | ~~~~~~~~~~~~~~ +LL - dbg!(dbg!(dbg!(42))); +LL + dbg!(dbg!(42)); + | error: the `dbg!` macro is intended as a debugging tool --> tests/ui/dbg_macro/dbg_macro_unfixable.rs:8:10 @@ -30,8 +31,9 @@ LL | dbg!(dbg!(dbg!(42))); | help: remove the invocation before committing it to a version control system | -LL | dbg!(dbg!(42)); - | ~~~~~~~~ +LL - dbg!(dbg!(dbg!(42))); +LL + dbg!(dbg!(42)); + | error: the `dbg!` macro is intended as a debugging tool --> tests/ui/dbg_macro/dbg_macro_unfixable.rs:8:15 @@ -41,8 +43,9 @@ LL | dbg!(dbg!(dbg!(42))); | help: remove the invocation before committing it to a version control system | -LL | dbg!(dbg!(42)); - | ~~ +LL - dbg!(dbg!(dbg!(42))); +LL + dbg!(dbg!(42)); + | error: the `dbg!` macro is intended as a debugging tool --> tests/ui/dbg_macro/dbg_macro_unfixable.rs:10:5 @@ -52,8 +55,9 @@ LL | dbg!(1, 2, dbg!(3, 4)); | help: remove the invocation before committing it to a version control system | -LL | (1, 2, dbg!(3, 4)); - | ~~~~~~~~~~~~~~~~~~ +LL - dbg!(1, 2, dbg!(3, 4)); +LL + (1, 2, dbg!(3, 4)); + | error: the `dbg!` macro is intended as a debugging tool --> tests/ui/dbg_macro/dbg_macro_unfixable.rs:10:16 @@ -63,8 +67,9 @@ LL | dbg!(1, 2, dbg!(3, 4)); | help: remove the invocation before committing it to a version control system | -LL | dbg!(1, 2, (3, 4)); - | ~~~~~~ +LL - dbg!(1, 2, dbg!(3, 4)); +LL + dbg!(1, 2, (3, 4)); + | error: aborting due to 6 previous errors diff --git a/src/tools/clippy/tests/ui/doc/doc-fixable.stderr b/src/tools/clippy/tests/ui/doc/doc-fixable.stderr index 27a04e4b558..54d73581485 100644 --- a/src/tools/clippy/tests/ui/doc/doc-fixable.stderr +++ b/src/tools/clippy/tests/ui/doc/doc-fixable.stderr @@ -8,8 +8,9 @@ LL | /// The foo_bar function does _nothing_. See also foo::bar. (note the dot t = help: to override `-D warnings` add `#[allow(clippy::doc_markdown)]` help: try | -LL | /// The `foo_bar` function does _nothing_. See also foo::bar. (note the dot there) - | ~~~~~~~~~ +LL - /// The foo_bar function does _nothing_. See also foo::bar. (note the dot there) +LL + /// The `foo_bar` function does _nothing_. See also foo::bar. (note the dot there) + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:9:51 @@ -19,8 +20,9 @@ LL | /// The foo_bar function does _nothing_. See also foo::bar. (note the dot t | help: try | -LL | /// The foo_bar function does _nothing_. See also `foo::bar`. (note the dot there) - | ~~~~~~~~~~ +LL - /// The foo_bar function does _nothing_. See also foo::bar. (note the dot there) +LL + /// The foo_bar function does _nothing_. See also `foo::bar`. (note the dot there) + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:10:83 @@ -30,8 +32,9 @@ LL | /// Markdown is _weird_. I mean _really weird_. This \_ is ok. So is `_`. B | help: try | -LL | /// Markdown is _weird_. I mean _really weird_. This \_ is ok. So is `_`. But not `Foo::some_fun` - | ~~~~~~~~~~~~~~~ +LL - /// Markdown is _weird_. I mean _really weird_. This \_ is ok. So is `_`. But not Foo::some_fun +LL + /// Markdown is _weird_. I mean _really weird_. This \_ is ok. So is `_`. But not `Foo::some_fun` + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:12:13 @@ -41,8 +44,9 @@ LL | /// Here be ::a::global:path, and _::another::global::path_. :: is not a p | help: try | -LL | /// Here be `::a::global:path`, and _::another::global::path_. :: is not a path though. - | ~~~~~~~~~~~~~~~~~~ +LL - /// Here be ::a::global:path, and _::another::global::path_. :: is not a path though. +LL + /// Here be `::a::global:path`, and _::another::global::path_. :: is not a path though. + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:12:36 @@ -52,8 +56,9 @@ LL | /// Here be ::a::global:path, and _::another::global::path_. :: is not a p | help: try | -LL | /// Here be ::a::global:path, and _`::another::global::path`_. :: is not a path though. - | ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - /// Here be ::a::global:path, and _::another::global::path_. :: is not a path though. +LL + /// Here be ::a::global:path, and _`::another::global::path`_. :: is not a path though. + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:13:25 @@ -63,8 +68,9 @@ LL | /// Import an item from ::awesome::global::blob:: (Intended postfix) | help: try | -LL | /// Import an item from `::awesome::global::blob::` (Intended postfix) - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - /// Import an item from ::awesome::global::blob:: (Intended postfix) +LL + /// Import an item from `::awesome::global::blob::` (Intended postfix) + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:14:31 @@ -74,8 +80,9 @@ LL | /// These are the options for ::Cat: (Intended trailing single colon, shoul | help: try | -LL | /// These are the options for `::Cat`: (Intended trailing single colon, shouldn't be linted) - | ~~~~~~~ +LL - /// These are the options for ::Cat: (Intended trailing single colon, shouldn't be linted) +LL + /// These are the options for `::Cat`: (Intended trailing single colon, shouldn't be linted) + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:15:22 @@ -85,8 +92,9 @@ LL | /// That's not code ~NotInCodeBlock~. | help: try | -LL | /// That's not code ~`NotInCodeBlock`~. - | ~~~~~~~~~~~~~~~~ +LL - /// That's not code ~NotInCodeBlock~. +LL + /// That's not code ~`NotInCodeBlock`~. + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:16:5 @@ -96,8 +104,9 @@ LL | /// be_sure_we_got_to_the_end_of_it | help: try | -LL | /// `be_sure_we_got_to_the_end_of_it` - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - /// be_sure_we_got_to_the_end_of_it +LL + /// `be_sure_we_got_to_the_end_of_it` + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:30:5 @@ -107,8 +116,9 @@ LL | /// be_sure_we_got_to_the_end_of_it | help: try | -LL | /// `be_sure_we_got_to_the_end_of_it` - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - /// be_sure_we_got_to_the_end_of_it +LL + /// `be_sure_we_got_to_the_end_of_it` + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:37:5 @@ -118,8 +128,9 @@ LL | /// be_sure_we_got_to_the_end_of_it | help: try | -LL | /// `be_sure_we_got_to_the_end_of_it` - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - /// be_sure_we_got_to_the_end_of_it +LL + /// `be_sure_we_got_to_the_end_of_it` + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:51:5 @@ -129,8 +140,9 @@ LL | /// be_sure_we_got_to_the_end_of_it | help: try | -LL | /// `be_sure_we_got_to_the_end_of_it` - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - /// be_sure_we_got_to_the_end_of_it +LL + /// `be_sure_we_got_to_the_end_of_it` + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:79:5 @@ -140,8 +152,9 @@ LL | /// be_sure_we_got_to_the_end_of_it | help: try | -LL | /// `be_sure_we_got_to_the_end_of_it` - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - /// be_sure_we_got_to_the_end_of_it +LL + /// `be_sure_we_got_to_the_end_of_it` + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:96:5 @@ -151,8 +164,9 @@ LL | /// be_sure_we_got_to_the_end_of_it | help: try | -LL | /// `be_sure_we_got_to_the_end_of_it` - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - /// be_sure_we_got_to_the_end_of_it +LL + /// `be_sure_we_got_to_the_end_of_it` + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:104:8 @@ -162,8 +176,9 @@ LL | /// ## CamelCaseThing | help: try | -LL | /// ## `CamelCaseThing` - | ~~~~~~~~~~~~~~~~ +LL - /// ## CamelCaseThing +LL + /// ## `CamelCaseThing` + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:107:7 @@ -173,8 +188,9 @@ LL | /// # CamelCaseThing | help: try | -LL | /// # `CamelCaseThing` - | ~~~~~~~~~~~~~~~~ +LL - /// # CamelCaseThing +LL + /// # `CamelCaseThing` + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:109:22 @@ -184,8 +200,9 @@ LL | /// Not a title #897 CamelCaseThing | help: try | -LL | /// Not a title #897 `CamelCaseThing` - | ~~~~~~~~~~~~~~~~ +LL - /// Not a title #897 CamelCaseThing +LL + /// Not a title #897 `CamelCaseThing` + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:110:5 @@ -195,8 +212,9 @@ LL | /// be_sure_we_got_to_the_end_of_it | help: try | -LL | /// `be_sure_we_got_to_the_end_of_it` - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - /// be_sure_we_got_to_the_end_of_it +LL + /// `be_sure_we_got_to_the_end_of_it` + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:117:5 @@ -206,8 +224,9 @@ LL | /// be_sure_we_got_to_the_end_of_it | help: try | -LL | /// `be_sure_we_got_to_the_end_of_it` - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - /// be_sure_we_got_to_the_end_of_it +LL + /// `be_sure_we_got_to_the_end_of_it` + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:130:5 @@ -217,8 +236,9 @@ LL | /// be_sure_we_got_to_the_end_of_it | help: try | -LL | /// `be_sure_we_got_to_the_end_of_it` - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - /// be_sure_we_got_to_the_end_of_it +LL + /// `be_sure_we_got_to_the_end_of_it` + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:141:43 @@ -228,8 +248,9 @@ LL | /** E.g., serialization of an empty list: FooBar | help: try | -LL | /** E.g., serialization of an empty list: `FooBar` - | ~~~~~~~~ +LL - /** E.g., serialization of an empty list: FooBar +LL + /** E.g., serialization of an empty list: `FooBar` + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:146:5 @@ -239,8 +260,9 @@ LL | And BarQuz too. | help: try | -LL | And `BarQuz` too. - | ~~~~~~~~ +LL - And BarQuz too. +LL + And `BarQuz` too. + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:147:1 @@ -250,7 +272,8 @@ LL | be_sure_we_got_to_the_end_of_it | help: try | -LL | `be_sure_we_got_to_the_end_of_it` +LL - be_sure_we_got_to_the_end_of_it +LL + `be_sure_we_got_to_the_end_of_it` | error: item in documentation is missing backticks @@ -261,8 +284,9 @@ LL | /** E.g., serialization of an empty list: FooBar | help: try | -LL | /** E.g., serialization of an empty list: `FooBar` - | ~~~~~~~~ +LL - /** E.g., serialization of an empty list: FooBar +LL + /** E.g., serialization of an empty list: `FooBar` + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:157:5 @@ -272,8 +296,9 @@ LL | And BarQuz too. | help: try | -LL | And `BarQuz` too. - | ~~~~~~~~ +LL - And BarQuz too. +LL + And `BarQuz` too. + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:158:1 @@ -283,7 +308,8 @@ LL | be_sure_we_got_to_the_end_of_it | help: try | -LL | `be_sure_we_got_to_the_end_of_it` +LL - be_sure_we_got_to_the_end_of_it +LL + `be_sure_we_got_to_the_end_of_it` | error: item in documentation is missing backticks @@ -294,8 +320,9 @@ LL | /// be_sure_we_got_to_the_end_of_it | help: try | -LL | /// `be_sure_we_got_to_the_end_of_it` - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - /// be_sure_we_got_to_the_end_of_it +LL + /// `be_sure_we_got_to_the_end_of_it` + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:188:22 @@ -305,8 +332,9 @@ LL | /// An iterator over mycrate::Collection's values. | help: try | -LL | /// An iterator over `mycrate::Collection`'s values. - | ~~~~~~~~~~~~~~~~~~~~~ +LL - /// An iterator over mycrate::Collection's values. +LL + /// An iterator over `mycrate::Collection`'s values. + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:212:34 @@ -316,8 +344,9 @@ LL | /// Foo \[bar\] \[baz\] \[qux\]. DocMarkdownLint | help: try | -LL | /// Foo \[bar\] \[baz\] \[qux\]. `DocMarkdownLint` - | ~~~~~~~~~~~~~~~~~ +LL - /// Foo \[bar\] \[baz\] \[qux\]. DocMarkdownLint +LL + /// Foo \[bar\] \[baz\] \[qux\]. `DocMarkdownLint` + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:235:22 @@ -327,8 +356,9 @@ LL | /// There is no try (do() or do_not()). | help: try | -LL | /// There is no try (`do()` or do_not()). - | ~~~~~~ +LL - /// There is no try (do() or do_not()). +LL + /// There is no try (`do()` or do_not()). + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:235:30 @@ -338,8 +368,9 @@ LL | /// There is no try (do() or do_not()). | help: try | -LL | /// There is no try (do() or `do_not()`). - | ~~~~~~~~~~ +LL - /// There is no try (do() or do_not()). +LL + /// There is no try (do() or `do_not()`). + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:238:5 @@ -349,8 +380,9 @@ LL | /// ABes | help: try | -LL | /// `ABes` - | ~~~~~~ +LL - /// ABes +LL + /// `ABes` + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:244:9 @@ -360,8 +392,9 @@ LL | /// foo() | help: try | -LL | /// `foo()` - | ~~~~~~~ +LL - /// foo() +LL + /// `foo()` + | error: you should put bare URLs between `<`/`>` or make a proper Markdown link --> tests/ui/doc/doc-fixable.rs:248:5 diff --git a/src/tools/clippy/tests/ui/doc/doc_markdown-issue_13097.stderr b/src/tools/clippy/tests/ui/doc/doc_markdown-issue_13097.stderr index ae68a767ec9..65b8f2ed80b 100644 --- a/src/tools/clippy/tests/ui/doc/doc_markdown-issue_13097.stderr +++ b/src/tools/clippy/tests/ui/doc/doc_markdown-issue_13097.stderr @@ -11,8 +11,9 @@ LL | #![deny(clippy::doc_markdown)] | ^^^^^^^^^^^^^^^^^^^^ help: try | -LL | /// `HumaNified` - | ~~~~~~~~~~~~ +LL - /// HumaNified +LL + /// `HumaNified` + | error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/doc/issue_10262.stderr b/src/tools/clippy/tests/ui/doc/issue_10262.stderr index f43d9551e94..f9ecb3de219 100644 --- a/src/tools/clippy/tests/ui/doc/issue_10262.stderr +++ b/src/tools/clippy/tests/ui/doc/issue_10262.stderr @@ -8,8 +8,9 @@ LL | /// AviSynth documentation: = help: to override `-D warnings` add `#[allow(clippy::doc_markdown)]` help: try | -LL | /// `AviSynth` documentation: - | ~~~~~~~~~~ +LL - /// AviSynth documentation: +LL + /// `AviSynth` documentation: + | error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/doc/issue_12795.stderr b/src/tools/clippy/tests/ui/doc/issue_12795.stderr index 5700145ec8f..047de915ed4 100644 --- a/src/tools/clippy/tests/ui/doc/issue_12795.stderr +++ b/src/tools/clippy/tests/ui/doc/issue_12795.stderr @@ -8,8 +8,9 @@ LL | //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe a_b( = help: to override `-D warnings` add `#[allow(clippy::doc_markdown)]` help: try | -LL | //! A comment with `a_b(x)` and a_c in it and (a_b((c)) ) too and (maybe a_b((c))) - | ~~~~~~~~ +LL - //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe a_b((c))) +LL + //! A comment with `a_b(x)` and a_c in it and (a_b((c)) ) too and (maybe a_b((c))) + | error: item in documentation is missing backticks --> tests/ui/doc/issue_12795.rs:3:31 @@ -19,8 +20,9 @@ LL | //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe a_b( | help: try | -LL | //! A comment with a_b(x) and `a_c` in it and (a_b((c)) ) too and (maybe a_b((c))) - | ~~~~~ +LL - //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe a_b((c))) +LL + //! A comment with a_b(x) and `a_c` in it and (a_b((c)) ) too and (maybe a_b((c))) + | error: item in documentation is missing backticks --> tests/ui/doc/issue_12795.rs:3:46 @@ -30,8 +32,9 @@ LL | //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe a_b( | help: try | -LL | //! A comment with a_b(x) and a_c in it and (`a_b((c))` ) too and (maybe a_b((c))) - | ~~~~~~~~~~ +LL - //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe a_b((c))) +LL + //! A comment with a_b(x) and a_c in it and (`a_b((c))` ) too and (maybe a_b((c))) + | error: item in documentation is missing backticks --> tests/ui/doc/issue_12795.rs:3:72 @@ -41,8 +44,9 @@ LL | //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe a_b( | help: try | -LL | //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe `a_b((c))`) - | ~~~~~~~~~~ +LL - //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe a_b((c))) +LL + //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe `a_b((c))`) + | error: aborting due to 4 previous errors diff --git a/src/tools/clippy/tests/ui/doc/issue_9473.stderr b/src/tools/clippy/tests/ui/doc/issue_9473.stderr index 35aa2884cc1..744c8dc8c83 100644 --- a/src/tools/clippy/tests/ui/doc/issue_9473.stderr +++ b/src/tools/clippy/tests/ui/doc/issue_9473.stderr @@ -8,8 +8,9 @@ LL | /// Blah blah blah <code>[FooBar]<[FooBar]></code>[FooBar]. = help: to override `-D warnings` add `#[allow(clippy::doc_markdown)]` help: try | -LL | /// Blah blah blah <code>[FooBar]<[FooBar]></code>[`FooBar`]. - | ~~~~~~~~ +LL - /// Blah blah blah <code>[FooBar]<[FooBar]></code>[FooBar]. +LL + /// Blah blah blah <code>[FooBar]<[FooBar]></code>[`FooBar`]. + | error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/doc/unbalanced_ticks.stderr b/src/tools/clippy/tests/ui/doc/unbalanced_ticks.stderr index c9fd25eb1a1..4114a823822 100644 --- a/src/tools/clippy/tests/ui/doc/unbalanced_ticks.stderr +++ b/src/tools/clippy/tests/ui/doc/unbalanced_ticks.stderr @@ -29,8 +29,9 @@ LL | /// This paragraph is fine and should_be linted normally. | help: try | -LL | /// This paragraph is fine and `should_be` linted normally. - | ~~~~~~~~~~~ +LL - /// This paragraph is fine and should_be linted normally. +LL + /// This paragraph is fine and `should_be` linted normally. + | error: backticks are unbalanced --> tests/ui/doc/unbalanced_ticks.rs:20:5 @@ -48,8 +49,9 @@ LL | /// ## not_fine | help: try | -LL | /// ## `not_fine` - | ~~~~~~~~~~ +LL - /// ## not_fine +LL + /// ## `not_fine` + | error: backticks are unbalanced --> tests/ui/doc/unbalanced_ticks.rs:37:5 @@ -75,8 +77,9 @@ LL | /// - This item needs backticks_here | help: try | -LL | /// - This item needs `backticks_here` - | ~~~~~~~~~~~~~~~~ +LL - /// - This item needs backticks_here +LL + /// - This item needs `backticks_here` + | error: backticks are unbalanced --> tests/ui/doc/unbalanced_ticks.rs:53:5 diff --git a/src/tools/clippy/tests/ui/eager_transmute.stderr b/src/tools/clippy/tests/ui/eager_transmute.stderr index 5cf7bd49a92..68690c3730d 100644 --- a/src/tools/clippy/tests/ui/eager_transmute.stderr +++ b/src/tools/clippy/tests/ui/eager_transmute.stderr @@ -8,8 +8,9 @@ LL | (op < 4).then_some(unsafe { std::mem::transmute(op) }) = help: to override `-D warnings` add `#[allow(clippy::eager_transmute)]` help: consider using `bool::then` to only transmute if the condition holds | -LL | (op < 4).then(|| unsafe { std::mem::transmute(op) }) - | ~~~~ ++ +LL - (op < 4).then_some(unsafe { std::mem::transmute(op) }) +LL + (op < 4).then(|| unsafe { std::mem::transmute(op) }) + | error: this transmute is always evaluated eagerly, even if the condition is false --> tests/ui/eager_transmute.rs:27:33 @@ -19,8 +20,9 @@ LL | (op < 4).then_some(unsafe { std::mem::transmute::<_, Opcode>(op) }); | help: consider using `bool::then` to only transmute if the condition holds | -LL | (op < 4).then(|| unsafe { std::mem::transmute::<_, Opcode>(op) }); - | ~~~~ ++ +LL - (op < 4).then_some(unsafe { std::mem::transmute::<_, Opcode>(op) }); +LL + (op < 4).then(|| unsafe { std::mem::transmute::<_, Opcode>(op) }); + | error: this transmute is always evaluated eagerly, even if the condition is false --> tests/ui/eager_transmute.rs:28:33 @@ -30,8 +32,9 @@ LL | (op > 4).then_some(unsafe { std::mem::transmute::<_, Opcode>(op) }); | help: consider using `bool::then` to only transmute if the condition holds | -LL | (op > 4).then(|| unsafe { std::mem::transmute::<_, Opcode>(op) }); - | ~~~~ ++ +LL - (op > 4).then_some(unsafe { std::mem::transmute::<_, Opcode>(op) }); +LL + (op > 4).then(|| unsafe { std::mem::transmute::<_, Opcode>(op) }); + | error: this transmute is always evaluated eagerly, even if the condition is false --> tests/ui/eager_transmute.rs:29:34 @@ -41,8 +44,9 @@ LL | (op == 0).then_some(unsafe { std::mem::transmute::<_, Opcode>(op) }); | help: consider using `bool::then` to only transmute if the condition holds | -LL | (op == 0).then(|| unsafe { std::mem::transmute::<_, Opcode>(op) }); - | ~~~~ ++ +LL - (op == 0).then_some(unsafe { std::mem::transmute::<_, Opcode>(op) }); +LL + (op == 0).then(|| unsafe { std::mem::transmute::<_, Opcode>(op) }); + | error: this transmute is always evaluated eagerly, even if the condition is false --> tests/ui/eager_transmute.rs:31:68 @@ -52,8 +56,9 @@ LL | let _: Option<Opcode> = (op > 0 && op < 10).then_some(unsafe { std::mem | help: consider using `bool::then` to only transmute if the condition holds | -LL | let _: Option<Opcode> = (op > 0 && op < 10).then(|| unsafe { std::mem::transmute(op) }); - | ~~~~ ++ +LL - let _: Option<Opcode> = (op > 0 && op < 10).then_some(unsafe { std::mem::transmute(op) }); +LL + let _: Option<Opcode> = (op > 0 && op < 10).then(|| unsafe { std::mem::transmute(op) }); + | error: this transmute is always evaluated eagerly, even if the condition is false --> tests/ui/eager_transmute.rs:32:86 @@ -63,8 +68,9 @@ LL | let _: Option<Opcode> = (op > 0 && op < 10 && unrelated == 0).then_some | help: consider using `bool::then` to only transmute if the condition holds | -LL | let _: Option<Opcode> = (op > 0 && op < 10 && unrelated == 0).then(|| unsafe { std::mem::transmute(op) }); - | ~~~~ ++ +LL - let _: Option<Opcode> = (op > 0 && op < 10 && unrelated == 0).then_some(unsafe { std::mem::transmute(op) }); +LL + let _: Option<Opcode> = (op > 0 && op < 10 && unrelated == 0).then(|| unsafe { std::mem::transmute(op) }); + | error: this transmute is always evaluated eagerly, even if the condition is false --> tests/ui/eager_transmute.rs:35:84 @@ -74,8 +80,9 @@ LL | let _: Option<Opcode> = (op2.foo[0] > 0 && op2.foo[0] < 10).then_some(u | help: consider using `bool::then` to only transmute if the condition holds | -LL | let _: Option<Opcode> = (op2.foo[0] > 0 && op2.foo[0] < 10).then(|| unsafe { std::mem::transmute(op2.foo[0]) }); - | ~~~~ ++ +LL - let _: Option<Opcode> = (op2.foo[0] > 0 && op2.foo[0] < 10).then_some(unsafe { std::mem::transmute(op2.foo[0]) }); +LL + let _: Option<Opcode> = (op2.foo[0] > 0 && op2.foo[0] < 10).then(|| unsafe { std::mem::transmute(op2.foo[0]) }); + | error: this transmute is always evaluated eagerly, even if the condition is false --> tests/ui/eager_transmute.rs:47:70 @@ -85,8 +92,9 @@ LL | let _: Option<Opcode> = (1..=3).contains(&op).then_some(unsafe { std::m | help: consider using `bool::then` to only transmute if the condition holds | -LL | let _: Option<Opcode> = (1..=3).contains(&op).then(|| unsafe { std::mem::transmute(op) }); - | ~~~~ ++ +LL - let _: Option<Opcode> = (1..=3).contains(&op).then_some(unsafe { std::mem::transmute(op) }); +LL + let _: Option<Opcode> = (1..=3).contains(&op).then(|| unsafe { std::mem::transmute(op) }); + | error: this transmute is always evaluated eagerly, even if the condition is false --> tests/ui/eager_transmute.rs:48:83 @@ -96,8 +104,9 @@ LL | let _: Option<Opcode> = ((1..=3).contains(&op) || op == 4).then_some(un | help: consider using `bool::then` to only transmute if the condition holds | -LL | let _: Option<Opcode> = ((1..=3).contains(&op) || op == 4).then(|| unsafe { std::mem::transmute(op) }); - | ~~~~ ++ +LL - let _: Option<Opcode> = ((1..=3).contains(&op) || op == 4).then_some(unsafe { std::mem::transmute(op) }); +LL + let _: Option<Opcode> = ((1..=3).contains(&op) || op == 4).then(|| unsafe { std::mem::transmute(op) }); + | error: this transmute is always evaluated eagerly, even if the condition is false --> tests/ui/eager_transmute.rs:49:69 @@ -107,8 +116,9 @@ LL | let _: Option<Opcode> = (1..3).contains(&op).then_some(unsafe { std::me | help: consider using `bool::then` to only transmute if the condition holds | -LL | let _: Option<Opcode> = (1..3).contains(&op).then(|| unsafe { std::mem::transmute(op) }); - | ~~~~ ++ +LL - let _: Option<Opcode> = (1..3).contains(&op).then_some(unsafe { std::mem::transmute(op) }); +LL + let _: Option<Opcode> = (1..3).contains(&op).then(|| unsafe { std::mem::transmute(op) }); + | error: this transmute is always evaluated eagerly, even if the condition is false --> tests/ui/eager_transmute.rs:50:68 @@ -118,8 +128,9 @@ LL | let _: Option<Opcode> = (1..).contains(&op).then_some(unsafe { std::mem | help: consider using `bool::then` to only transmute if the condition holds | -LL | let _: Option<Opcode> = (1..).contains(&op).then(|| unsafe { std::mem::transmute(op) }); - | ~~~~ ++ +LL - let _: Option<Opcode> = (1..).contains(&op).then_some(unsafe { std::mem::transmute(op) }); +LL + let _: Option<Opcode> = (1..).contains(&op).then(|| unsafe { std::mem::transmute(op) }); + | error: this transmute is always evaluated eagerly, even if the condition is false --> tests/ui/eager_transmute.rs:51:68 @@ -129,8 +140,9 @@ LL | let _: Option<Opcode> = (..3).contains(&op).then_some(unsafe { std::mem | help: consider using `bool::then` to only transmute if the condition holds | -LL | let _: Option<Opcode> = (..3).contains(&op).then(|| unsafe { std::mem::transmute(op) }); - | ~~~~ ++ +LL - let _: Option<Opcode> = (..3).contains(&op).then_some(unsafe { std::mem::transmute(op) }); +LL + let _: Option<Opcode> = (..3).contains(&op).then(|| unsafe { std::mem::transmute(op) }); + | error: this transmute is always evaluated eagerly, even if the condition is false --> tests/ui/eager_transmute.rs:52:69 @@ -140,8 +152,9 @@ LL | let _: Option<Opcode> = (..=3).contains(&op).then_some(unsafe { std::me | help: consider using `bool::then` to only transmute if the condition holds | -LL | let _: Option<Opcode> = (..=3).contains(&op).then(|| unsafe { std::mem::transmute(op) }); - | ~~~~ ++ +LL - let _: Option<Opcode> = (..=3).contains(&op).then_some(unsafe { std::mem::transmute(op) }); +LL + let _: Option<Opcode> = (..=3).contains(&op).then(|| unsafe { std::mem::transmute(op) }); + | error: this transmute is always evaluated eagerly, even if the condition is false --> tests/ui/eager_transmute.rs:61:24 @@ -151,8 +164,9 @@ LL | (op < 4).then_some(std::mem::transmute::<_, Opcode>(op)); | help: consider using `bool::then` to only transmute if the condition holds | -LL | (op < 4).then(|| std::mem::transmute::<_, Opcode>(op)); - | ~~~~ ++ +LL - (op < 4).then_some(std::mem::transmute::<_, Opcode>(op)); +LL + (op < 4).then(|| std::mem::transmute::<_, Opcode>(op)); + | error: this transmute is always evaluated eagerly, even if the condition is false --> tests/ui/eager_transmute.rs:90:62 @@ -162,8 +176,9 @@ LL | let _: Option<NonZero<u8>> = (v1 > 0).then_some(unsafe { std::mem::tran | help: consider using `bool::then` to only transmute if the condition holds | -LL | let _: Option<NonZero<u8>> = (v1 > 0).then(|| unsafe { std::mem::transmute(v1) }); - | ~~~~ ++ +LL - let _: Option<NonZero<u8>> = (v1 > 0).then_some(unsafe { std::mem::transmute(v1) }); +LL + let _: Option<NonZero<u8>> = (v1 > 0).then(|| unsafe { std::mem::transmute(v1) }); + | error: this transmute is always evaluated eagerly, even if the condition is false --> tests/ui/eager_transmute.rs:96:86 @@ -173,8 +188,9 @@ LL | let _: Option<NonMaxU8> = (v2 < NonZero::new(255u8).unwrap()).then_some | help: consider using `bool::then` to only transmute if the condition holds | -LL | let _: Option<NonMaxU8> = (v2 < NonZero::new(255u8).unwrap()).then(|| unsafe { std::mem::transmute(v2) }); - | ~~~~ ++ +LL - let _: Option<NonMaxU8> = (v2 < NonZero::new(255u8).unwrap()).then_some(unsafe { std::mem::transmute(v2) }); +LL + let _: Option<NonMaxU8> = (v2 < NonZero::new(255u8).unwrap()).then(|| unsafe { std::mem::transmute(v2) }); + | error: this transmute is always evaluated eagerly, even if the condition is false --> tests/ui/eager_transmute.rs:102:93 @@ -184,8 +200,9 @@ LL | let _: Option<NonZeroNonMaxU8> = (v2 < NonZero::new(255u8).unwrap()).th | help: consider using `bool::then` to only transmute if the condition holds | -LL | let _: Option<NonZeroNonMaxU8> = (v2 < NonZero::new(255u8).unwrap()).then(|| unsafe { std::mem::transmute(v2) }); - | ~~~~ ++ +LL - let _: Option<NonZeroNonMaxU8> = (v2 < NonZero::new(255u8).unwrap()).then_some(unsafe { std::mem::transmute(v2) }); +LL + let _: Option<NonZeroNonMaxU8> = (v2 < NonZero::new(255u8).unwrap()).then(|| unsafe { std::mem::transmute(v2) }); + | error: aborting due to 17 previous errors diff --git a/src/tools/clippy/tests/ui/empty_line_after/doc_comments.stderr b/src/tools/clippy/tests/ui/empty_line_after/doc_comments.stderr index 7b197ae67e0..ca05a1b03eb 100644 --- a/src/tools/clippy/tests/ui/empty_line_after/doc_comments.stderr +++ b/src/tools/clippy/tests/ui/empty_line_after/doc_comments.stderr @@ -131,8 +131,9 @@ LL | fn first_in_module() {} = help: if the empty line is unintentional, remove it help: if the comment should document the parent module use an inner doc comment | -LL | /*! - | ~ +LL - /** +LL + /*! + | error: empty line after doc comment --> tests/ui/empty_line_after/doc_comments.rs:85:5 diff --git a/src/tools/clippy/tests/ui/excessive_precision.stderr b/src/tools/clippy/tests/ui/excessive_precision.stderr index 81e4fb6765d..b1f12eed420 100644 --- a/src/tools/clippy/tests/ui/excessive_precision.stderr +++ b/src/tools/clippy/tests/ui/excessive_precision.stderr @@ -8,8 +8,9 @@ LL | const BAD32_1: f32 = 0.123_456_789_f32; = help: to override `-D warnings` add `#[allow(clippy::excessive_precision)]` help: consider changing the type or truncating it to | -LL | const BAD32_1: f32 = 0.123_456_79_f32; - | ~~~~~~~~~~~~~~~~ +LL - const BAD32_1: f32 = 0.123_456_789_f32; +LL + const BAD32_1: f32 = 0.123_456_79_f32; + | error: float has excessive precision --> tests/ui/excessive_precision.rs:21:26 @@ -19,8 +20,9 @@ LL | const BAD32_2: f32 = 0.123_456_789; | help: consider changing the type or truncating it to | -LL | const BAD32_2: f32 = 0.123_456_79; - | ~~~~~~~~~~~~ +LL - const BAD32_2: f32 = 0.123_456_789; +LL + const BAD32_2: f32 = 0.123_456_79; + | error: float has excessive precision --> tests/ui/excessive_precision.rs:22:26 @@ -30,8 +32,9 @@ LL | const BAD32_3: f32 = 0.100_000_000_000_1; | help: consider changing the type or truncating it to | -LL | const BAD32_3: f32 = 0.1; - | ~~~ +LL - const BAD32_3: f32 = 0.100_000_000_000_1; +LL + const BAD32_3: f32 = 0.1; + | error: float has excessive precision --> tests/ui/excessive_precision.rs:23:29 @@ -41,8 +44,9 @@ LL | const BAD32_EDGE: f32 = 1.000_000_9; | help: consider changing the type or truncating it to | -LL | const BAD32_EDGE: f32 = 1.000_001; - | ~~~~~~~~~ +LL - const BAD32_EDGE: f32 = 1.000_000_9; +LL + const BAD32_EDGE: f32 = 1.000_001; + | error: float has excessive precision --> tests/ui/excessive_precision.rs:27:26 @@ -52,8 +56,9 @@ LL | const BAD64_3: f64 = 0.100_000_000_000_000_000_1; | help: consider changing the type or truncating it to | -LL | const BAD64_3: f64 = 0.1; - | ~~~ +LL - const BAD64_3: f64 = 0.100_000_000_000_000_000_1; +LL + const BAD64_3: f64 = 0.1; + | error: float has excessive precision --> tests/ui/excessive_precision.rs:30:22 @@ -63,8 +68,9 @@ LL | println!("{:?}", 8.888_888_888_888_888_888_888); | help: consider changing the type or truncating it to | -LL | println!("{:?}", 8.888_888_888_888_89); - | ~~~~~~~~~~~~~~~~~~~~ +LL - println!("{:?}", 8.888_888_888_888_888_888_888); +LL + println!("{:?}", 8.888_888_888_888_89); + | error: float has excessive precision --> tests/ui/excessive_precision.rs:41:22 @@ -74,8 +80,9 @@ LL | let bad32: f32 = 1.123_456_789; | help: consider changing the type or truncating it to | -LL | let bad32: f32 = 1.123_456_8; - | ~~~~~~~~~~~ +LL - let bad32: f32 = 1.123_456_789; +LL + let bad32: f32 = 1.123_456_8; + | error: float has excessive precision --> tests/ui/excessive_precision.rs:42:26 @@ -85,8 +92,9 @@ LL | let bad32_suf: f32 = 1.123_456_789_f32; | help: consider changing the type or truncating it to | -LL | let bad32_suf: f32 = 1.123_456_8_f32; - | ~~~~~~~~~~~~~~~ +LL - let bad32_suf: f32 = 1.123_456_789_f32; +LL + let bad32_suf: f32 = 1.123_456_8_f32; + | error: float has excessive precision --> tests/ui/excessive_precision.rs:43:21 @@ -96,8 +104,9 @@ LL | let bad32_inf = 1.123_456_789_f32; | help: consider changing the type or truncating it to | -LL | let bad32_inf = 1.123_456_8_f32; - | ~~~~~~~~~~~~~~~ +LL - let bad32_inf = 1.123_456_789_f32; +LL + let bad32_inf = 1.123_456_8_f32; + | error: float has excessive precision --> tests/ui/excessive_precision.rs:53:36 @@ -107,8 +116,9 @@ LL | let bad_vec32: Vec<f32> = vec![0.123_456_789]; | help: consider changing the type or truncating it to | -LL | let bad_vec32: Vec<f32> = vec![0.123_456_79]; - | ~~~~~~~~~~~~ +LL - let bad_vec32: Vec<f32> = vec![0.123_456_789]; +LL + let bad_vec32: Vec<f32> = vec![0.123_456_79]; + | error: float has excessive precision --> tests/ui/excessive_precision.rs:54:36 @@ -118,8 +128,9 @@ LL | let bad_vec64: Vec<f64> = vec![0.123_456_789_123_456_789]; | help: consider changing the type or truncating it to | -LL | let bad_vec64: Vec<f64> = vec![0.123_456_789_123_456_78]; - | ~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let bad_vec64: Vec<f64> = vec![0.123_456_789_123_456_789]; +LL + let bad_vec64: Vec<f64> = vec![0.123_456_789_123_456_78]; + | error: float has excessive precision --> tests/ui/excessive_precision.rs:58:24 @@ -129,8 +140,9 @@ LL | let bad_e32: f32 = 1.123_456_788_888e-10; | help: consider changing the type or truncating it to | -LL | let bad_e32: f32 = 1.123_456_8e-10; - | ~~~~~~~~~~~~~~~ +LL - let bad_e32: f32 = 1.123_456_788_888e-10; +LL + let bad_e32: f32 = 1.123_456_8e-10; + | error: float has excessive precision --> tests/ui/excessive_precision.rs:61:27 @@ -140,8 +152,9 @@ LL | let bad_bige32: f32 = 1.123_456_788_888E-10; | help: consider changing the type or truncating it to | -LL | let bad_bige32: f32 = 1.123_456_8E-10; - | ~~~~~~~~~~~~~~~ +LL - let bad_bige32: f32 = 1.123_456_788_888E-10; +LL + let bad_bige32: f32 = 1.123_456_8E-10; + | error: float has excessive precision --> tests/ui/excessive_precision.rs:70:13 @@ -151,8 +164,9 @@ LL | let _ = 2.225_073_858_507_201_1e-308_f64; | help: consider changing the type or truncating it to | -LL | let _ = 2.225_073_858_507_201e-308_f64; - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _ = 2.225_073_858_507_201_1e-308_f64; +LL + let _ = 2.225_073_858_507_201e-308_f64; + | error: float has excessive precision --> tests/ui/excessive_precision.rs:73:13 @@ -162,8 +176,9 @@ LL | let _ = 1.000_000_000_000_001e-324_f64; | help: consider changing the type or truncating it to | -LL | let _ = 0_f64; - | ~~~~~ +LL - let _ = 1.000_000_000_000_001e-324_f64; +LL + let _ = 0_f64; + | error: float has excessive precision --> tests/ui/excessive_precision.rs:83:20 @@ -173,8 +188,9 @@ LL | const _: f64 = 3.0000000000000000e+00; | help: consider changing the type or truncating it to | -LL | const _: f64 = 3.0; - | ~~~ +LL - const _: f64 = 3.0000000000000000e+00; +LL + const _: f64 = 3.0; + | error: aborting due to 16 previous errors diff --git a/src/tools/clippy/tests/ui/fn_to_numeric_cast_any.stderr b/src/tools/clippy/tests/ui/fn_to_numeric_cast_any.stderr index a05b7138bc9..c069c9d1672 100644 --- a/src/tools/clippy/tests/ui/fn_to_numeric_cast_any.stderr +++ b/src/tools/clippy/tests/ui/fn_to_numeric_cast_any.stderr @@ -8,8 +8,9 @@ LL | let _ = foo as i8; = help: to override `-D warnings` add `#[allow(clippy::fn_to_numeric_cast_any)]` help: did you mean to invoke the function? | -LL | let _ = foo() as i8; - | ~~~~~~~~~~~ +LL - let _ = foo as i8; +LL + let _ = foo() as i8; + | error: casting function pointer `foo` to `i16` --> tests/ui/fn_to_numeric_cast_any.rs:26:13 @@ -19,8 +20,9 @@ LL | let _ = foo as i16; | help: did you mean to invoke the function? | -LL | let _ = foo() as i16; - | ~~~~~~~~~~~~ +LL - let _ = foo as i16; +LL + let _ = foo() as i16; + | error: casting function pointer `foo` to `i32` --> tests/ui/fn_to_numeric_cast_any.rs:28:13 @@ -30,8 +32,9 @@ LL | let _ = foo as i32; | help: did you mean to invoke the function? | -LL | let _ = foo() as i32; - | ~~~~~~~~~~~~ +LL - let _ = foo as i32; +LL + let _ = foo() as i32; + | error: casting function pointer `foo` to `i64` --> tests/ui/fn_to_numeric_cast_any.rs:30:13 @@ -41,8 +44,9 @@ LL | let _ = foo as i64; | help: did you mean to invoke the function? | -LL | let _ = foo() as i64; - | ~~~~~~~~~~~~ +LL - let _ = foo as i64; +LL + let _ = foo() as i64; + | error: casting function pointer `foo` to `i128` --> tests/ui/fn_to_numeric_cast_any.rs:32:13 @@ -52,8 +56,9 @@ LL | let _ = foo as i128; | help: did you mean to invoke the function? | -LL | let _ = foo() as i128; - | ~~~~~~~~~~~~~ +LL - let _ = foo as i128; +LL + let _ = foo() as i128; + | error: casting function pointer `foo` to `isize` --> tests/ui/fn_to_numeric_cast_any.rs:34:13 @@ -63,8 +68,9 @@ LL | let _ = foo as isize; | help: did you mean to invoke the function? | -LL | let _ = foo() as isize; - | ~~~~~~~~~~~~~~ +LL - let _ = foo as isize; +LL + let _ = foo() as isize; + | error: casting function pointer `foo` to `u8` --> tests/ui/fn_to_numeric_cast_any.rs:37:13 @@ -74,8 +80,9 @@ LL | let _ = foo as u8; | help: did you mean to invoke the function? | -LL | let _ = foo() as u8; - | ~~~~~~~~~~~ +LL - let _ = foo as u8; +LL + let _ = foo() as u8; + | error: casting function pointer `foo` to `u16` --> tests/ui/fn_to_numeric_cast_any.rs:39:13 @@ -85,8 +92,9 @@ LL | let _ = foo as u16; | help: did you mean to invoke the function? | -LL | let _ = foo() as u16; - | ~~~~~~~~~~~~ +LL - let _ = foo as u16; +LL + let _ = foo() as u16; + | error: casting function pointer `foo` to `u32` --> tests/ui/fn_to_numeric_cast_any.rs:41:13 @@ -96,8 +104,9 @@ LL | let _ = foo as u32; | help: did you mean to invoke the function? | -LL | let _ = foo() as u32; - | ~~~~~~~~~~~~ +LL - let _ = foo as u32; +LL + let _ = foo() as u32; + | error: casting function pointer `foo` to `u64` --> tests/ui/fn_to_numeric_cast_any.rs:43:13 @@ -107,8 +116,9 @@ LL | let _ = foo as u64; | help: did you mean to invoke the function? | -LL | let _ = foo() as u64; - | ~~~~~~~~~~~~ +LL - let _ = foo as u64; +LL + let _ = foo() as u64; + | error: casting function pointer `foo` to `u128` --> tests/ui/fn_to_numeric_cast_any.rs:45:13 @@ -118,8 +128,9 @@ LL | let _ = foo as u128; | help: did you mean to invoke the function? | -LL | let _ = foo() as u128; - | ~~~~~~~~~~~~~ +LL - let _ = foo as u128; +LL + let _ = foo() as u128; + | error: casting function pointer `foo` to `usize` --> tests/ui/fn_to_numeric_cast_any.rs:47:13 @@ -129,8 +140,9 @@ LL | let _ = foo as usize; | help: did you mean to invoke the function? | -LL | let _ = foo() as usize; - | ~~~~~~~~~~~~~~ +LL - let _ = foo as usize; +LL + let _ = foo() as usize; + | error: casting function pointer `Struct::static_method` to `usize` --> tests/ui/fn_to_numeric_cast_any.rs:52:13 @@ -140,8 +152,9 @@ LL | let _ = Struct::static_method as usize; | help: did you mean to invoke the function? | -LL | let _ = Struct::static_method() as usize; - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _ = Struct::static_method as usize; +LL + let _ = Struct::static_method() as usize; + | error: casting function pointer `f` to `usize` --> tests/ui/fn_to_numeric_cast_any.rs:57:5 @@ -151,7 +164,8 @@ LL | f as usize | help: did you mean to invoke the function? | -LL | f() as usize +LL - f as usize +LL + f() as usize | error: casting function pointer `T::static_method` to `usize` @@ -162,7 +176,8 @@ LL | T::static_method as usize | help: did you mean to invoke the function? | -LL | T::static_method() as usize +LL - T::static_method as usize +LL + T::static_method() as usize | error: casting function pointer `(clos as fn(u32) -> u32)` to `usize` @@ -173,8 +188,9 @@ LL | let _ = (clos as fn(u32) -> u32) as usize; | help: did you mean to invoke the function? | -LL | let _ = (clos as fn(u32) -> u32)() as usize; - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _ = (clos as fn(u32) -> u32) as usize; +LL + let _ = (clos as fn(u32) -> u32)() as usize; + | error: casting function pointer `foo` to `*const ()` --> tests/ui/fn_to_numeric_cast_any.rs:74:13 @@ -184,8 +200,9 @@ LL | let _ = foo as *const (); | help: did you mean to invoke the function? | -LL | let _ = foo() as *const (); - | ~~~~~~~~~~~~~~~~~~ +LL - let _ = foo as *const (); +LL + let _ = foo() as *const (); + | error: aborting due to 17 previous errors diff --git a/src/tools/clippy/tests/ui/for_kv_map.stderr b/src/tools/clippy/tests/ui/for_kv_map.stderr index adcc3ab8fdb..11b61c8cbc6 100644 --- a/src/tools/clippy/tests/ui/for_kv_map.stderr +++ b/src/tools/clippy/tests/ui/for_kv_map.stderr @@ -8,8 +8,9 @@ LL | for (_, v) in &m { = help: to override `-D warnings` add `#[allow(clippy::for_kv_map)]` help: use the corresponding method | -LL | for v in m.values() { - | ~ ~~~~~~~~~~ +LL - for (_, v) in &m { +LL + for v in m.values() { + | error: you seem to want to iterate on a map's values --> tests/ui/for_kv_map.rs:16:19 @@ -19,8 +20,9 @@ LL | for (_, v) in &*m { | help: use the corresponding method | -LL | for v in (*m).values() { - | ~ ~~~~~~~~~~~~~ +LL - for (_, v) in &*m { +LL + for v in (*m).values() { + | error: you seem to want to iterate on a map's values --> tests/ui/for_kv_map.rs:25:19 @@ -30,8 +32,9 @@ LL | for (_, v) in &mut m { | help: use the corresponding method | -LL | for v in m.values_mut() { - | ~ ~~~~~~~~~~~~~~ +LL - for (_, v) in &mut m { +LL + for v in m.values_mut() { + | error: you seem to want to iterate on a map's values --> tests/ui/for_kv_map.rs:31:19 @@ -41,8 +44,9 @@ LL | for (_, v) in &mut *m { | help: use the corresponding method | -LL | for v in (*m).values_mut() { - | ~ ~~~~~~~~~~~~~~~~~ +LL - for (_, v) in &mut *m { +LL + for v in (*m).values_mut() { + | error: you seem to want to iterate on a map's keys --> tests/ui/for_kv_map.rs:38:24 @@ -52,8 +56,9 @@ LL | for (k, _value) in rm { | help: use the corresponding method | -LL | for k in rm.keys() { - | ~ ~~~~~~~~~ +LL - for (k, _value) in rm { +LL + for k in rm.keys() { + | error: you seem to want to iterate on a map's keys --> tests/ui/for_kv_map.rs:45:32 @@ -63,8 +68,9 @@ LL | 'label: for (k, _value) in rm { | help: use the corresponding method | -LL | 'label: for k in rm.keys() { - | ~ ~~~~~~~~~ +LL - 'label: for (k, _value) in rm { +LL + 'label: for k in rm.keys() { + | error: aborting due to 6 previous errors diff --git a/src/tools/clippy/tests/ui/four_forward_slashes.stderr b/src/tools/clippy/tests/ui/four_forward_slashes.stderr index 3606a2227a0..d5bf71fadc7 100644 --- a/src/tools/clippy/tests/ui/four_forward_slashes.stderr +++ b/src/tools/clippy/tests/ui/four_forward_slashes.stderr @@ -9,6 +9,8 @@ LL | | fn a() {} = help: to override `-D warnings` add `#[allow(clippy::four_forward_slashes)]` help: make this a doc comment by removing one `/` | +LL - //// whoops +LL - fn a() {} LL + /// whoops | @@ -22,6 +24,8 @@ LL | | fn b() {} | help: make this a doc comment by removing one `/` | +LL - //// whoops +LL - #[allow(dead_code)] LL + /// whoops | @@ -50,6 +54,8 @@ LL | | fn g() {} | help: make this a doc comment by removing one `/` | +LL - //// between attributes +LL - #[allow(dead_code)] LL + /// between attributes | @@ -62,6 +68,8 @@ LL | | fn h() {} | help: make this a doc comment by removing one `/` | +LL - //// not very start of contents +LL - fn h() {} LL + /// not very start of contents | diff --git a/src/tools/clippy/tests/ui/four_forward_slashes_first_line.stderr b/src/tools/clippy/tests/ui/four_forward_slashes_first_line.stderr index 81732346412..83bfb60eb16 100644 --- a/src/tools/clippy/tests/ui/four_forward_slashes_first_line.stderr +++ b/src/tools/clippy/tests/ui/four_forward_slashes_first_line.stderr @@ -9,6 +9,8 @@ LL | | fn a() {} = help: to override `-D warnings` add `#[allow(clippy::four_forward_slashes)]` help: make this a doc comment by removing one `/` | +LL - //// borked doc comment on the first line. doesn't combust! +LL - fn a() {} LL + /// borked doc comment on the first line. doesn't combust! | diff --git a/src/tools/clippy/tests/ui/get_unwrap.stderr b/src/tools/clippy/tests/ui/get_unwrap.stderr index 8eacb249c60..fc6c0b9299c 100644 --- a/src/tools/clippy/tests/ui/get_unwrap.stderr +++ b/src/tools/clippy/tests/ui/get_unwrap.stderr @@ -11,8 +11,9 @@ LL | #![deny(clippy::get_unwrap)] | ^^^^^^^^^^^^^^^^^^ help: using `[]` is clearer and more concise | -LL | let _ = &boxed_slice[1]; - | ~~~~~~~~~~~~~~~ +LL - let _ = boxed_slice.get(1).unwrap(); +LL + let _ = &boxed_slice[1]; + | error: used `unwrap()` on an `Option` value --> tests/ui/get_unwrap.rs:37:17 @@ -33,8 +34,9 @@ LL | let _ = some_slice.get(0).unwrap(); | help: using `[]` is clearer and more concise | -LL | let _ = &some_slice[0]; - | ~~~~~~~~~~~~~~ +LL - let _ = some_slice.get(0).unwrap(); +LL + let _ = &some_slice[0]; + | error: used `unwrap()` on an `Option` value --> tests/ui/get_unwrap.rs:38:17 @@ -53,8 +55,9 @@ LL | let _ = some_vec.get(0).unwrap(); | help: using `[]` is clearer and more concise | -LL | let _ = &some_vec[0]; - | ~~~~~~~~~~~~ +LL - let _ = some_vec.get(0).unwrap(); +LL + let _ = &some_vec[0]; + | error: used `unwrap()` on an `Option` value --> tests/ui/get_unwrap.rs:39:17 @@ -73,8 +76,9 @@ LL | let _ = some_vecdeque.get(0).unwrap(); | help: using `[]` is clearer and more concise | -LL | let _ = &some_vecdeque[0]; - | ~~~~~~~~~~~~~~~~~ +LL - let _ = some_vecdeque.get(0).unwrap(); +LL + let _ = &some_vecdeque[0]; + | error: used `unwrap()` on an `Option` value --> tests/ui/get_unwrap.rs:40:17 @@ -93,8 +97,9 @@ LL | let _ = some_hashmap.get(&1).unwrap(); | help: using `[]` is clearer and more concise | -LL | let _ = &some_hashmap[&1]; - | ~~~~~~~~~~~~~~~~~ +LL - let _ = some_hashmap.get(&1).unwrap(); +LL + let _ = &some_hashmap[&1]; + | error: used `unwrap()` on an `Option` value --> tests/ui/get_unwrap.rs:41:17 @@ -113,8 +118,9 @@ LL | let _ = some_btreemap.get(&1).unwrap(); | help: using `[]` is clearer and more concise | -LL | let _ = &some_btreemap[&1]; - | ~~~~~~~~~~~~~~~~~~ +LL - let _ = some_btreemap.get(&1).unwrap(); +LL + let _ = &some_btreemap[&1]; + | error: used `unwrap()` on an `Option` value --> tests/ui/get_unwrap.rs:42:17 @@ -133,8 +139,9 @@ LL | let _: u8 = *boxed_slice.get(1).unwrap(); | help: using `[]` is clearer and more concise | -LL | let _: u8 = boxed_slice[1]; - | ~~~~~~~~~~~~~~ +LL - let _: u8 = *boxed_slice.get(1).unwrap(); +LL + let _: u8 = boxed_slice[1]; + | error: used `unwrap()` on an `Option` value --> tests/ui/get_unwrap.rs:46:22 @@ -153,8 +160,9 @@ LL | *boxed_slice.get_mut(0).unwrap() = 1; | help: using `[]` is clearer and more concise | -LL | boxed_slice[0] = 1; - | ~~~~~~~~~~~~~~ +LL - *boxed_slice.get_mut(0).unwrap() = 1; +LL + boxed_slice[0] = 1; + | error: used `unwrap()` on an `Option` value --> tests/ui/get_unwrap.rs:51:10 @@ -173,8 +181,9 @@ LL | *some_slice.get_mut(0).unwrap() = 1; | help: using `[]` is clearer and more concise | -LL | some_slice[0] = 1; - | ~~~~~~~~~~~~~ +LL - *some_slice.get_mut(0).unwrap() = 1; +LL + some_slice[0] = 1; + | error: used `unwrap()` on an `Option` value --> tests/ui/get_unwrap.rs:52:10 @@ -193,8 +202,9 @@ LL | *some_vec.get_mut(0).unwrap() = 1; | help: using `[]` is clearer and more concise | -LL | some_vec[0] = 1; - | ~~~~~~~~~~~ +LL - *some_vec.get_mut(0).unwrap() = 1; +LL + some_vec[0] = 1; + | error: used `unwrap()` on an `Option` value --> tests/ui/get_unwrap.rs:53:10 @@ -213,8 +223,9 @@ LL | *some_vecdeque.get_mut(0).unwrap() = 1; | help: using `[]` is clearer and more concise | -LL | some_vecdeque[0] = 1; - | ~~~~~~~~~~~~~~~~ +LL - *some_vecdeque.get_mut(0).unwrap() = 1; +LL + some_vecdeque[0] = 1; + | error: used `unwrap()` on an `Option` value --> tests/ui/get_unwrap.rs:54:10 @@ -233,8 +244,9 @@ LL | let _ = some_vec.get(0..1).unwrap().to_vec(); | help: using `[]` is clearer and more concise | -LL | let _ = some_vec[0..1].to_vec(); - | ~~~~~~~~~~~~~~ +LL - let _ = some_vec.get(0..1).unwrap().to_vec(); +LL + let _ = some_vec[0..1].to_vec(); + | error: used `unwrap()` on an `Option` value --> tests/ui/get_unwrap.rs:66:17 @@ -253,8 +265,9 @@ LL | let _ = some_vec.get_mut(0..1).unwrap().to_vec(); | help: using `[]` is clearer and more concise | -LL | let _ = some_vec[0..1].to_vec(); - | ~~~~~~~~~~~~~~ +LL - let _ = some_vec.get_mut(0..1).unwrap().to_vec(); +LL + let _ = some_vec[0..1].to_vec(); + | error: used `unwrap()` on an `Option` value --> tests/ui/get_unwrap.rs:67:17 @@ -273,8 +286,9 @@ LL | let _x: &i32 = f.get(1 + 2).unwrap(); | help: using `[]` is clearer and more concise | -LL | let _x: &i32 = &f[1 + 2]; - | ~~~~~~~~~ +LL - let _x: &i32 = f.get(1 + 2).unwrap(); +LL + let _x: &i32 = &f[1 + 2]; + | error: called `.get().unwrap()` on a slice --> tests/ui/get_unwrap.rs:81:18 @@ -284,8 +298,9 @@ LL | let _x = f.get(1 + 2).unwrap().to_string(); | help: using `[]` is clearer and more concise | -LL | let _x = f[1 + 2].to_string(); - | ~~~~~~~~ +LL - let _x = f.get(1 + 2).unwrap().to_string(); +LL + let _x = f[1 + 2].to_string(); + | error: called `.get().unwrap()` on a slice --> tests/ui/get_unwrap.rs:84:18 @@ -295,8 +310,9 @@ LL | let _x = f.get(1 + 2).unwrap().abs(); | help: using `[]` is clearer and more concise | -LL | let _x = f[1 + 2].abs(); - | ~~~~~~~~ +LL - let _x = f.get(1 + 2).unwrap().abs(); +LL + let _x = f[1 + 2].abs(); + | error: called `.get_mut().unwrap()` on a slice --> tests/ui/get_unwrap.rs:101:33 @@ -306,8 +322,9 @@ LL | let b = rest.get_mut(linidx(j, k) - linidx(i, k) - | help: using `[]` is clearer and more concise | -LL | let b = &mut rest[linidx(j, k) - linidx(i, k) - 1]; - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let b = rest.get_mut(linidx(j, k) - linidx(i, k) - 1).unwrap(); +LL + let b = &mut rest[linidx(j, k) - linidx(i, k) - 1]; + | error: aborting due to 30 previous errors diff --git a/src/tools/clippy/tests/ui/implicit_hasher.stderr b/src/tools/clippy/tests/ui/implicit_hasher.stderr index 442f4789aac..6e964c65a2e 100644 --- a/src/tools/clippy/tests/ui/implicit_hasher.stderr +++ b/src/tools/clippy/tests/ui/implicit_hasher.stderr @@ -78,8 +78,9 @@ LL | pub fn map(map: &mut HashMap<i32, i32>) {} | help: add a type parameter for `BuildHasher` | -LL | pub fn map<S: ::std::hash::BuildHasher>(map: &mut HashMap<i32, i32, S>) {} - | +++++++++++++++++++++++++++++ ~~~~~~~~~~~~~~~~~~~~ +LL - pub fn map(map: &mut HashMap<i32, i32>) {} +LL + pub fn map<S: ::std::hash::BuildHasher>(map: &mut HashMap<i32, i32, S>) {} + | error: parameter of type `HashSet` should be generalized over different hashers --> tests/ui/implicit_hasher.rs:70:22 @@ -89,8 +90,9 @@ LL | pub fn set(set: &mut HashSet<i32>) {} | help: add a type parameter for `BuildHasher` | -LL | pub fn set<S: ::std::hash::BuildHasher>(set: &mut HashSet<i32, S>) {} - | +++++++++++++++++++++++++++++ ~~~~~~~~~~~~~~~ +LL - pub fn set(set: &mut HashSet<i32>) {} +LL + pub fn set<S: ::std::hash::BuildHasher>(set: &mut HashSet<i32, S>) {} + | error: impl for `HashMap` should be generalized over different hashers --> tests/ui/implicit_hasher.rs:76:43 @@ -114,8 +116,9 @@ LL | pub async fn election_vote(_data: HashMap<i32, i32>) {} | help: add a type parameter for `BuildHasher` | -LL | pub async fn election_vote<S: ::std::hash::BuildHasher>(_data: HashMap<i32, i32, S>) {} - | +++++++++++++++++++++++++++++ ~~~~~~~~~~~~~~~~~~~~ +LL - pub async fn election_vote(_data: HashMap<i32, i32>) {} +LL + pub async fn election_vote<S: ::std::hash::BuildHasher>(_data: HashMap<i32, i32, S>) {} + | error: aborting due to 9 previous errors diff --git a/src/tools/clippy/tests/ui/implicit_return.stderr b/src/tools/clippy/tests/ui/implicit_return.stderr index 3b06f26f5a0..7ea72307450 100644 --- a/src/tools/clippy/tests/ui/implicit_return.stderr +++ b/src/tools/clippy/tests/ui/implicit_return.stderr @@ -20,7 +20,7 @@ LL | if true { true } else { false } help: add `return` as shown | LL | if true { return true } else { false } - | ~~~~~~~~~~~ + | ++++++ error: missing `return` statement --> tests/ui/implicit_return.rs:19:29 @@ -31,7 +31,7 @@ LL | if true { true } else { false } help: add `return` as shown | LL | if true { true } else { return false } - | ~~~~~~~~~~~~ + | ++++++ error: missing `return` statement --> tests/ui/implicit_return.rs:25:17 @@ -42,7 +42,7 @@ LL | true => false, help: add `return` as shown | LL | true => return false, - | ~~~~~~~~~~~~ + | ++++++ error: missing `return` statement --> tests/ui/implicit_return.rs:26:20 @@ -53,7 +53,7 @@ LL | false => { true }, help: add `return` as shown | LL | false => { return true }, - | ~~~~~~~~~~~ + | ++++++ error: missing `return` statement --> tests/ui/implicit_return.rs:39:9 @@ -63,8 +63,9 @@ LL | break true; | help: change `break` to `return` as shown | -LL | return true; - | ~~~~~~~~~~~ +LL - break true; +LL + return true; + | error: missing `return` statement --> tests/ui/implicit_return.rs:46:13 @@ -74,8 +75,9 @@ LL | break true; | help: change `break` to `return` as shown | -LL | return true; - | ~~~~~~~~~~~ +LL - break true; +LL + return true; + | error: missing `return` statement --> tests/ui/implicit_return.rs:54:13 @@ -85,8 +87,9 @@ LL | break true; | help: change `break` to `return` as shown | -LL | return true; - | ~~~~~~~~~~~ +LL - break true; +LL + return true; + | error: missing `return` statement --> tests/ui/implicit_return.rs:72:18 @@ -97,7 +100,7 @@ LL | let _ = || { true }; help: add `return` as shown | LL | let _ = || { return true }; - | ~~~~~~~~~~~ + | ++++++ error: missing `return` statement --> tests/ui/implicit_return.rs:73:16 @@ -108,7 +111,7 @@ LL | let _ = || true; help: add `return` as shown | LL | let _ = || return true; - | ~~~~~~~~~~~ + | ++++++ error: missing `return` statement --> tests/ui/implicit_return.rs:81:5 @@ -140,8 +143,9 @@ LL | break true; | help: change `break` to `return` as shown | -LL | return true; - | ~~~~~~~~~~~ +LL - break true; +LL + return true; + | error: missing `return` statement --> tests/ui/implicit_return.rs:101:17 @@ -151,8 +155,9 @@ LL | break 'outer false; | help: change `break` to `return` as shown | -LL | return false; - | ~~~~~~~~~~~~ +LL - break 'outer false; +LL + return false; + | error: missing `return` statement --> tests/ui/implicit_return.rs:116:5 diff --git a/src/tools/clippy/tests/ui/iter_nth.stderr b/src/tools/clippy/tests/ui/iter_nth.stderr index 178463f5347..1167a604ecd 100644 --- a/src/tools/clippy/tests/ui/iter_nth.stderr +++ b/src/tools/clippy/tests/ui/iter_nth.stderr @@ -8,8 +8,9 @@ LL | let bad_vec = some_vec.iter().nth(3); = help: to override `-D warnings` add `#[allow(clippy::iter_nth)]` help: `get` is equivalent but more concise | -LL | let bad_vec = some_vec.get(3); - | ~~~ +LL - let bad_vec = some_vec.iter().nth(3); +LL + let bad_vec = some_vec.get(3); + | error: called `.iter().nth()` on a slice --> tests/ui/iter_nth.rs:35:26 @@ -19,8 +20,9 @@ LL | let bad_slice = &some_vec[..].iter().nth(3); | help: `get` is equivalent but more concise | -LL | let bad_slice = &some_vec[..].get(3); - | ~~~ +LL - let bad_slice = &some_vec[..].iter().nth(3); +LL + let bad_slice = &some_vec[..].get(3); + | error: called `.iter().nth()` on a slice --> tests/ui/iter_nth.rs:36:31 @@ -30,8 +32,9 @@ LL | let bad_boxed_slice = boxed_slice.iter().nth(3); | help: `get` is equivalent but more concise | -LL | let bad_boxed_slice = boxed_slice.get(3); - | ~~~ +LL - let bad_boxed_slice = boxed_slice.iter().nth(3); +LL + let bad_boxed_slice = boxed_slice.get(3); + | error: called `.iter().nth()` on a `VecDeque` --> tests/ui/iter_nth.rs:37:29 @@ -41,8 +44,9 @@ LL | let bad_vec_deque = some_vec_deque.iter().nth(3); | help: `get` is equivalent but more concise | -LL | let bad_vec_deque = some_vec_deque.get(3); - | ~~~ +LL - let bad_vec_deque = some_vec_deque.iter().nth(3); +LL + let bad_vec_deque = some_vec_deque.get(3); + | error: called `.iter_mut().nth()` on a `Vec` --> tests/ui/iter_nth.rs:42:23 @@ -52,8 +56,9 @@ LL | let bad_vec = some_vec.iter_mut().nth(3); | help: `get_mut` is equivalent but more concise | -LL | let bad_vec = some_vec.get_mut(3); - | ~~~~~~~ +LL - let bad_vec = some_vec.iter_mut().nth(3); +LL + let bad_vec = some_vec.get_mut(3); + | error: called `.iter_mut().nth()` on a slice --> tests/ui/iter_nth.rs:45:26 @@ -63,8 +68,9 @@ LL | let bad_slice = &some_vec[..].iter_mut().nth(3); | help: `get_mut` is equivalent but more concise | -LL | let bad_slice = &some_vec[..].get_mut(3); - | ~~~~~~~ +LL - let bad_slice = &some_vec[..].iter_mut().nth(3); +LL + let bad_slice = &some_vec[..].get_mut(3); + | error: called `.iter_mut().nth()` on a `VecDeque` --> tests/ui/iter_nth.rs:48:29 @@ -74,8 +80,9 @@ LL | let bad_vec_deque = some_vec_deque.iter_mut().nth(3); | help: `get_mut` is equivalent but more concise | -LL | let bad_vec_deque = some_vec_deque.get_mut(3); - | ~~~~~~~ +LL - let bad_vec_deque = some_vec_deque.iter_mut().nth(3); +LL + let bad_vec_deque = some_vec_deque.get_mut(3); + | error: called `.iter().nth()` on a `Vec` --> tests/ui/iter_nth.rs:52:5 @@ -85,8 +92,9 @@ LL | vec_ref.iter().nth(3); | help: `get` is equivalent but more concise | -LL | vec_ref.get(3); - | ~~~ +LL - vec_ref.iter().nth(3); +LL + vec_ref.get(3); + | error: aborting due to 8 previous errors diff --git a/src/tools/clippy/tests/ui/join_absolute_paths.stderr b/src/tools/clippy/tests/ui/join_absolute_paths.stderr index e7fd5508823..300946bf3b5 100644 --- a/src/tools/clippy/tests/ui/join_absolute_paths.stderr +++ b/src/tools/clippy/tests/ui/join_absolute_paths.stderr @@ -9,12 +9,14 @@ LL | path.join("/sh"); = help: to override `-D warnings` add `#[allow(clippy::join_absolute_paths)]` help: if this is unintentional, try removing the starting separator | -LL | path.join("sh"); - | ~~~~ +LL - path.join("/sh"); +LL + path.join("sh"); + | help: if this is intentional, consider using `Path::new` | -LL | PathBuf::from("/sh"); - | ~~~~~~~~~~~~~~~~~~~~ +LL - path.join("/sh"); +LL + PathBuf::from("/sh"); + | error: argument to `Path::join` starts with a path separator --> tests/ui/join_absolute_paths.rs:14:15 @@ -25,12 +27,14 @@ LL | path.join("\\user"); = note: joining a path starting with separator will replace the path instead help: if this is unintentional, try removing the starting separator | -LL | path.join("\user"); - | ~~~~~~~ +LL - path.join("\\user"); +LL + path.join("\user"); + | help: if this is intentional, consider using `Path::new` | -LL | PathBuf::from("\\user"); - | ~~~~~~~~~~~~~~~~~~~~~~~ +LL - path.join("\\user"); +LL + PathBuf::from("\\user"); + | error: argument to `Path::join` starts with a path separator --> tests/ui/join_absolute_paths.rs:18:15 @@ -41,12 +45,14 @@ LL | path.join("/sh"); = note: joining a path starting with separator will replace the path instead help: if this is unintentional, try removing the starting separator | -LL | path.join("sh"); - | ~~~~ +LL - path.join("/sh"); +LL + path.join("sh"); + | help: if this is intentional, consider using `Path::new` | -LL | PathBuf::from("/sh"); - | ~~~~~~~~~~~~~~~~~~~~ +LL - path.join("/sh"); +LL + PathBuf::from("/sh"); + | error: argument to `Path::join` starts with a path separator --> tests/ui/join_absolute_paths.rs:22:15 @@ -57,12 +63,14 @@ LL | path.join(r#"/sh"#); = note: joining a path starting with separator will replace the path instead help: if this is unintentional, try removing the starting separator | -LL | path.join(r#"sh"#); - | ~~~~~~~ +LL - path.join(r#"/sh"#); +LL + path.join(r#"sh"#); + | help: if this is intentional, consider using `Path::new` | -LL | PathBuf::from(r#"/sh"#); - | ~~~~~~~~~~~~~~~~~~~~~~~ +LL - path.join(r#"/sh"#); +LL + PathBuf::from(r#"/sh"#); + | error: aborting due to 4 previous errors diff --git a/src/tools/clippy/tests/ui/large_enum_variant.64bit.stderr b/src/tools/clippy/tests/ui/large_enum_variant.64bit.stderr index 805cb406f83..60653b4abfb 100644 --- a/src/tools/clippy/tests/ui/large_enum_variant.64bit.stderr +++ b/src/tools/clippy/tests/ui/large_enum_variant.64bit.stderr @@ -13,8 +13,9 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::large_enum_variant)]` help: consider boxing the large fields to reduce the total size of the enum | -LL | B(Box<[i32; 8000]>), - | ~~~~~~~~~~~~~~~~ +LL - B([i32; 8000]), +LL + B(Box<[i32; 8000]>), + | error: large size difference between variants --> tests/ui/large_enum_variant.rs:35:1 @@ -29,8 +30,9 @@ LL | | } | help: consider boxing the large fields to reduce the total size of the enum | -LL | ContainingLargeEnum(Box<LargeEnum>), - | ~~~~~~~~~~~~~~ +LL - ContainingLargeEnum(LargeEnum), +LL + ContainingLargeEnum(Box<LargeEnum>), + | error: large size difference between variants --> tests/ui/large_enum_variant.rs:40:1 @@ -46,8 +48,9 @@ LL | | } | help: consider boxing the large fields to reduce the total size of the enum | -LL | ContainingMoreThanOneField(i32, Box<[i32; 8000]>, Box<[i32; 9500]>), - | ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~ +LL - ContainingMoreThanOneField(i32, [i32; 8000], [i32; 9500]), +LL + ContainingMoreThanOneField(i32, Box<[i32; 8000]>, Box<[i32; 9500]>), + | error: large size difference between variants --> tests/ui/large_enum_variant.rs:46:1 @@ -62,8 +65,9 @@ LL | | } | help: consider boxing the large fields to reduce the total size of the enum | -LL | StructLikeLarge { x: Box<[i32; 8000]>, y: i32 }, - | ~~~~~~~~~~~~~~~~ +LL - StructLikeLarge { x: [i32; 8000], y: i32 }, +LL + StructLikeLarge { x: Box<[i32; 8000]>, y: i32 }, + | error: large size difference between variants --> tests/ui/large_enum_variant.rs:51:1 @@ -78,8 +82,9 @@ LL | | } | help: consider boxing the large fields to reduce the total size of the enum | -LL | StructLikeLarge2 { x: Box<[i32; 8000]> }, - | ~~~~~~~~~~~~~~~~ +LL - StructLikeLarge2 { x: [i32; 8000] }, +LL + StructLikeLarge2 { x: Box<[i32; 8000]> }, + | error: large size difference between variants --> tests/ui/large_enum_variant.rs:67:1 @@ -95,8 +100,9 @@ LL | | } | help: consider boxing the large fields to reduce the total size of the enum | -LL | B(Box<[u8; 1255]>), - | ~~~~~~~~~~~~~~~ +LL - B([u8; 1255]), +LL + B(Box<[u8; 1255]>), + | error: large size difference between variants --> tests/ui/large_enum_variant.rs:73:1 @@ -111,8 +117,9 @@ LL | | } | help: consider boxing the large fields to reduce the total size of the enum | -LL | ContainingMoreThanOneField(Box<[i32; 8000]>, [i32; 2], Box<[i32; 9500]>, [i32; 30]), - | ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~ +LL - ContainingMoreThanOneField([i32; 8000], [i32; 2], [i32; 9500], [i32; 30]), +LL + ContainingMoreThanOneField(Box<[i32; 8000]>, [i32; 2], Box<[i32; 9500]>, [i32; 30]), + | error: large size difference between variants --> tests/ui/large_enum_variant.rs:78:1 @@ -127,8 +134,9 @@ LL | | } | help: consider boxing the large fields to reduce the total size of the enum | -LL | B(Box<Struct2>), - | ~~~~~~~~~~~~ +LL - B(Struct2), +LL + B(Box<Struct2>), + | error: large size difference between variants --> tests/ui/large_enum_variant.rs:83:1 @@ -143,8 +151,9 @@ LL | | } | help: consider boxing the large fields to reduce the total size of the enum | -LL | B(Box<Struct2>), - | ~~~~~~~~~~~~ +LL - B(Struct2), +LL + B(Box<Struct2>), + | error: large size difference between variants --> tests/ui/large_enum_variant.rs:88:1 @@ -159,8 +168,9 @@ LL | | } | help: consider boxing the large fields to reduce the total size of the enum | -LL | B(Box<Struct2>), - | ~~~~~~~~~~~~ +LL - B(Struct2), +LL + B(Box<Struct2>), + | error: large size difference between variants --> tests/ui/large_enum_variant.rs:103:1 @@ -241,8 +251,9 @@ LL | | } | help: consider boxing the large fields to reduce the total size of the enum | -LL | Large(Box<(T, [u8; 512])>), - | ~~~~~~~~~~~~~~~~~~~ +LL - Large((T, [u8; 512])), +LL + Large(Box<(T, [u8; 512])>), + | error: large size difference between variants --> tests/ui/large_enum_variant.rs:143:1 @@ -257,8 +268,9 @@ LL | | } | help: consider boxing the large fields to reduce the total size of the enum | -LL | Large(Box<[Foo<u64>; 64]>), - | ~~~~~~~~~~~~~~~~~~~ +LL - Large([Foo<u64>; 64]), +LL + Large(Box<[Foo<u64>; 64]>), + | error: large size difference between variants --> tests/ui/large_enum_variant.rs:153:1 @@ -273,8 +285,9 @@ LL | | } | help: consider boxing the large fields to reduce the total size of the enum | -LL | Error(Box<PossiblyLargeEnumWithConst<256>>), - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - Error(PossiblyLargeEnumWithConst<256>), +LL + Error(Box<PossiblyLargeEnumWithConst<256>>), + | error: aborting due to 16 previous errors diff --git a/src/tools/clippy/tests/ui/legacy_numeric_constants.stderr b/src/tools/clippy/tests/ui/legacy_numeric_constants.stderr index 267b9ac8e4d..91dfe79d55b 100644 --- a/src/tools/clippy/tests/ui/legacy_numeric_constants.stderr +++ b/src/tools/clippy/tests/ui/legacy_numeric_constants.stderr @@ -8,8 +8,9 @@ LL | std::f32::EPSILON; = help: to override `-D warnings` add `#[allow(clippy::legacy_numeric_constants)]` help: use the associated constant instead | -LL | f32::EPSILON; - | ~~~~~~~~~~~~ +LL - std::f32::EPSILON; +LL + f32::EPSILON; + | error: usage of a legacy numeric constant --> tests/ui/legacy_numeric_constants.rs:34:5 @@ -19,8 +20,9 @@ LL | std::u8::MIN; | help: use the associated constant instead | -LL | u8::MIN; - | ~~~~~~~ +LL - std::u8::MIN; +LL + u8::MIN; + | error: usage of a legacy numeric constant --> tests/ui/legacy_numeric_constants.rs:37:5 @@ -30,8 +32,9 @@ LL | std::usize::MIN; | help: use the associated constant instead | -LL | usize::MIN; - | ~~~~~~~~~~ +LL - std::usize::MIN; +LL + usize::MIN; + | error: usage of a legacy numeric constant --> tests/ui/legacy_numeric_constants.rs:40:5 @@ -41,8 +44,9 @@ LL | std::u32::MAX; | help: use the associated constant instead | -LL | u32::MAX; - | ~~~~~~~~ +LL - std::u32::MAX; +LL + u32::MAX; + | error: usage of a legacy numeric constant --> tests/ui/legacy_numeric_constants.rs:43:5 @@ -52,8 +56,9 @@ LL | core::u32::MAX; | help: use the associated constant instead | -LL | u32::MAX; - | ~~~~~~~~ +LL - core::u32::MAX; +LL + u32::MAX; + | error: usage of a legacy numeric constant --> tests/ui/legacy_numeric_constants.rs:46:5 @@ -64,7 +69,7 @@ LL | MAX; help: use the associated constant instead | LL | u32::MAX; - | ~~~~~~~~ + | +++++ error: usage of a legacy numeric method --> tests/ui/legacy_numeric_constants.rs:49:10 @@ -74,8 +79,9 @@ LL | i32::max_value(); | help: use the associated constant instead | -LL | i32::MAX; - | ~~~ +LL - i32::max_value(); +LL + i32::MAX; + | error: usage of a legacy numeric method --> tests/ui/legacy_numeric_constants.rs:52:9 @@ -85,8 +91,9 @@ LL | u8::max_value(); | help: use the associated constant instead | -LL | u8::MAX; - | ~~~ +LL - u8::max_value(); +LL + u8::MAX; + | error: usage of a legacy numeric method --> tests/ui/legacy_numeric_constants.rs:55:9 @@ -96,8 +103,9 @@ LL | u8::min_value(); | help: use the associated constant instead | -LL | u8::MIN; - | ~~~ +LL - u8::min_value(); +LL + u8::MIN; + | error: usage of a legacy numeric constant --> tests/ui/legacy_numeric_constants.rs:58:5 @@ -107,8 +115,9 @@ LL | ::std::u8::MIN; | help: use the associated constant instead | -LL | u8::MIN; - | ~~~~~~~ +LL - ::std::u8::MIN; +LL + u8::MIN; + | error: usage of a legacy numeric method --> tests/ui/legacy_numeric_constants.rs:61:27 @@ -118,8 +127,9 @@ LL | ::std::primitive::u8::min_value(); | help: use the associated constant instead | -LL | ::std::primitive::u8::MIN; - | ~~~ +LL - ::std::primitive::u8::min_value(); +LL + ::std::primitive::u8::MIN; + | error: usage of a legacy numeric method --> tests/ui/legacy_numeric_constants.rs:64:26 @@ -129,8 +139,9 @@ LL | std::primitive::i32::max_value(); | help: use the associated constant instead | -LL | std::primitive::i32::MAX; - | ~~~ +LL - std::primitive::i32::max_value(); +LL + std::primitive::i32::MAX; + | error: usage of a legacy numeric constant --> tests/ui/legacy_numeric_constants.rs:67:5 @@ -140,8 +151,9 @@ LL | self::a::u128::MAX; | help: use the associated constant instead | -LL | u128::MAX; - | ~~~~~~~~~ +LL - self::a::u128::MAX; +LL + u128::MAX; + | error: usage of a legacy numeric constant --> tests/ui/legacy_numeric_constants.rs:17:25 @@ -155,8 +167,9 @@ LL | b!(); = note: this error originates in the macro `b` (in Nightly builds, run with -Z macro-backtrace for more info) help: use the associated constant instead | -LL | let x = u64::MAX; - | ~~~~~~~~ +LL - let x = std::u64::MAX; +LL + let x = u64::MAX; + | error: usage of a legacy numeric constant --> tests/ui/legacy_numeric_constants.rs:81:14 @@ -166,8 +179,9 @@ LL | [(0, "", std::i128::MAX)]; | help: use the associated constant instead | -LL | [(0, "", i128::MAX)]; - | ~~~~~~~~~ +LL - [(0, "", std::i128::MAX)]; +LL + [(0, "", i128::MAX)]; + | error: usage of a legacy numeric constant --> tests/ui/legacy_numeric_constants.rs:115:5 @@ -177,8 +191,9 @@ LL | std::u32::MAX; | help: use the associated constant instead | -LL | u32::MAX; - | ~~~~~~~~ +LL - std::u32::MAX; +LL + u32::MAX; + | error: aborting due to 16 previous errors diff --git a/src/tools/clippy/tests/ui/literals.stderr b/src/tools/clippy/tests/ui/literals.stderr index 564e0bc4f74..a9192825b35 100644 --- a/src/tools/clippy/tests/ui/literals.stderr +++ b/src/tools/clippy/tests/ui/literals.stderr @@ -71,12 +71,14 @@ LL | let fail_multi_zero = 000_123usize; = help: to override `-D warnings` add `#[allow(clippy::zero_prefixed_literal)]` help: if you mean to use a decimal constant, remove the `0` to avoid confusion | -LL | let fail_multi_zero = 123usize; - | ~~~~~~~~ +LL - let fail_multi_zero = 000_123usize; +LL + let fail_multi_zero = 123usize; + | help: if you mean to use an octal constant, use `0o` | -LL | let fail_multi_zero = 0o123usize; - | ~~~~~~~~~~ +LL - let fail_multi_zero = 000_123usize; +LL + let fail_multi_zero = 0o123usize; + | error: integer type suffix should not be separated by an underscore --> tests/ui/literals.rs:36:16 @@ -92,12 +94,14 @@ LL | let fail8 = 0123; | help: if you mean to use a decimal constant, remove the `0` to avoid confusion | -LL | let fail8 = 123; - | ~~~ +LL - let fail8 = 0123; +LL + let fail8 = 123; + | help: if you mean to use an octal constant, use `0o` | -LL | let fail8 = 0o123; - | ~~~~~ +LL - let fail8 = 0123; +LL + let fail8 = 0o123; + | error: integer type suffix should not be separated by an underscore --> tests/ui/literals.rs:48:16 @@ -143,8 +147,9 @@ LL | let _ = 08; | help: if you mean to use a decimal constant, remove the `0` to avoid confusion | -LL | let _ = 8; - | ~ +LL - let _ = 08; +LL + let _ = 8; + | error: this is a decimal constant --> tests/ui/literals.rs:72:13 @@ -154,8 +159,9 @@ LL | let _ = 09; | help: if you mean to use a decimal constant, remove the `0` to avoid confusion | -LL | let _ = 9; - | ~ +LL - let _ = 09; +LL + let _ = 9; + | error: this is a decimal constant --> tests/ui/literals.rs:74:13 @@ -165,8 +171,9 @@ LL | let _ = 089; | help: if you mean to use a decimal constant, remove the `0` to avoid confusion | -LL | let _ = 89; - | ~~ +LL - let _ = 089; +LL + let _ = 89; + | error: aborting due to 20 previous errors diff --git a/src/tools/clippy/tests/ui/lossy_float_literal.stderr b/src/tools/clippy/tests/ui/lossy_float_literal.stderr index 3026854e317..118351a62d0 100644 --- a/src/tools/clippy/tests/ui/lossy_float_literal.stderr +++ b/src/tools/clippy/tests/ui/lossy_float_literal.stderr @@ -8,8 +8,9 @@ LL | let _: f32 = 16_777_217.0; = help: to override `-D warnings` add `#[allow(clippy::lossy_float_literal)]` help: consider changing the type or replacing it with | -LL | let _: f32 = 16_777_216.0; - | ~~~~~~~~~~~~ +LL - let _: f32 = 16_777_217.0; +LL + let _: f32 = 16_777_216.0; + | error: literal cannot be represented as the underlying type without loss of precision --> tests/ui/lossy_float_literal.rs:15:18 @@ -19,8 +20,9 @@ LL | let _: f32 = 16_777_219.0; | help: consider changing the type or replacing it with | -LL | let _: f32 = 16_777_220.0; - | ~~~~~~~~~~~~ +LL - let _: f32 = 16_777_219.0; +LL + let _: f32 = 16_777_220.0; + | error: literal cannot be represented as the underlying type without loss of precision --> tests/ui/lossy_float_literal.rs:16:18 @@ -30,8 +32,9 @@ LL | let _: f32 = 16_777_219.; | help: consider changing the type or replacing it with | -LL | let _: f32 = 16_777_220.0; - | ~~~~~~~~~~~~ +LL - let _: f32 = 16_777_219.; +LL + let _: f32 = 16_777_220.0; + | error: literal cannot be represented as the underlying type without loss of precision --> tests/ui/lossy_float_literal.rs:17:18 @@ -41,8 +44,9 @@ LL | let _: f32 = 16_777_219.000; | help: consider changing the type or replacing it with | -LL | let _: f32 = 16_777_220.0; - | ~~~~~~~~~~~~ +LL - let _: f32 = 16_777_219.000; +LL + let _: f32 = 16_777_220.0; + | error: literal cannot be represented as the underlying type without loss of precision --> tests/ui/lossy_float_literal.rs:18:13 @@ -52,8 +56,9 @@ LL | let _ = 16_777_219f32; | help: consider changing the type or replacing it with | -LL | let _ = 16_777_220_f32; - | ~~~~~~~~~~~~~~ +LL - let _ = 16_777_219f32; +LL + let _ = 16_777_220_f32; + | error: literal cannot be represented as the underlying type without loss of precision --> tests/ui/lossy_float_literal.rs:19:19 @@ -63,8 +68,9 @@ LL | let _: f32 = -16_777_219.0; | help: consider changing the type or replacing it with | -LL | let _: f32 = -16_777_220.0; - | ~~~~~~~~~~~~ +LL - let _: f32 = -16_777_219.0; +LL + let _: f32 = -16_777_220.0; + | error: literal cannot be represented as the underlying type without loss of precision --> tests/ui/lossy_float_literal.rs:21:18 @@ -74,8 +80,9 @@ LL | let _: f64 = 9_007_199_254_740_993.0; | help: consider changing the type or replacing it with | -LL | let _: f64 = 9_007_199_254_740_992.0; - | ~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _: f64 = 9_007_199_254_740_993.0; +LL + let _: f64 = 9_007_199_254_740_992.0; + | error: literal cannot be represented as the underlying type without loss of precision --> tests/ui/lossy_float_literal.rs:22:18 @@ -85,8 +92,9 @@ LL | let _: f64 = 9_007_199_254_740_993.; | help: consider changing the type or replacing it with | -LL | let _: f64 = 9_007_199_254_740_992.0; - | ~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _: f64 = 9_007_199_254_740_993.; +LL + let _: f64 = 9_007_199_254_740_992.0; + | error: literal cannot be represented as the underlying type without loss of precision --> tests/ui/lossy_float_literal.rs:23:18 @@ -96,8 +104,9 @@ LL | let _: f64 = 9_007_199_254_740_993.00; | help: consider changing the type or replacing it with | -LL | let _: f64 = 9_007_199_254_740_992.0; - | ~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _: f64 = 9_007_199_254_740_993.00; +LL + let _: f64 = 9_007_199_254_740_992.0; + | error: literal cannot be represented as the underlying type without loss of precision --> tests/ui/lossy_float_literal.rs:24:13 @@ -107,8 +116,9 @@ LL | let _ = 9_007_199_254_740_993f64; | help: consider changing the type or replacing it with | -LL | let _ = 9_007_199_254_740_992_f64; - | ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _ = 9_007_199_254_740_993f64; +LL + let _ = 9_007_199_254_740_992_f64; + | error: literal cannot be represented as the underlying type without loss of precision --> tests/ui/lossy_float_literal.rs:25:19 @@ -118,8 +128,9 @@ LL | let _: f64 = -9_007_199_254_740_993.0; | help: consider changing the type or replacing it with | -LL | let _: f64 = -9_007_199_254_740_992.0; - | ~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _: f64 = -9_007_199_254_740_993.0; +LL + let _: f64 = -9_007_199_254_740_992.0; + | error: aborting due to 11 previous errors diff --git a/src/tools/clippy/tests/ui/manual_assert.edition2018.stderr b/src/tools/clippy/tests/ui/manual_assert.edition2018.stderr index 004463720e2..dfccf7e9939 100644 --- a/src/tools/clippy/tests/ui/manual_assert.edition2018.stderr +++ b/src/tools/clippy/tests/ui/manual_assert.edition2018.stderr @@ -79,7 +79,15 @@ LL | | } | help: try instead | -LL | assert!(!(a > 2), "panic with comment"); +LL - if a > 2 { +LL - // comment +LL - /* this is a +LL - multiline +LL - comment */ +LL - /// Doc comment +LL - panic!("panic with comment") // comment after `panic!` +LL - } +LL + assert!(!(a > 2), "panic with comment"); | error: only a `panic!` in `if`-then statement diff --git a/src/tools/clippy/tests/ui/manual_assert.edition2021.stderr b/src/tools/clippy/tests/ui/manual_assert.edition2021.stderr index 004463720e2..dfccf7e9939 100644 --- a/src/tools/clippy/tests/ui/manual_assert.edition2021.stderr +++ b/src/tools/clippy/tests/ui/manual_assert.edition2021.stderr @@ -79,7 +79,15 @@ LL | | } | help: try instead | -LL | assert!(!(a > 2), "panic with comment"); +LL - if a > 2 { +LL - // comment +LL - /* this is a +LL - multiline +LL - comment */ +LL - /// Doc comment +LL - panic!("panic with comment") // comment after `panic!` +LL - } +LL + assert!(!(a > 2), "panic with comment"); | error: only a `panic!` in `if`-then statement diff --git a/src/tools/clippy/tests/ui/manual_async_fn.stderr b/src/tools/clippy/tests/ui/manual_async_fn.stderr index 68a97243436..a7cfc30fb69 100644 --- a/src/tools/clippy/tests/ui/manual_async_fn.stderr +++ b/src/tools/clippy/tests/ui/manual_async_fn.stderr @@ -8,8 +8,9 @@ LL | fn fut() -> impl Future<Output = i32> { = help: to override `-D warnings` add `#[allow(clippy::manual_async_fn)]` help: make the function `async` and return the output of the future directly | -LL | async fn fut() -> i32 { 42 } - | ~~~~~~~~~~~~~~~~~~~~~ ~~~~~~ +LL - fn fut() -> impl Future<Output = i32> { +LL + async fn fut() -> i32 { 42 } + | error: this function can be simplified using the `async fn` syntax --> tests/ui/manual_async_fn.rs:11:1 @@ -19,8 +20,9 @@ LL | fn fut2() ->impl Future<Output = i32> { | help: make the function `async` and return the output of the future directly | -LL | async fn fut2() -> i32 { 42 } - | ~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~ +LL - fn fut2() ->impl Future<Output = i32> { +LL + async fn fut2() -> i32 { 42 } + | error: this function can be simplified using the `async fn` syntax --> tests/ui/manual_async_fn.rs:16:1 @@ -30,8 +32,9 @@ LL | fn fut3()-> impl Future<Output = i32> { | help: make the function `async` and return the output of the future directly | -LL | async fn fut3() -> i32 { 42 } - | ~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~ +LL - fn fut3()-> impl Future<Output = i32> { +LL + async fn fut3() -> i32 { 42 } + | error: this function can be simplified using the `async fn` syntax --> tests/ui/manual_async_fn.rs:20:1 @@ -41,8 +44,9 @@ LL | fn empty_fut() -> impl Future<Output = ()> { | help: make the function `async` and return the output of the future directly | -LL | async fn empty_fut() {} - | ~~~~~~~~~~~~~~~~~~~~ ~~ +LL - fn empty_fut() -> impl Future<Output = ()> { +LL + async fn empty_fut() {} + | error: this function can be simplified using the `async fn` syntax --> tests/ui/manual_async_fn.rs:25:1 @@ -52,8 +56,9 @@ LL | fn empty_fut2() ->impl Future<Output = ()> { | help: make the function `async` and return the output of the future directly | -LL | async fn empty_fut2() {} - | ~~~~~~~~~~~~~~~~~~~~~ ~~ +LL - fn empty_fut2() ->impl Future<Output = ()> { +LL + async fn empty_fut2() {} + | error: this function can be simplified using the `async fn` syntax --> tests/ui/manual_async_fn.rs:30:1 @@ -63,8 +68,9 @@ LL | fn empty_fut3()-> impl Future<Output = ()> { | help: make the function `async` and return the output of the future directly | -LL | async fn empty_fut3() {} - | ~~~~~~~~~~~~~~~~~~~~~ ~~ +LL - fn empty_fut3()-> impl Future<Output = ()> { +LL + async fn empty_fut3() {} + | error: this function can be simplified using the `async fn` syntax --> tests/ui/manual_async_fn.rs:34:1 @@ -74,8 +80,9 @@ LL | fn core_fut() -> impl core::future::Future<Output = i32> { | help: make the function `async` and return the output of the future directly | -LL | async fn core_fut() -> i32 { 42 } - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~ +LL - fn core_fut() -> impl core::future::Future<Output = i32> { +LL + async fn core_fut() -> i32 { 42 } + | error: this function can be simplified using the `async fn` syntax --> tests/ui/manual_async_fn.rs:56:5 @@ -108,8 +115,9 @@ LL | fn elided(_: &i32) -> impl Future<Output = i32> + '_ { | help: make the function `async` and return the output of the future directly | -LL | async fn elided(_: &i32) -> i32 { 42 } - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~ +LL - fn elided(_: &i32) -> impl Future<Output = i32> + '_ { +LL + async fn elided(_: &i32) -> i32 { 42 } + | error: this function can be simplified using the `async fn` syntax --> tests/ui/manual_async_fn.rs:101:1 @@ -119,8 +127,9 @@ LL | fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> impl Future<Output = i32> + | help: make the function `async` and return the output of the future directly | -LL | async fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> i32 { 42 } - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~ +LL - fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> impl Future<Output = i32> + 'a + 'b { +LL + async fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> i32 { 42 } + | error: this function can be simplified using the `async fn` syntax --> tests/ui/manual_async_fn.rs:130:1 @@ -130,8 +139,9 @@ LL | pub fn issue_10450() -> impl Future<Output = i32> { | help: make the function `async` and return the output of the future directly | -LL | pub async fn issue_10450() -> i32 { 42 } - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~ +LL - pub fn issue_10450() -> impl Future<Output = i32> { +LL + pub async fn issue_10450() -> i32 { 42 } + | error: this function can be simplified using the `async fn` syntax --> tests/ui/manual_async_fn.rs:134:1 @@ -141,8 +151,9 @@ LL | pub(crate) fn issue_10450_2() -> impl Future<Output = i32> { | help: make the function `async` and return the output of the future directly | -LL | pub(crate) async fn issue_10450_2() -> i32 { 42 } - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~ +LL - pub(crate) fn issue_10450_2() -> impl Future<Output = i32> { +LL + pub(crate) async fn issue_10450_2() -> i32 { 42 } + | error: this function can be simplified using the `async fn` syntax --> tests/ui/manual_async_fn.rs:138:1 @@ -152,8 +163,9 @@ LL | pub(self) fn issue_10450_3() -> impl Future<Output = i32> { | help: make the function `async` and return the output of the future directly | -LL | pub(self) async fn issue_10450_3() -> i32 { 42 } - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~ +LL - pub(self) fn issue_10450_3() -> impl Future<Output = i32> { +LL + pub(self) async fn issue_10450_3() -> i32 { 42 } + | error: aborting due to 13 previous errors diff --git a/src/tools/clippy/tests/ui/manual_float_methods.stderr b/src/tools/clippy/tests/ui/manual_float_methods.stderr index 676a4485ab4..1352c5e73ca 100644 --- a/src/tools/clippy/tests/ui/manual_float_methods.stderr +++ b/src/tools/clippy/tests/ui/manual_float_methods.stderr @@ -17,16 +17,19 @@ LL | if x != f32::INFINITY && x != f32::NEG_INFINITY {} = help: to override `-D warnings` add `#[allow(clippy::manual_is_finite)]` help: use the dedicated method instead | -LL | if x.is_finite() {} - | ~~~~~~~~~~~~~ +LL - if x != f32::INFINITY && x != f32::NEG_INFINITY {} +LL + if x.is_finite() {} + | help: this will alter how it handles NaN; if that is a problem, use instead | -LL | if x.is_finite() || x.is_nan() {} - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - if x != f32::INFINITY && x != f32::NEG_INFINITY {} +LL + if x.is_finite() || x.is_nan() {} + | help: or, for conciseness | -LL | if !x.is_infinite() {} - | ~~~~~~~~~~~~~~~~ +LL - if x != f32::INFINITY && x != f32::NEG_INFINITY {} +LL + if !x.is_infinite() {} + | error: manually checking if a float is infinite --> tests/ui/manual_float_methods.rs:26:8 @@ -42,16 +45,19 @@ LL | if x != INFINITE && x != NEG_INFINITE {} | help: use the dedicated method instead | -LL | if x.is_finite() {} - | ~~~~~~~~~~~~~ +LL - if x != INFINITE && x != NEG_INFINITE {} +LL + if x.is_finite() {} + | help: this will alter how it handles NaN; if that is a problem, use instead | -LL | if x.is_finite() || x.is_nan() {} - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - if x != INFINITE && x != NEG_INFINITE {} +LL + if x.is_finite() || x.is_nan() {} + | help: or, for conciseness | -LL | if !x.is_infinite() {} - | ~~~~~~~~~~~~~~~~ +LL - if x != INFINITE && x != NEG_INFINITE {} +LL + if !x.is_infinite() {} + | error: manually checking if a float is infinite --> tests/ui/manual_float_methods.rs:29:8 @@ -67,16 +73,19 @@ LL | if x != f64::INFINITY && x != f64::NEG_INFINITY {} | help: use the dedicated method instead | -LL | if x.is_finite() {} - | ~~~~~~~~~~~~~ +LL - if x != f64::INFINITY && x != f64::NEG_INFINITY {} +LL + if x.is_finite() {} + | help: this will alter how it handles NaN; if that is a problem, use instead | -LL | if x.is_finite() || x.is_nan() {} - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - if x != f64::INFINITY && x != f64::NEG_INFINITY {} +LL + if x.is_finite() || x.is_nan() {} + | help: or, for conciseness | -LL | if !x.is_infinite() {} - | ~~~~~~~~~~~~~~~~ +LL - if x != f64::INFINITY && x != f64::NEG_INFINITY {} +LL + if !x.is_infinite() {} + | error: manually checking if a float is infinite --> tests/ui/manual_float_methods.rs:44:12 diff --git a/src/tools/clippy/tests/ui/manual_ignore_case_cmp.stderr b/src/tools/clippy/tests/ui/manual_ignore_case_cmp.stderr index 11e8b8aebb5..bc6393b66d5 100644 --- a/src/tools/clippy/tests/ui/manual_ignore_case_cmp.stderr +++ b/src/tools/clippy/tests/ui/manual_ignore_case_cmp.stderr @@ -11,8 +11,9 @@ LL | #![deny(clippy::manual_ignore_case_cmp)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.eq_ignore_ascii_case()` instead | -LL | if a.eq_ignore_ascii_case(b) { - | ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - if a.to_ascii_lowercase() == b.to_ascii_lowercase() { +LL + if a.eq_ignore_ascii_case(b) { + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:12:8 @@ -22,8 +23,9 @@ LL | if a.to_ascii_uppercase() == b.to_ascii_uppercase() { | help: consider using `.eq_ignore_ascii_case()` instead | -LL | if a.eq_ignore_ascii_case(b) { - | ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - if a.to_ascii_uppercase() == b.to_ascii_uppercase() { +LL + if a.eq_ignore_ascii_case(b) { + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:15:13 @@ -33,8 +35,9 @@ LL | let r = a.to_ascii_lowercase() == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | let r = a.eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let r = a.to_ascii_lowercase() == b.to_ascii_lowercase(); +LL + let r = a.eq_ignore_ascii_case(b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:16:18 @@ -44,8 +47,9 @@ LL | let r = r || a.to_ascii_uppercase() == b.to_ascii_uppercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | let r = r || a.eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let r = r || a.to_ascii_uppercase() == b.to_ascii_uppercase(); +LL + let r = r || a.eq_ignore_ascii_case(b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:17:10 @@ -55,8 +59,9 @@ LL | r && a.to_ascii_lowercase() == b.to_uppercase().to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | r && a.eq_ignore_ascii_case(&b.to_uppercase()); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - r && a.to_ascii_lowercase() == b.to_uppercase().to_ascii_lowercase(); +LL + r && a.eq_ignore_ascii_case(&b.to_uppercase()); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:19:8 @@ -66,8 +71,9 @@ LL | if a.to_ascii_lowercase() != b.to_ascii_lowercase() { | help: consider using `.eq_ignore_ascii_case()` instead | -LL | if !a.eq_ignore_ascii_case(b) { - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - if a.to_ascii_lowercase() != b.to_ascii_lowercase() { +LL + if !a.eq_ignore_ascii_case(b) { + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:22:8 @@ -77,8 +83,9 @@ LL | if a.to_ascii_uppercase() != b.to_ascii_uppercase() { | help: consider using `.eq_ignore_ascii_case()` instead | -LL | if !a.eq_ignore_ascii_case(b) { - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - if a.to_ascii_uppercase() != b.to_ascii_uppercase() { +LL + if !a.eq_ignore_ascii_case(b) { + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:25:13 @@ -88,8 +95,9 @@ LL | let r = a.to_ascii_lowercase() != b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | let r = !a.eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let r = a.to_ascii_lowercase() != b.to_ascii_lowercase(); +LL + let r = !a.eq_ignore_ascii_case(b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:26:18 @@ -99,8 +107,9 @@ LL | let r = r || a.to_ascii_uppercase() != b.to_ascii_uppercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | let r = r || !a.eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let r = r || a.to_ascii_uppercase() != b.to_ascii_uppercase(); +LL + let r = r || !a.eq_ignore_ascii_case(b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:27:10 @@ -110,8 +119,9 @@ LL | r && a.to_ascii_lowercase() != b.to_uppercase().to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | r && !a.eq_ignore_ascii_case(&b.to_uppercase()); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - r && a.to_ascii_lowercase() != b.to_uppercase().to_ascii_lowercase(); +LL + r && !a.eq_ignore_ascii_case(&b.to_uppercase()); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:38:5 @@ -121,8 +131,9 @@ LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.eq_ignore_ascii_case(&b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_ascii_lowercase() == b.to_ascii_lowercase(); +LL + a.eq_ignore_ascii_case(&b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:41:5 @@ -132,8 +143,9 @@ LL | a.to_ascii_lowercase() == 'a'; | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.eq_ignore_ascii_case(&'a'); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_ascii_lowercase() == 'a'; +LL + a.eq_ignore_ascii_case(&'a'); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:42:5 @@ -143,8 +155,9 @@ LL | 'a' == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | 'a'.eq_ignore_ascii_case(&b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - 'a' == b.to_ascii_lowercase(); +LL + 'a'.eq_ignore_ascii_case(&b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:45:5 @@ -154,8 +167,9 @@ LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.eq_ignore_ascii_case(&b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_ascii_lowercase() == b.to_ascii_lowercase(); +LL + a.eq_ignore_ascii_case(&b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:46:5 @@ -165,8 +179,9 @@ LL | a.to_ascii_lowercase() == b'a'; | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.eq_ignore_ascii_case(&b'a'); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_ascii_lowercase() == b'a'; +LL + a.eq_ignore_ascii_case(&b'a'); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:47:5 @@ -176,8 +191,9 @@ LL | b'a' == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | b'a'.eq_ignore_ascii_case(&b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - b'a' == b.to_ascii_lowercase(); +LL + b'a'.eq_ignore_ascii_case(&b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:50:5 @@ -187,8 +203,9 @@ LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_ascii_lowercase() == b.to_ascii_lowercase(); +LL + a.eq_ignore_ascii_case(b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:51:5 @@ -198,8 +215,9 @@ LL | a.to_uppercase().to_ascii_lowercase() == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.to_uppercase().eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_uppercase().to_ascii_lowercase() == b.to_ascii_lowercase(); +LL + a.to_uppercase().eq_ignore_ascii_case(b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:52:5 @@ -209,8 +227,9 @@ LL | a.to_ascii_lowercase() == "a"; | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.eq_ignore_ascii_case("a"); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_ascii_lowercase() == "a"; +LL + a.eq_ignore_ascii_case("a"); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:53:5 @@ -220,8 +239,9 @@ LL | "a" == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | "a".eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - "a" == b.to_ascii_lowercase(); +LL + "a".eq_ignore_ascii_case(b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:56:5 @@ -231,8 +251,9 @@ LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_ascii_lowercase() == b.to_ascii_lowercase(); +LL + a.eq_ignore_ascii_case(b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:57:5 @@ -242,8 +263,9 @@ LL | a.to_uppercase().to_ascii_lowercase() == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.to_uppercase().eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_uppercase().to_ascii_lowercase() == b.to_ascii_lowercase(); +LL + a.to_uppercase().eq_ignore_ascii_case(b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:58:5 @@ -253,8 +275,9 @@ LL | a.to_ascii_lowercase() == "a"; | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.eq_ignore_ascii_case("a"); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_ascii_lowercase() == "a"; +LL + a.eq_ignore_ascii_case("a"); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:59:5 @@ -264,8 +287,9 @@ LL | "a" == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | "a".eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - "a" == b.to_ascii_lowercase(); +LL + "a".eq_ignore_ascii_case(b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:62:5 @@ -275,8 +299,9 @@ LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.eq_ignore_ascii_case(&b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_ascii_lowercase() == b.to_ascii_lowercase(); +LL + a.eq_ignore_ascii_case(&b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:63:5 @@ -286,8 +311,9 @@ LL | a.to_ascii_lowercase() == "a"; | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.eq_ignore_ascii_case("a"); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_ascii_lowercase() == "a"; +LL + a.eq_ignore_ascii_case("a"); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:64:5 @@ -297,8 +323,9 @@ LL | "a" == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | "a".eq_ignore_ascii_case(&b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - "a" == b.to_ascii_lowercase(); +LL + "a".eq_ignore_ascii_case(&b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:67:5 @@ -308,8 +335,9 @@ LL | a.to_ascii_lowercase() == "a"; | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.eq_ignore_ascii_case("a"); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_ascii_lowercase() == "a"; +LL + a.eq_ignore_ascii_case("a"); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:68:5 @@ -319,8 +347,9 @@ LL | "a" == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | "a".eq_ignore_ascii_case(&b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - "a" == b.to_ascii_lowercase(); +LL + "a".eq_ignore_ascii_case(&b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:71:5 @@ -330,8 +359,9 @@ LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_ascii_lowercase() == b.to_ascii_lowercase(); +LL + a.eq_ignore_ascii_case(b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:72:5 @@ -341,8 +371,9 @@ LL | a.to_ascii_lowercase() == "a"; | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.eq_ignore_ascii_case("a"); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_ascii_lowercase() == "a"; +LL + a.eq_ignore_ascii_case("a"); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:73:5 @@ -352,8 +383,9 @@ LL | "a" == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | "a".eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - "a" == b.to_ascii_lowercase(); +LL + "a".eq_ignore_ascii_case(b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:75:5 @@ -363,8 +395,9 @@ LL | b.to_ascii_lowercase() == a.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | b.eq_ignore_ascii_case(&a); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - b.to_ascii_lowercase() == a.to_ascii_lowercase(); +LL + b.eq_ignore_ascii_case(&a); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:76:5 @@ -374,8 +407,9 @@ LL | b.to_ascii_lowercase() == "a"; | help: consider using `.eq_ignore_ascii_case()` instead | -LL | b.eq_ignore_ascii_case("a"); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - b.to_ascii_lowercase() == "a"; +LL + b.eq_ignore_ascii_case("a"); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:77:5 @@ -385,8 +419,9 @@ LL | "a" == a.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | "a".eq_ignore_ascii_case(&a); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - "a" == a.to_ascii_lowercase(); +LL + "a".eq_ignore_ascii_case(&a); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:80:5 @@ -396,8 +431,9 @@ LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_ascii_lowercase() == b.to_ascii_lowercase(); +LL + a.eq_ignore_ascii_case(b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:81:5 @@ -407,8 +443,9 @@ LL | a.to_ascii_lowercase() == "a"; | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.eq_ignore_ascii_case("a"); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_ascii_lowercase() == "a"; +LL + a.eq_ignore_ascii_case("a"); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:82:5 @@ -418,8 +455,9 @@ LL | "a" == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | "a".eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - "a" == b.to_ascii_lowercase(); +LL + "a".eq_ignore_ascii_case(b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:84:5 @@ -429,8 +467,9 @@ LL | b.to_ascii_lowercase() == a.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | b.eq_ignore_ascii_case(&a); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - b.to_ascii_lowercase() == a.to_ascii_lowercase(); +LL + b.eq_ignore_ascii_case(&a); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:85:5 @@ -440,8 +479,9 @@ LL | b.to_ascii_lowercase() == "a"; | help: consider using `.eq_ignore_ascii_case()` instead | -LL | b.eq_ignore_ascii_case("a"); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - b.to_ascii_lowercase() == "a"; +LL + b.eq_ignore_ascii_case("a"); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:86:5 @@ -451,8 +491,9 @@ LL | "a" == a.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | "a".eq_ignore_ascii_case(&a); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - "a" == a.to_ascii_lowercase(); +LL + "a".eq_ignore_ascii_case(&a); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:89:5 @@ -462,8 +503,9 @@ LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_ascii_lowercase() == b.to_ascii_lowercase(); +LL + a.eq_ignore_ascii_case(b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:92:5 @@ -473,8 +515,9 @@ LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.eq_ignore_ascii_case(&b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_ascii_lowercase() == b.to_ascii_lowercase(); +LL + a.eq_ignore_ascii_case(&b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:95:5 @@ -484,8 +527,9 @@ LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_ascii_lowercase() == b.to_ascii_lowercase(); +LL + a.eq_ignore_ascii_case(b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:96:5 @@ -495,8 +539,9 @@ LL | b.to_ascii_lowercase() == a.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | b.eq_ignore_ascii_case(&a); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - b.to_ascii_lowercase() == a.to_ascii_lowercase(); +LL + b.eq_ignore_ascii_case(&a); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:99:5 @@ -506,8 +551,9 @@ LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_ascii_lowercase() == b.to_ascii_lowercase(); +LL + a.eq_ignore_ascii_case(b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:102:5 @@ -517,8 +563,9 @@ LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_ascii_lowercase() == b.to_ascii_lowercase(); +LL + a.eq_ignore_ascii_case(b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:105:5 @@ -528,8 +575,9 @@ LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_ascii_lowercase() == b.to_ascii_lowercase(); +LL + a.eq_ignore_ascii_case(b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:106:5 @@ -539,8 +587,9 @@ LL | b.to_ascii_lowercase() == a.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | b.eq_ignore_ascii_case(a); - | ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - b.to_ascii_lowercase() == a.to_ascii_lowercase(); +LL + b.eq_ignore_ascii_case(a); + | error: aborting due to 49 previous errors diff --git a/src/tools/clippy/tests/ui/manual_is_ascii_check.stderr b/src/tools/clippy/tests/ui/manual_is_ascii_check.stderr index 92d93208006..7b3f0c938b0 100644 --- a/src/tools/clippy/tests/ui/manual_is_ascii_check.stderr +++ b/src/tools/clippy/tests/ui/manual_is_ascii_check.stderr @@ -153,8 +153,9 @@ LL | take_while(|c| ('A'..='Z').contains(&c)); | help: try | -LL | take_while(|c: char| c.is_ascii_uppercase()); - | ~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~ +LL - take_while(|c| ('A'..='Z').contains(&c)); +LL + take_while(|c: char| c.is_ascii_uppercase()); + | error: manual check for common ascii range --> tests/ui/manual_is_ascii_check.rs:82:20 @@ -164,8 +165,9 @@ LL | take_while(|c| (b'A'..=b'Z').contains(&c)); | help: try | -LL | take_while(|c: u8| c.is_ascii_uppercase()); - | ~~~~~ ~~~~~~~~~~~~~~~~~~~~~~ +LL - take_while(|c| (b'A'..=b'Z').contains(&c)); +LL + take_while(|c: u8| c.is_ascii_uppercase()); + | error: manual check for common ascii range --> tests/ui/manual_is_ascii_check.rs:83:26 @@ -181,8 +183,9 @@ LL | let digits: Vec<&char> = ['1', 'A'].iter().take_while(|c| ('0'..='9').c | help: try | -LL | let digits: Vec<&char> = ['1', 'A'].iter().take_while(|c: &&char| c.is_ascii_digit()).collect(); - | ~~~~~~~~~ ~~~~~~~~~~~~~~~~~~ +LL - let digits: Vec<&char> = ['1', 'A'].iter().take_while(|c| ('0'..='9').contains(c)).collect(); +LL + let digits: Vec<&char> = ['1', 'A'].iter().take_while(|c: &&char| c.is_ascii_digit()).collect(); + | error: manual check for common ascii range --> tests/ui/manual_is_ascii_check.rs:88:71 @@ -192,8 +195,9 @@ LL | let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c| ('0'. | help: try | -LL | let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c: &&mut char| c.is_ascii_digit()).collect(); - | ~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~ +LL - let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c| ('0'..='9').contains(c)).collect(); +LL + let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c: &&mut char| c.is_ascii_digit()).collect(); + | error: aborting due to 29 previous errors diff --git a/src/tools/clippy/tests/ui/map_all_any_identity.stderr b/src/tools/clippy/tests/ui/map_all_any_identity.stderr index 98fdcc2a939..39df2a3d961 100644 --- a/src/tools/clippy/tests/ui/map_all_any_identity.stderr +++ b/src/tools/clippy/tests/ui/map_all_any_identity.stderr @@ -8,8 +8,9 @@ LL | let _ = ["foo"].into_iter().map(|s| s == "foo").any(|a| a); = help: to override `-D warnings` add `#[allow(clippy::map_all_any_identity)]` help: use `.any(...)` instead | -LL | let _ = ["foo"].into_iter().any(|s| s == "foo"); - | ~~~~~~~~~~~~~~~~~~~ +LL - let _ = ["foo"].into_iter().map(|s| s == "foo").any(|a| a); +LL + let _ = ["foo"].into_iter().any(|s| s == "foo"); + | error: usage of `.map(...).all(identity)` --> tests/ui/map_all_any_identity.rs:6:33 @@ -19,8 +20,9 @@ LL | let _ = ["foo"].into_iter().map(|s| s == "foo").all(std::convert::ident | help: use `.all(...)` instead | -LL | let _ = ["foo"].into_iter().all(|s| s == "foo"); - | ~~~~~~~~~~~~~~~~~~~ +LL - let _ = ["foo"].into_iter().map(|s| s == "foo").all(std::convert::identity); +LL + let _ = ["foo"].into_iter().all(|s| s == "foo"); + | error: aborting due to 2 previous errors diff --git a/src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges.stderr b/src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges.stderr index 0b56c6d9521..840515f95df 100644 --- a/src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges.stderr +++ b/src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges.stderr @@ -68,8 +68,9 @@ LL | (0..10).map(|_| 3); | help: remove the explicit range and use `repeat_n` | -LL | std::iter::repeat_n(3, 10); - | ~~~~~~~~~~~~~~~~~~~ ~~~~~ +LL - (0..10).map(|_| 3); +LL + std::iter::repeat_n(3, 10); + | error: map of a closure that does not depend on its parameter over a range --> tests/ui/map_with_unused_argument_over_ranges.rs:31:5 @@ -216,8 +217,9 @@ LL | (0..10).map(|_| 3); | help: remove the explicit range and use `repeat` and `take` | -LL | std::iter::repeat(3).take(10); - | ~~~~~~~~~~~~~~~~~ ~ +++++++++ +LL - (0..10).map(|_| 3); +LL + std::iter::repeat(3).take(10); + | error: aborting due to 18 previous errors diff --git a/src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges_nostd.stderr b/src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges_nostd.stderr index d47f3d09175..975ded83560 100644 --- a/src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges_nostd.stderr +++ b/src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges_nostd.stderr @@ -8,8 +8,9 @@ LL | let _: Vec<_> = (0..10).map(|_| 3 + 1).collect(); = help: to override `-D warnings` add `#[allow(clippy::map_with_unused_argument_over_ranges)]` help: remove the explicit range and use `repeat_n` | -LL | let _: Vec<_> = core::iter::repeat_n(3 + 1, 10).collect(); - | ~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~ +LL - let _: Vec<_> = (0..10).map(|_| 3 + 1).collect(); +LL + let _: Vec<_> = core::iter::repeat_n(3 + 1, 10).collect(); + | error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/match_result_ok.stderr b/src/tools/clippy/tests/ui/match_result_ok.stderr index b5b91cbe553..18b23bd7845 100644 --- a/src/tools/clippy/tests/ui/match_result_ok.stderr +++ b/src/tools/clippy/tests/ui/match_result_ok.stderr @@ -8,8 +8,9 @@ LL | if let Some(y) = x.parse().ok() { y } else { 0 } = help: to override `-D warnings` add `#[allow(clippy::match_result_ok)]` help: consider matching on `Ok(y)` and removing the call to `ok` instead | -LL | if let Ok(y) = x.parse() { y } else { 0 } - | ~~~~~~~~~~~~~~~~~~~~~~~~ +LL - if let Some(y) = x.parse().ok() { y } else { 0 } +LL + if let Ok(y) = x.parse() { y } else { 0 } + | error: matching on `Some` with `ok()` is redundant --> tests/ui/match_result_ok.rs:23:9 @@ -19,8 +20,9 @@ LL | if let Some(y) = x . parse() . ok () { | help: consider matching on `Ok(y)` and removing the call to `ok` instead | -LL | if let Ok(y) = x . parse() { - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - if let Some(y) = x . parse() . ok () { +LL + if let Ok(y) = x . parse() { + | error: matching on `Some` with `ok()` is redundant --> tests/ui/match_result_ok.rs:49:5 @@ -30,8 +32,9 @@ LL | while let Some(a) = wat.next().ok() { | help: consider matching on `Ok(a)` and removing the call to `ok` instead | -LL | while let Ok(a) = wat.next() { - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - while let Some(a) = wat.next().ok() { +LL + while let Ok(a) = wat.next() { + | error: aborting due to 3 previous errors diff --git a/src/tools/clippy/tests/ui/match_str_case_mismatch.stderr b/src/tools/clippy/tests/ui/match_str_case_mismatch.stderr index 67e9ccaf6d2..5b14fd13a53 100644 --- a/src/tools/clippy/tests/ui/match_str_case_mismatch.stderr +++ b/src/tools/clippy/tests/ui/match_str_case_mismatch.stderr @@ -8,8 +8,9 @@ LL | "Bar" => {}, = help: to override `-D warnings` add `#[allow(clippy::match_str_case_mismatch)]` help: consider changing the case of this arm to respect `to_ascii_lowercase` | -LL | "bar" => {}, - | ~~~~~ +LL - "Bar" => {}, +LL + "bar" => {}, + | error: this `match` arm has a differing case than its expression --> tests/ui/match_str_case_mismatch.rs:122:9 @@ -19,8 +20,9 @@ LL | "~!@#$%^&*()-_=+Foo" => {}, | help: consider changing the case of this arm to respect `to_ascii_lowercase` (notice the capitalization difference) | -LL | "~!@#$%^&*()-_=+foo" => {}, - | ~~~~~~~~~~~~~~~~~~~~ +LL - "~!@#$%^&*()-_=+Foo" => {}, +LL + "~!@#$%^&*()-_=+foo" => {}, + | error: this `match` arm has a differing case than its expression --> tests/ui/match_str_case_mismatch.rs:134:9 @@ -30,8 +32,9 @@ LL | "Воды" => {}, | help: consider changing the case of this arm to respect `to_lowercase` | -LL | "воды" => {}, - | ~~~~~~ +LL - "Воды" => {}, +LL + "воды" => {}, + | error: this `match` arm has a differing case than its expression --> tests/ui/match_str_case_mismatch.rs:145:9 @@ -41,8 +44,9 @@ LL | "barDz" => {}, | help: consider changing the case of this arm to respect `to_lowercase` | -LL | "bardz" => {}, - | ~~~~~~ +LL - "barDz" => {}, +LL + "bardz" => {}, + | error: this `match` arm has a differing case than its expression --> tests/ui/match_str_case_mismatch.rs:155:9 @@ -52,8 +56,9 @@ LL | "bARʁ" => {}, | help: consider changing the case of this arm to respect `to_uppercase` | -LL | "BARʁ" => {}, - | ~~~~~~ +LL - "bARʁ" => {}, +LL + "BARʁ" => {}, + | error: this `match` arm has a differing case than its expression --> tests/ui/match_str_case_mismatch.rs:165:9 @@ -63,8 +68,9 @@ LL | "Bar" => {}, | help: consider changing the case of this arm to respect `to_ascii_lowercase` | -LL | "bar" => {}, - | ~~~~~ +LL - "Bar" => {}, +LL + "bar" => {}, + | error: this `match` arm has a differing case than its expression --> tests/ui/match_str_case_mismatch.rs:180:9 @@ -74,8 +80,9 @@ LL | "bAR" => {}, | help: consider changing the case of this arm to respect `to_ascii_uppercase` | -LL | "BAR" => {}, - | ~~~~~ +LL - "bAR" => {}, +LL + "BAR" => {}, + | error: aborting due to 7 previous errors diff --git a/src/tools/clippy/tests/ui/needless_borrow_pat.stderr b/src/tools/clippy/tests/ui/needless_borrow_pat.stderr index 2ad69449039..035376cabaf 100644 --- a/src/tools/clippy/tests/ui/needless_borrow_pat.stderr +++ b/src/tools/clippy/tests/ui/needless_borrow_pat.stderr @@ -15,8 +15,9 @@ LL | Some(ref x) => *x, | help: try | -LL | Some(x) => x, - | ~ ~ +LL - Some(ref x) => *x, +LL + Some(x) => x, + | error: this pattern creates a reference to a reference --> tests/ui/needless_borrow_pat.rs:74:14 @@ -71,8 +72,9 @@ LL | E::A(ref x) | E::B(ref x) => *x, | help: try | -LL | E::A(x) | E::B(x) => x, - | ~ ~ ~ +LL - E::A(ref x) | E::B(ref x) => *x, +LL + E::A(x) | E::B(x) => x, + | error: this pattern creates a reference to a reference --> tests/ui/needless_borrow_pat.rs:126:21 diff --git a/src/tools/clippy/tests/ui/needless_for_each_unfixable.stderr b/src/tools/clippy/tests/ui/needless_for_each_unfixable.stderr index 682140a1dfd..722016b1212 100644 --- a/src/tools/clippy/tests/ui/needless_for_each_unfixable.stderr +++ b/src/tools/clippy/tests/ui/needless_for_each_unfixable.stderr @@ -25,8 +25,9 @@ LL + } | help: ...and replace `return` with `continue` | -LL | continue; - | ~~~~~~~~ +LL - return; +LL + continue; + | error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/needless_pass_by_value.stderr b/src/tools/clippy/tests/ui/needless_pass_by_value.stderr index 2587d3f8c52..2c90da51252 100644 --- a/src/tools/clippy/tests/ui/needless_pass_by_value.stderr +++ b/src/tools/clippy/tests/ui/needless_pass_by_value.stderr @@ -63,12 +63,14 @@ LL | fn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) { | help: consider changing the type to | -LL | fn issue_2114(s: String, t: &str, u: Vec<i32>, v: Vec<i32>) { - | ~~~~ +LL - fn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) { +LL + fn issue_2114(s: String, t: &str, u: Vec<i32>, v: Vec<i32>) { + | help: change `t.clone()` to | -LL | let _ = t.to_string(); - | ~~~~~~~~~~~~~ +LL - let _ = t.clone(); +LL + let _ = t.to_string(); + | error: this argument is passed by value, but not consumed in the function body --> tests/ui/needless_pass_by_value.rs:91:40 @@ -84,12 +86,14 @@ LL | fn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) { | help: consider changing the type to | -LL | fn issue_2114(s: String, t: String, u: Vec<i32>, v: &[i32]) { - | ~~~~~~ +LL - fn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) { +LL + fn issue_2114(s: String, t: String, u: Vec<i32>, v: &[i32]) { + | help: change `v.clone()` to | -LL | let _ = v.to_owned(); - | ~~~~~~~~~~~~ +LL - let _ = v.clone(); +LL + let _ = v.to_owned(); + | error: this argument is passed by value, but not consumed in the function body --> tests/ui/needless_pass_by_value.rs:108:12 diff --git a/src/tools/clippy/tests/ui/needless_range_loop.stderr b/src/tools/clippy/tests/ui/needless_range_loop.stderr index 503d796e5e8..831b8511e43 100644 --- a/src/tools/clippy/tests/ui/needless_range_loop.stderr +++ b/src/tools/clippy/tests/ui/needless_range_loop.stderr @@ -8,8 +8,9 @@ LL | for i in 0..vec.len() { = help: to override `-D warnings` add `#[allow(clippy::needless_range_loop)]` help: consider using an iterator | -LL | for <item> in &vec { - | ~~~~~~ ~~~~ +LL - for i in 0..vec.len() { +LL + for <item> in &vec { + | error: the loop variable `i` is only used to index `vec` --> tests/ui/needless_range_loop.rs:27:14 @@ -19,8 +20,9 @@ LL | for i in 0..vec.len() { | help: consider using an iterator | -LL | for <item> in &vec { - | ~~~~~~ ~~~~ +LL - for i in 0..vec.len() { +LL + for <item> in &vec { + | error: the loop variable `j` is only used to index `STATIC` --> tests/ui/needless_range_loop.rs:33:14 @@ -30,8 +32,9 @@ LL | for j in 0..4 { | help: consider using an iterator | -LL | for <item> in &STATIC { - | ~~~~~~ ~~~~~~~ +LL - for j in 0..4 { +LL + for <item> in &STATIC { + | error: the loop variable `j` is only used to index `CONST` --> tests/ui/needless_range_loop.rs:38:14 @@ -41,8 +44,9 @@ LL | for j in 0..4 { | help: consider using an iterator | -LL | for <item> in &CONST { - | ~~~~~~ ~~~~~~ +LL - for j in 0..4 { +LL + for <item> in &CONST { + | error: the loop variable `i` is used to index `vec` --> tests/ui/needless_range_loop.rs:43:14 @@ -52,8 +56,9 @@ LL | for i in 0..vec.len() { | help: consider using an iterator and enumerate() | -LL | for (i, <item>) in vec.iter().enumerate() { - | ~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~ +LL - for i in 0..vec.len() { +LL + for (i, <item>) in vec.iter().enumerate() { + | error: the loop variable `i` is only used to index `vec2` --> tests/ui/needless_range_loop.rs:52:14 @@ -63,8 +68,9 @@ LL | for i in 0..vec.len() { | help: consider using an iterator | -LL | for <item> in vec2.iter().take(vec.len()) { - | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - for i in 0..vec.len() { +LL + for <item> in vec2.iter().take(vec.len()) { + | error: the loop variable `i` is only used to index `vec` --> tests/ui/needless_range_loop.rs:57:14 @@ -74,8 +80,9 @@ LL | for i in 5..vec.len() { | help: consider using an iterator | -LL | for <item> in vec.iter().skip(5) { - | ~~~~~~ ~~~~~~~~~~~~~~~~~~ +LL - for i in 5..vec.len() { +LL + for <item> in vec.iter().skip(5) { + | error: the loop variable `i` is only used to index `vec` --> tests/ui/needless_range_loop.rs:62:14 @@ -85,8 +92,9 @@ LL | for i in 0..MAX_LEN { | help: consider using an iterator | -LL | for <item> in vec.iter().take(MAX_LEN) { - | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~ +LL - for i in 0..MAX_LEN { +LL + for <item> in vec.iter().take(MAX_LEN) { + | error: the loop variable `i` is only used to index `vec` --> tests/ui/needless_range_loop.rs:67:14 @@ -96,8 +104,9 @@ LL | for i in 0..=MAX_LEN { | help: consider using an iterator | -LL | for <item> in vec.iter().take(MAX_LEN + 1) { - | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - for i in 0..=MAX_LEN { +LL + for <item> in vec.iter().take(MAX_LEN + 1) { + | error: the loop variable `i` is only used to index `vec` --> tests/ui/needless_range_loop.rs:72:14 @@ -107,8 +116,9 @@ LL | for i in 5..10 { | help: consider using an iterator | -LL | for <item> in vec.iter().take(10).skip(5) { - | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - for i in 5..10 { +LL + for <item> in vec.iter().take(10).skip(5) { + | error: the loop variable `i` is only used to index `vec` --> tests/ui/needless_range_loop.rs:77:14 @@ -118,8 +128,9 @@ LL | for i in 5..=10 { | help: consider using an iterator | -LL | for <item> in vec.iter().take(10 + 1).skip(5) { - | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - for i in 5..=10 { +LL + for <item> in vec.iter().take(10 + 1).skip(5) { + | error: the loop variable `i` is used to index `vec` --> tests/ui/needless_range_loop.rs:82:14 @@ -129,8 +140,9 @@ LL | for i in 5..vec.len() { | help: consider using an iterator and enumerate() | -LL | for (i, <item>) in vec.iter().enumerate().skip(5) { - | ~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - for i in 5..vec.len() { +LL + for (i, <item>) in vec.iter().enumerate().skip(5) { + | error: the loop variable `i` is used to index `vec` --> tests/ui/needless_range_loop.rs:87:14 @@ -140,8 +152,9 @@ LL | for i in 5..10 { | help: consider using an iterator and enumerate() | -LL | for (i, <item>) in vec.iter().enumerate().take(10).skip(5) { - | ~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - for i in 5..10 { +LL + for (i, <item>) in vec.iter().enumerate().take(10).skip(5) { + | error: the loop variable `i` is used to index `vec` --> tests/ui/needless_range_loop.rs:93:14 @@ -151,8 +164,9 @@ LL | for i in 0..vec.len() { | help: consider using an iterator and enumerate() | -LL | for (i, <item>) in vec.iter_mut().enumerate() { - | ~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - for i in 0..vec.len() { +LL + for (i, <item>) in vec.iter_mut().enumerate() { + | error: aborting due to 14 previous errors diff --git a/src/tools/clippy/tests/ui/needless_range_loop2.stderr b/src/tools/clippy/tests/ui/needless_range_loop2.stderr index 353f30b1b26..f37e1f2872d 100644 --- a/src/tools/clippy/tests/ui/needless_range_loop2.stderr +++ b/src/tools/clippy/tests/ui/needless_range_loop2.stderr @@ -8,8 +8,9 @@ LL | for i in 3..10 { = help: to override `-D warnings` add `#[allow(clippy::needless_range_loop)]` help: consider using an iterator | -LL | for <item> in ns.iter().take(10).skip(3) { - | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - for i in 3..10 { +LL + for <item> in ns.iter().take(10).skip(3) { + | error: the loop variable `i` is only used to index `ms` --> tests/ui/needless_range_loop2.rs:34:14 @@ -19,8 +20,9 @@ LL | for i in 0..ms.len() { | help: consider using an iterator | -LL | for <item> in &mut ms { - | ~~~~~~ ~~~~~~~ +LL - for i in 0..ms.len() { +LL + for <item> in &mut ms { + | error: the loop variable `i` is only used to index `ms` --> tests/ui/needless_range_loop2.rs:41:14 @@ -30,8 +32,9 @@ LL | for i in 0..ms.len() { | help: consider using an iterator | -LL | for <item> in &mut ms { - | ~~~~~~ ~~~~~~~ +LL - for i in 0..ms.len() { +LL + for <item> in &mut ms { + | error: the loop variable `i` is only used to index `vec` --> tests/ui/needless_range_loop2.rs:66:14 @@ -41,8 +44,9 @@ LL | for i in x..x + 4 { | help: consider using an iterator | -LL | for <item> in vec.iter_mut().skip(x).take(4) { - | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - for i in x..x + 4 { +LL + for <item> in vec.iter_mut().skip(x).take(4) { + | error: the loop variable `i` is only used to index `vec` --> tests/ui/needless_range_loop2.rs:74:14 @@ -52,8 +56,9 @@ LL | for i in x..=x + 4 { | help: consider using an iterator | -LL | for <item> in vec.iter_mut().skip(x).take(4 + 1) { - | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - for i in x..=x + 4 { +LL + for <item> in vec.iter_mut().skip(x).take(4 + 1) { + | error: the loop variable `i` is only used to index `arr` --> tests/ui/needless_range_loop2.rs:81:14 @@ -63,8 +68,9 @@ LL | for i in 0..3 { | help: consider using an iterator | -LL | for <item> in &arr { - | ~~~~~~ ~~~~ +LL - for i in 0..3 { +LL + for <item> in &arr { + | error: the loop variable `i` is only used to index `arr` --> tests/ui/needless_range_loop2.rs:86:14 @@ -74,8 +80,9 @@ LL | for i in 0..2 { | help: consider using an iterator | -LL | for <item> in arr.iter().take(2) { - | ~~~~~~ ~~~~~~~~~~~~~~~~~~ +LL - for i in 0..2 { +LL + for <item> in arr.iter().take(2) { + | error: the loop variable `i` is only used to index `arr` --> tests/ui/needless_range_loop2.rs:91:14 @@ -85,8 +92,9 @@ LL | for i in 1..3 { | help: consider using an iterator | -LL | for <item> in arr.iter().skip(1) { - | ~~~~~~ ~~~~~~~~~~~~~~~~~~ +LL - for i in 1..3 { +LL + for <item> in arr.iter().skip(1) { + | error: aborting due to 8 previous errors diff --git a/src/tools/clippy/tests/ui/needless_return.stderr b/src/tools/clippy/tests/ui/needless_return.stderr index d3c2a6badc0..8d8b5b9e713 100644 --- a/src/tools/clippy/tests/ui/needless_return.stderr +++ b/src/tools/clippy/tests/ui/needless_return.stderr @@ -80,8 +80,9 @@ LL | true => return false, | help: remove `return` | -LL | true => false, - | ~~~~~ +LL - true => return false, +LL + true => false, + | error: unneeded `return` statement --> tests/ui/needless_return.rs:58:13 @@ -115,8 +116,9 @@ LL | let _ = || return true; | help: remove `return` | -LL | let _ = || true; - | ~~~~ +LL - let _ = || return true; +LL + let _ = || true; + | error: unneeded `return` statement --> tests/ui/needless_return.rs:71:5 @@ -183,8 +185,9 @@ LL | _ => return, | help: replace `return` with a unit value | -LL | _ => (), - | ~~ +LL - _ => return, +LL + _ => (), + | error: unneeded `return` statement --> tests/ui/needless_return.rs:97:24 @@ -209,8 +212,9 @@ LL | _ => return, | help: replace `return` with a unit value | -LL | _ => (), - | ~~ +LL - _ => return, +LL + _ => (), + | error: unneeded `return` statement --> tests/ui/needless_return.rs:113:9 @@ -244,8 +248,9 @@ LL | bar.unwrap_or_else(|_| return) | help: replace `return` with an empty block | -LL | bar.unwrap_or_else(|_| {}) - | ~~ +LL - bar.unwrap_or_else(|_| return) +LL + bar.unwrap_or_else(|_| {}) + | error: unneeded `return` statement --> tests/ui/needless_return.rs:141:21 @@ -270,8 +275,9 @@ LL | let _ = || return; | help: replace `return` with an empty block | -LL | let _ = || {}; - | ~~ +LL - let _ = || return; +LL + let _ = || {}; + | error: unneeded `return` statement --> tests/ui/needless_return.rs:150:32 @@ -281,8 +287,9 @@ LL | res.unwrap_or_else(|_| return Foo) | help: remove `return` | -LL | res.unwrap_or_else(|_| Foo) - | ~~~ +LL - res.unwrap_or_else(|_| return Foo) +LL + res.unwrap_or_else(|_| Foo) + | error: unneeded `return` statement --> tests/ui/needless_return.rs:159:5 @@ -340,8 +347,9 @@ LL | true => return false, | help: remove `return` | -LL | true => false, - | ~~~~~ +LL - true => return false, +LL + true => false, + | error: unneeded `return` statement --> tests/ui/needless_return.rs:178:13 @@ -375,8 +383,9 @@ LL | let _ = || return true; | help: remove `return` | -LL | let _ = || true; - | ~~~~ +LL - let _ = || return true; +LL + let _ = || true; + | error: unneeded `return` statement --> tests/ui/needless_return.rs:191:5 @@ -443,8 +452,9 @@ LL | _ => return, | help: replace `return` with a unit value | -LL | _ => (), - | ~~ +LL - _ => return, +LL + _ => (), + | error: unneeded `return` statement --> tests/ui/needless_return.rs:222:9 diff --git a/src/tools/clippy/tests/ui/never_loop.stderr b/src/tools/clippy/tests/ui/never_loop.stderr index dab3488af10..203e3325822 100644 --- a/src/tools/clippy/tests/ui/never_loop.stderr +++ b/src/tools/clippy/tests/ui/never_loop.stderr @@ -77,8 +77,9 @@ LL | | } | help: if you need the first element of the iterator, try writing | -LL | if let Some(x) = (0..10).next() { - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - for x in 0..10 { +LL + if let Some(x) = (0..10).next() { + | error: this loop never actually loops --> tests/ui/never_loop.rs:167:5 @@ -145,8 +146,9 @@ LL | | } | help: if you need the first element of the iterator, try writing | -LL | if let Some(_) = (0..20).next() { - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - for _ in 0..20 { +LL + if let Some(_) = (0..20).next() { + | error: this loop never actually loops --> tests/ui/never_loop.rs:378:13 diff --git a/src/tools/clippy/tests/ui/non_canonical_partial_ord_impl.stderr b/src/tools/clippy/tests/ui/non_canonical_partial_ord_impl.stderr index a15379c5b1a..9f0c2ec4301 100644 --- a/src/tools/clippy/tests/ui/non_canonical_partial_ord_impl.stderr +++ b/src/tools/clippy/tests/ui/non_canonical_partial_ord_impl.stderr @@ -25,8 +25,9 @@ LL | | } | help: change this to | -LL | fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(other)) } - | ~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - fn partial_cmp(&self, _: &Self) -> Option<Ordering> { +LL + fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(other)) } + | error: aborting due to 2 previous errors diff --git a/src/tools/clippy/tests/ui/non_std_lazy_static/non_std_lazy_static_fixable.stderr b/src/tools/clippy/tests/ui/non_std_lazy_static/non_std_lazy_static_fixable.stderr index f956f4b8d52..333052ae1c1 100644 --- a/src/tools/clippy/tests/ui/non_std_lazy_static/non_std_lazy_static_fixable.stderr +++ b/src/tools/clippy/tests/ui/non_std_lazy_static/non_std_lazy_static_fixable.stderr @@ -8,8 +8,9 @@ LL | static LAZY_FOO: Lazy<String> = Lazy::new(|| "foo".to_uppercase()); = help: to override `-D warnings` add `#[allow(clippy::non_std_lazy_statics)]` help: use `std::sync::LazyLock` instead | -LL | static LAZY_FOO: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| "foo".to_uppercase()); - | ~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~ +LL - static LAZY_FOO: Lazy<String> = Lazy::new(|| "foo".to_uppercase()); +LL + static LAZY_FOO: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| "foo".to_uppercase()); + | error: this type has been superceded by `LazyLock` in the standard library --> tests/ui/non_std_lazy_static/non_std_lazy_static_fixable.rs:13:18 @@ -19,8 +20,9 @@ LL | static LAZY_BAR: Lazy<String> = Lazy::new(|| { | help: use `std::sync::LazyLock` instead | -LL | static LAZY_BAR: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| { - | ~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~ +LL - static LAZY_BAR: Lazy<String> = Lazy::new(|| { +LL + static LAZY_BAR: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| { + | error: this type has been superceded by `LazyLock` in the standard library --> tests/ui/non_std_lazy_static/non_std_lazy_static_fixable.rs:18:18 @@ -30,8 +32,9 @@ LL | static LAZY_BAZ: Lazy<String> = { Lazy::new(|| "baz".to_uppercase()) }; | help: use `std::sync::LazyLock` instead | -LL | static LAZY_BAZ: std::sync::LazyLock<String> = { std::sync::LazyLock::new(|| "baz".to_uppercase()) }; - | ~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~ +LL - static LAZY_BAZ: Lazy<String> = { Lazy::new(|| "baz".to_uppercase()) }; +LL + static LAZY_BAZ: std::sync::LazyLock<String> = { std::sync::LazyLock::new(|| "baz".to_uppercase()) }; + | error: this type has been superceded by `LazyLock` in the standard library --> tests/ui/non_std_lazy_static/non_std_lazy_static_fixable.rs:20:18 diff --git a/src/tools/clippy/tests/ui/non_std_lazy_static/non_std_lazy_static_unfixable.stderr b/src/tools/clippy/tests/ui/non_std_lazy_static/non_std_lazy_static_unfixable.stderr index 66dc435f982..216190ae4ca 100644 --- a/src/tools/clippy/tests/ui/non_std_lazy_static/non_std_lazy_static_unfixable.stderr +++ b/src/tools/clippy/tests/ui/non_std_lazy_static/non_std_lazy_static_unfixable.stderr @@ -37,8 +37,9 @@ LL | static LAZY_FOO: Lazy<String> = Lazy::new(|| "foo".to_uppercase()); | help: use `std::sync::LazyLock` instead | -LL | static LAZY_FOO: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| "foo".to_uppercase()); - | ~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~ +LL - static LAZY_FOO: Lazy<String> = Lazy::new(|| "foo".to_uppercase()); +LL + static LAZY_FOO: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| "foo".to_uppercase()); + | error: this type has been superceded by `LazyLock` in the standard library --> tests/ui/non_std_lazy_static/non_std_lazy_static_unfixable.rs:13:26 @@ -48,8 +49,9 @@ LL | static mut LAZY_BAR: Lazy<String> = Lazy::new(|| "bar".to_uppercase()); | help: use `std::sync::LazyLock` instead | -LL | static mut LAZY_BAR: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| "bar".to_uppercase()); - | ~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~ +LL - static mut LAZY_BAR: Lazy<String> = Lazy::new(|| "bar".to_uppercase()); +LL + static mut LAZY_BAR: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| "bar".to_uppercase()); + | error: this type has been superceded by `LazyLock` in the standard library --> tests/ui/non_std_lazy_static/non_std_lazy_static_unfixable.rs:15:26 @@ -59,8 +61,9 @@ LL | static mut LAZY_BAZ: Lazy<String> = Lazy::new(|| "baz".to_uppercase()); | help: use `std::sync::LazyLock` instead | -LL | static mut LAZY_BAZ: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| "baz".to_uppercase()); - | ~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~ +LL - static mut LAZY_BAZ: Lazy<String> = Lazy::new(|| "baz".to_uppercase()); +LL + static mut LAZY_BAZ: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| "baz".to_uppercase()); + | error: aborting due to 6 previous errors diff --git a/src/tools/clippy/tests/ui/nonminimal_bool.stderr b/src/tools/clippy/tests/ui/nonminimal_bool.stderr index 578f918f013..56d6eb10ac0 100644 --- a/src/tools/clippy/tests/ui/nonminimal_bool.stderr +++ b/src/tools/clippy/tests/ui/nonminimal_bool.stderr @@ -51,10 +51,12 @@ LL | let _ = a == b && c == 5 && a == b; | help: try | -LL | let _ = !(a != b || c != 5); - | ~~~~~~~~~~~~~~~~~~~ -LL | let _ = a == b && c == 5; - | ~~~~~~~~~~~~~~~~ +LL - let _ = a == b && c == 5 && a == b; +LL + let _ = !(a != b || c != 5); + | +LL - let _ = a == b && c == 5 && a == b; +LL + let _ = a == b && c == 5; + | error: this boolean expression can be simplified --> tests/ui/nonminimal_bool.rs:44:13 @@ -64,10 +66,12 @@ LL | let _ = a == b || c == 5 || a == b; | help: try | -LL | let _ = !(a != b && c != 5); - | ~~~~~~~~~~~~~~~~~~~ -LL | let _ = a == b || c == 5; - | ~~~~~~~~~~~~~~~~ +LL - let _ = a == b || c == 5 || a == b; +LL + let _ = !(a != b && c != 5); + | +LL - let _ = a == b || c == 5 || a == b; +LL + let _ = a == b || c == 5; + | error: this boolean expression can be simplified --> tests/ui/nonminimal_bool.rs:46:13 @@ -77,10 +81,12 @@ LL | let _ = a == b && c == 5 && b == a; | help: try | -LL | let _ = !(a != b || c != 5); - | ~~~~~~~~~~~~~~~~~~~ -LL | let _ = a == b && c == 5; - | ~~~~~~~~~~~~~~~~ +LL - let _ = a == b && c == 5 && b == a; +LL + let _ = !(a != b || c != 5); + | +LL - let _ = a == b && c == 5 && b == a; +LL + let _ = a == b && c == 5; + | error: this boolean expression can be simplified --> tests/ui/nonminimal_bool.rs:48:13 @@ -90,10 +96,12 @@ LL | let _ = a != b || !(a != b || c == d); | help: try | -LL | let _ = !(a == b && c == d); - | ~~~~~~~~~~~~~~~~~~~ -LL | let _ = a != b || c != d; - | ~~~~~~~~~~~~~~~~ +LL - let _ = a != b || !(a != b || c == d); +LL + let _ = !(a == b && c == d); + | +LL - let _ = a != b || !(a != b || c == d); +LL + let _ = a != b || c != d; + | error: this boolean expression can be simplified --> tests/ui/nonminimal_bool.rs:50:13 @@ -103,10 +111,12 @@ LL | let _ = a != b && !(a != b && c == d); | help: try | -LL | let _ = !(a == b || c == d); - | ~~~~~~~~~~~~~~~~~~~ -LL | let _ = a != b && c != d; - | ~~~~~~~~~~~~~~~~ +LL - let _ = a != b && !(a != b && c == d); +LL + let _ = !(a == b || c == d); + | +LL - let _ = a != b && !(a != b && c == d); +LL + let _ = a != b && c != d; + | error: this boolean expression can be simplified --> tests/ui/nonminimal_bool.rs:81:8 diff --git a/src/tools/clippy/tests/ui/octal_escapes.stderr b/src/tools/clippy/tests/ui/octal_escapes.stderr index 9343ba64a30..c8a89ac8bea 100644 --- a/src/tools/clippy/tests/ui/octal_escapes.stderr +++ b/src/tools/clippy/tests/ui/octal_escapes.stderr @@ -9,12 +9,14 @@ LL | let _bad1 = "\033[0m"; = help: to override `-D warnings` add `#[allow(clippy::octal_escapes)]` help: if an octal escape is intended, use a hex escape instead | -LL | let _bad1 = "\x1b[0m"; - | ~~~~ +LL - let _bad1 = "\033[0m"; +LL + let _bad1 = "\x1b[0m"; + | help: if a null escape is intended, disambiguate using | -LL | let _bad1 = "\x0033[0m"; - | ~~~~~~ +LL - let _bad1 = "\033[0m"; +LL + let _bad1 = "\x0033[0m"; + | error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:6:19 @@ -24,12 +26,14 @@ LL | let _bad2 = b"\033[0m"; | help: if an octal escape is intended, use a hex escape instead | -LL | let _bad2 = b"\x1b[0m"; - | ~~~~ +LL - let _bad2 = b"\033[0m"; +LL + let _bad2 = b"\x1b[0m"; + | help: if a null escape is intended, disambiguate using | -LL | let _bad2 = b"\x0033[0m"; - | ~~~~~~ +LL - let _bad2 = b"\033[0m"; +LL + let _bad2 = b"\x0033[0m"; + | error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:7:20 @@ -39,12 +43,14 @@ LL | let _bad3 = "\\\033[0m"; | help: if an octal escape is intended, use a hex escape instead | -LL | let _bad3 = "\\\x1b[0m"; - | ~~~~ +LL - let _bad3 = "\\\033[0m"; +LL + let _bad3 = "\\\x1b[0m"; + | help: if a null escape is intended, disambiguate using | -LL | let _bad3 = "\\\x0033[0m"; - | ~~~~~~ +LL - let _bad3 = "\\\033[0m"; +LL + let _bad3 = "\\\x0033[0m"; + | error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:9:18 @@ -54,12 +60,14 @@ LL | let _bad4 = "\01234567"; | help: if an octal escape is intended, use a hex escape instead | -LL | let _bad4 = "\x0a34567"; - | ~~~~ +LL - let _bad4 = "\01234567"; +LL + let _bad4 = "\x0a34567"; + | help: if a null escape is intended, disambiguate using | -LL | let _bad4 = "\x001234567"; - | ~~~~~~ +LL - let _bad4 = "\01234567"; +LL + let _bad4 = "\x001234567"; + | error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:10:20 @@ -69,12 +77,14 @@ LL | let _bad5 = "\0\03"; | help: if an octal escape is intended, use a hex escape instead | -LL | let _bad5 = "\0\x03"; - | ~~~~ +LL - let _bad5 = "\0\03"; +LL + let _bad5 = "\0\x03"; + | help: if a null escape is intended, disambiguate using | -LL | let _bad5 = "\0\x0003"; - | ~~~~~~ +LL - let _bad5 = "\0\03"; +LL + let _bad5 = "\0\x0003"; + | error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:11:23 @@ -84,12 +94,14 @@ LL | let _bad6 = "Text-\055\077-MoreText"; | help: if an octal escape is intended, use a hex escape instead | -LL | let _bad6 = "Text-\x2d\077-MoreText"; - | ~~~~ +LL - let _bad6 = "Text-\055\077-MoreText"; +LL + let _bad6 = "Text-\x2d\077-MoreText"; + | help: if a null escape is intended, disambiguate using | -LL | let _bad6 = "Text-\x0055\077-MoreText"; - | ~~~~~~ +LL - let _bad6 = "Text-\055\077-MoreText"; +LL + let _bad6 = "Text-\x0055\077-MoreText"; + | error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:11:27 @@ -99,12 +111,14 @@ LL | let _bad6 = "Text-\055\077-MoreText"; | help: if an octal escape is intended, use a hex escape instead | -LL | let _bad6 = "Text-\055\x3f-MoreText"; - | ~~~~ +LL - let _bad6 = "Text-\055\077-MoreText"; +LL + let _bad6 = "Text-\055\x3f-MoreText"; + | help: if a null escape is intended, disambiguate using | -LL | let _bad6 = "Text-\055\x0077-MoreText"; - | ~~~~~~ +LL - let _bad6 = "Text-\055\077-MoreText"; +LL + let _bad6 = "Text-\055\x0077-MoreText"; + | error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:14:31 @@ -114,12 +128,14 @@ LL | let _bad7 = "EvenMoreText-\01\02-ShortEscapes"; | help: if an octal escape is intended, use a hex escape instead | -LL | let _bad7 = "EvenMoreText-\x01\02-ShortEscapes"; - | ~~~~ +LL - let _bad7 = "EvenMoreText-\01\02-ShortEscapes"; +LL + let _bad7 = "EvenMoreText-\x01\02-ShortEscapes"; + | help: if a null escape is intended, disambiguate using | -LL | let _bad7 = "EvenMoreText-\x0001\02-ShortEscapes"; - | ~~~~~~ +LL - let _bad7 = "EvenMoreText-\01\02-ShortEscapes"; +LL + let _bad7 = "EvenMoreText-\x0001\02-ShortEscapes"; + | error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:14:34 @@ -129,12 +145,14 @@ LL | let _bad7 = "EvenMoreText-\01\02-ShortEscapes"; | help: if an octal escape is intended, use a hex escape instead | -LL | let _bad7 = "EvenMoreText-\01\x02-ShortEscapes"; - | ~~~~ +LL - let _bad7 = "EvenMoreText-\01\02-ShortEscapes"; +LL + let _bad7 = "EvenMoreText-\01\x02-ShortEscapes"; + | help: if a null escape is intended, disambiguate using | -LL | let _bad7 = "EvenMoreText-\01\x0002-ShortEscapes"; - | ~~~~~~ +LL - let _bad7 = "EvenMoreText-\01\02-ShortEscapes"; +LL + let _bad7 = "EvenMoreText-\01\x0002-ShortEscapes"; + | error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:17:19 @@ -144,12 +162,14 @@ LL | let _bad8 = "锈\01锈"; | help: if an octal escape is intended, use a hex escape instead | -LL | let _bad8 = "锈\x01锈"; - | ~~~~ +LL - let _bad8 = "锈\01锈"; +LL + let _bad8 = "锈\x01锈"; + | help: if a null escape is intended, disambiguate using | -LL | let _bad8 = "锈\x0001锈"; - | ~~~~~~ +LL - let _bad8 = "锈\01锈"; +LL + let _bad8 = "锈\x0001锈"; + | error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:18:19 @@ -159,12 +179,14 @@ LL | let _bad9 = "锈\011锈"; | help: if an octal escape is intended, use a hex escape instead | -LL | let _bad9 = "锈\x09锈"; - | ~~~~ +LL - let _bad9 = "锈\011锈"; +LL + let _bad9 = "锈\x09锈"; + | help: if a null escape is intended, disambiguate using | -LL | let _bad9 = "锈\x0011锈"; - | ~~~~~~ +LL - let _bad9 = "锈\011锈"; +LL + let _bad9 = "锈\x0011锈"; + | error: aborting due to 11 previous errors diff --git a/src/tools/clippy/tests/ui/op_ref.stderr b/src/tools/clippy/tests/ui/op_ref.stderr index c5b68730a8f..ad002437c0c 100644 --- a/src/tools/clippy/tests/ui/op_ref.stderr +++ b/src/tools/clippy/tests/ui/op_ref.stderr @@ -8,8 +8,9 @@ LL | let foo = &5 - &6; = help: to override `-D warnings` add `#[allow(clippy::op_ref)]` help: use the values directly | -LL | let foo = 5 - 6; - | ~ ~ +LL - let foo = &5 - &6; +LL + let foo = 5 - 6; + | error: taken reference of right operand --> tests/ui/op_ref.rs:58:13 diff --git a/src/tools/clippy/tests/ui/option_as_ref_cloned.stderr b/src/tools/clippy/tests/ui/option_as_ref_cloned.stderr index 5892f2bdec5..0eda42b91b9 100644 --- a/src/tools/clippy/tests/ui/option_as_ref_cloned.stderr +++ b/src/tools/clippy/tests/ui/option_as_ref_cloned.stderr @@ -8,8 +8,9 @@ LL | let _: Option<String> = x.as_ref().cloned(); = help: to override `-D warnings` add `#[allow(clippy::option_as_ref_cloned)]` help: this can be written more concisely by cloning the `Option<_>` directly | -LL | let _: Option<String> = x.clone(); - | ~~~~~ +LL - let _: Option<String> = x.as_ref().cloned(); +LL + let _: Option<String> = x.clone(); + | error: cloning an `Option<_>` using `.as_mut().cloned()` --> tests/ui/option_as_ref_cloned.rs:8:31 @@ -19,8 +20,9 @@ LL | let _: Option<String> = x.as_mut().cloned(); | help: this can be written more concisely by cloning the `Option<_>` directly | -LL | let _: Option<String> = x.clone(); - | ~~~~~ +LL - let _: Option<String> = x.as_mut().cloned(); +LL + let _: Option<String> = x.clone(); + | error: cloning an `Option<_>` using `.as_ref().cloned()` --> tests/ui/option_as_ref_cloned.rs:11:32 @@ -30,8 +32,9 @@ LL | let _: Option<&String> = y.as_ref().cloned(); | help: this can be written more concisely by cloning the `Option<_>` directly | -LL | let _: Option<&String> = y.clone(); - | ~~~~~ +LL - let _: Option<&String> = y.as_ref().cloned(); +LL + let _: Option<&String> = y.clone(); + | error: aborting due to 3 previous errors diff --git a/src/tools/clippy/tests/ui/redundant_guards.stderr b/src/tools/clippy/tests/ui/redundant_guards.stderr index 7512546450b..a10cd5c2f48 100644 --- a/src/tools/clippy/tests/ui/redundant_guards.stderr +++ b/src/tools/clippy/tests/ui/redundant_guards.stderr @@ -44,8 +44,9 @@ LL | Some(x) if matches!(x, Some(1) if true) => .., | help: try | -LL | Some(Some(1)) if true => .., - | ~~~~~~~ ~~~~~~~ +LL - Some(x) if matches!(x, Some(1) if true) => .., +LL + Some(Some(1)) if true => .., + | error: redundant guard --> tests/ui/redundant_guards.rs:50:20 diff --git a/src/tools/clippy/tests/ui/ref_binding_to_reference.stderr b/src/tools/clippy/tests/ui/ref_binding_to_reference.stderr index 25ab9822382..233416351a0 100644 --- a/src/tools/clippy/tests/ui/ref_binding_to_reference.stderr +++ b/src/tools/clippy/tests/ui/ref_binding_to_reference.stderr @@ -8,8 +8,9 @@ LL | Some(ref x) => x, = help: to override `-D warnings` add `#[allow(clippy::ref_binding_to_reference)]` help: try | -LL | Some(x) => &x, - | ~ ~~ +LL - Some(ref x) => x, +LL + Some(x) => &x, + | error: this pattern creates a reference to a reference --> tests/ui/ref_binding_to_reference.rs:38:14 @@ -34,8 +35,9 @@ LL | Some(ref x) => m2!(x), | help: try | -LL | Some(x) => m2!(&x), - | ~ ~~ +LL - Some(ref x) => m2!(x), +LL + Some(x) => m2!(&x), + | error: this pattern creates a reference to a reference --> tests/ui/ref_binding_to_reference.rs:55:15 diff --git a/src/tools/clippy/tests/ui/ref_option/ref_option.all.stderr b/src/tools/clippy/tests/ui/ref_option/ref_option.all.stderr index b4c69ac6296..fd30628bdd8 100644 --- a/src/tools/clippy/tests/ui/ref_option/ref_option.all.stderr +++ b/src/tools/clippy/tests/ui/ref_option/ref_option.all.stderr @@ -55,8 +55,9 @@ LL | fn mult_string(a: &Option<String>, b: &Option<Vec<u8>>) {} | help: change this to | -LL | fn mult_string(a: Option<&String>, b: Option<&Vec<u8>>) {} - | ~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~ +LL - fn mult_string(a: &Option<String>, b: &Option<Vec<u8>>) {} +LL + fn mult_string(a: Option<&String>, b: Option<&Vec<u8>>) {} + | error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>` --> tests/ui/ref_option/ref_option.rs:18:1 @@ -85,8 +86,9 @@ LL | pub fn pub_mult_string(a: &Option<String>, b: &Option<Vec<u8>>) {} | help: change this to | -LL | pub fn pub_mult_string(a: Option<&String>, b: Option<&Vec<u8>>) {} - | ~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~ +LL - pub fn pub_mult_string(a: &Option<String>, b: &Option<Vec<u8>>) {} +LL + pub fn pub_mult_string(a: Option<&String>, b: Option<&Vec<u8>>) {} + | error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>` --> tests/ui/ref_option/ref_option.rs:26:5 diff --git a/src/tools/clippy/tests/ui/ref_option/ref_option.private.stderr b/src/tools/clippy/tests/ui/ref_option/ref_option.private.stderr index 17c90536da3..d3428f1891f 100644 --- a/src/tools/clippy/tests/ui/ref_option/ref_option.private.stderr +++ b/src/tools/clippy/tests/ui/ref_option/ref_option.private.stderr @@ -55,8 +55,9 @@ LL | fn mult_string(a: &Option<String>, b: &Option<Vec<u8>>) {} | help: change this to | -LL | fn mult_string(a: Option<&String>, b: Option<&Vec<u8>>) {} - | ~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~ +LL - fn mult_string(a: &Option<String>, b: &Option<Vec<u8>>) {} +LL + fn mult_string(a: Option<&String>, b: Option<&Vec<u8>>) {} + | error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>` --> tests/ui/ref_option/ref_option.rs:18:1 diff --git a/src/tools/clippy/tests/ui/repeat_vec_with_capacity.stderr b/src/tools/clippy/tests/ui/repeat_vec_with_capacity.stderr index 43027c9cb89..05513a8859a 100644 --- a/src/tools/clippy/tests/ui/repeat_vec_with_capacity.stderr +++ b/src/tools/clippy/tests/ui/repeat_vec_with_capacity.stderr @@ -9,8 +9,9 @@ LL | vec![Vec::<()>::with_capacity(42); 123]; = help: to override `-D warnings` add `#[allow(clippy::repeat_vec_with_capacity)]` help: if you intended to initialize multiple `Vec`s with an initial capacity, try | -LL | (0..123).map(|_| Vec::<()>::with_capacity(42)).collect::<Vec<_>>(); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - vec![Vec::<()>::with_capacity(42); 123]; +LL + (0..123).map(|_| Vec::<()>::with_capacity(42)).collect::<Vec<_>>(); + | error: repeating `Vec::with_capacity` using `vec![x; n]`, which does not retain capacity --> tests/ui/repeat_vec_with_capacity.rs:12:9 @@ -21,8 +22,9 @@ LL | vec![Vec::<()>::with_capacity(42); n]; = note: only the last `Vec` will have the capacity help: if you intended to initialize multiple `Vec`s with an initial capacity, try | -LL | (0..n).map(|_| Vec::<()>::with_capacity(42)).collect::<Vec<_>>(); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - vec![Vec::<()>::with_capacity(42); n]; +LL + (0..n).map(|_| Vec::<()>::with_capacity(42)).collect::<Vec<_>>(); + | error: repeating `Vec::with_capacity` using `iter::repeat`, which does not retain capacity --> tests/ui/repeat_vec_with_capacity.rs:27:9 @@ -33,8 +35,9 @@ LL | std::iter::repeat(Vec::<()>::with_capacity(42)); = note: none of the yielded `Vec`s will have the requested capacity help: if you intended to create an iterator that yields `Vec`s with an initial capacity, try | -LL | std::iter::repeat_with(|| Vec::<()>::with_capacity(42)); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - std::iter::repeat(Vec::<()>::with_capacity(42)); +LL + std::iter::repeat_with(|| Vec::<()>::with_capacity(42)); + | error: aborting due to 3 previous errors diff --git a/src/tools/clippy/tests/ui/repeat_vec_with_capacity_nostd.stderr b/src/tools/clippy/tests/ui/repeat_vec_with_capacity_nostd.stderr index 39364d09b96..092167485ce 100644 --- a/src/tools/clippy/tests/ui/repeat_vec_with_capacity_nostd.stderr +++ b/src/tools/clippy/tests/ui/repeat_vec_with_capacity_nostd.stderr @@ -9,8 +9,9 @@ LL | let _: Vec<Vec<u8>> = iter::repeat(Vec::with_capacity(42)).take(123).co = help: to override `-D warnings` add `#[allow(clippy::repeat_vec_with_capacity)]` help: if you intended to create an iterator that yields `Vec`s with an initial capacity, try | -LL | let _: Vec<Vec<u8>> = core::iter::repeat_with(|| Vec::with_capacity(42)).take(123).collect(); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _: Vec<Vec<u8>> = iter::repeat(Vec::with_capacity(42)).take(123).collect(); +LL + let _: Vec<Vec<u8>> = core::iter::repeat_with(|| Vec::with_capacity(42)).take(123).collect(); + | error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/reversed_empty_ranges_fixable.stderr b/src/tools/clippy/tests/ui/reversed_empty_ranges_fixable.stderr index 3747eb9deeb..24cb959c96a 100644 --- a/src/tools/clippy/tests/ui/reversed_empty_ranges_fixable.stderr +++ b/src/tools/clippy/tests/ui/reversed_empty_ranges_fixable.stderr @@ -8,8 +8,9 @@ LL | (42..=21).for_each(|x| println!("{}", x)); = help: to override `-D warnings` add `#[allow(clippy::reversed_empty_ranges)]` help: consider using the following if you are attempting to iterate over this range in reverse | -LL | (21..=42).rev().for_each(|x| println!("{}", x)); - | ~~~~~~~~~~~~~~~ +LL - (42..=21).for_each(|x| println!("{}", x)); +LL + (21..=42).rev().for_each(|x| println!("{}", x)); + | error: this range is empty so it will yield no values --> tests/ui/reversed_empty_ranges_fixable.rs:10:13 @@ -19,8 +20,9 @@ LL | let _ = (ANSWER..21).filter(|x| x % 2 == 0).take(10).collect::<Vec<_>>( | help: consider using the following if you are attempting to iterate over this range in reverse | -LL | let _ = (21..ANSWER).rev().filter(|x| x % 2 == 0).take(10).collect::<Vec<_>>(); - | ~~~~~~~~~~~~~~~~~~ +LL - let _ = (ANSWER..21).filter(|x| x % 2 == 0).take(10).collect::<Vec<_>>(); +LL + let _ = (21..ANSWER).rev().filter(|x| x % 2 == 0).take(10).collect::<Vec<_>>(); + | error: this range is empty so it will yield no values --> tests/ui/reversed_empty_ranges_fixable.rs:12:14 @@ -30,8 +32,9 @@ LL | for _ in -21..=-42 {} | help: consider using the following if you are attempting to iterate over this range in reverse | -LL | for _ in (-42..=-21).rev() {} - | ~~~~~~~~~~~~~~~~~ +LL - for _ in -21..=-42 {} +LL + for _ in (-42..=-21).rev() {} + | error: this range is empty so it will yield no values --> tests/ui/reversed_empty_ranges_fixable.rs:13:14 @@ -41,8 +44,9 @@ LL | for _ in 42u32..21u32 {} | help: consider using the following if you are attempting to iterate over this range in reverse | -LL | for _ in (21u32..42u32).rev() {} - | ~~~~~~~~~~~~~~~~~~~~ +LL - for _ in 42u32..21u32 {} +LL + for _ in (21u32..42u32).rev() {} + | error: aborting due to 4 previous errors diff --git a/src/tools/clippy/tests/ui/reversed_empty_ranges_loops_fixable.stderr b/src/tools/clippy/tests/ui/reversed_empty_ranges_loops_fixable.stderr index d5df34c42f4..3e9ccb653fe 100644 --- a/src/tools/clippy/tests/ui/reversed_empty_ranges_loops_fixable.stderr +++ b/src/tools/clippy/tests/ui/reversed_empty_ranges_loops_fixable.stderr @@ -8,8 +8,9 @@ LL | for i in 10..0 { = help: to override `-D warnings` add `#[allow(clippy::reversed_empty_ranges)]` help: consider using the following if you are attempting to iterate over this range in reverse | -LL | for i in (0..10).rev() { - | ~~~~~~~~~~~~~ +LL - for i in 10..0 { +LL + for i in (0..10).rev() { + | error: this range is empty so it will yield no values --> tests/ui/reversed_empty_ranges_loops_fixable.rs:11:14 @@ -19,8 +20,9 @@ LL | for i in 10..=0 { | help: consider using the following if you are attempting to iterate over this range in reverse | -LL | for i in (0..=10).rev() { - | ~~~~~~~~~~~~~~ +LL - for i in 10..=0 { +LL + for i in (0..=10).rev() { + | error: this range is empty so it will yield no values --> tests/ui/reversed_empty_ranges_loops_fixable.rs:15:14 @@ -30,8 +32,9 @@ LL | for i in MAX_LEN..0 { | help: consider using the following if you are attempting to iterate over this range in reverse | -LL | for i in (0..MAX_LEN).rev() { - | ~~~~~~~~~~~~~~~~~~ +LL - for i in MAX_LEN..0 { +LL + for i in (0..MAX_LEN).rev() { + | error: this range is empty so it will yield no values --> tests/ui/reversed_empty_ranges_loops_fixable.rs:34:14 @@ -41,8 +44,9 @@ LL | for i in (10..0).map(|x| x * 2) { | help: consider using the following if you are attempting to iterate over this range in reverse | -LL | for i in (0..10).rev().map(|x| x * 2) { - | ~~~~~~~~~~~~~ +LL - for i in (10..0).map(|x| x * 2) { +LL + for i in (0..10).rev().map(|x| x * 2) { + | error: this range is empty so it will yield no values --> tests/ui/reversed_empty_ranges_loops_fixable.rs:39:14 @@ -52,8 +56,9 @@ LL | for i in 10..5 + 4 { | help: consider using the following if you are attempting to iterate over this range in reverse | -LL | for i in (5 + 4..10).rev() { - | ~~~~~~~~~~~~~~~~~ +LL - for i in 10..5 + 4 { +LL + for i in (5 + 4..10).rev() { + | error: this range is empty so it will yield no values --> tests/ui/reversed_empty_ranges_loops_fixable.rs:43:14 @@ -63,8 +68,9 @@ LL | for i in (5 + 2)..(3 - 1) { | help: consider using the following if you are attempting to iterate over this range in reverse | -LL | for i in ((3 - 1)..(5 + 2)).rev() { - | ~~~~~~~~~~~~~~~~~~~~~~~~ +LL - for i in (5 + 2)..(3 - 1) { +LL + for i in ((3 - 1)..(5 + 2)).rev() { + | error: aborting due to 6 previous errors diff --git a/src/tools/clippy/tests/ui/single_range_in_vec_init.stderr b/src/tools/clippy/tests/ui/single_range_in_vec_init.stderr index 9c125adb51a..b3bc8dd4aca 100644 --- a/src/tools/clippy/tests/ui/single_range_in_vec_init.stderr +++ b/src/tools/clippy/tests/ui/single_range_in_vec_init.stderr @@ -8,12 +8,14 @@ LL | [0..200]; = help: to override `-D warnings` add `#[allow(clippy::single_range_in_vec_init)]` help: if you wanted a `Vec` that contains the entire range, try | -LL | (0..200).collect::<std::vec::Vec<i32>>(); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - [0..200]; +LL + (0..200).collect::<std::vec::Vec<i32>>(); + | help: if you wanted an array of len 200, try | -LL | [0; 200]; - | ~~~~~~ +LL - [0..200]; +LL + [0; 200]; + | error: a `Vec` of `Range` that is only one element --> tests/ui/single_range_in_vec_init.rs:27:5 @@ -23,12 +25,14 @@ LL | vec![0..200]; | help: if you wanted a `Vec` that contains the entire range, try | -LL | (0..200).collect::<std::vec::Vec<i32>>(); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - vec![0..200]; +LL + (0..200).collect::<std::vec::Vec<i32>>(); + | help: if you wanted a `Vec` of len 200, try | -LL | vec![0; 200]; - | ~~~~~~ +LL - vec![0..200]; +LL + vec![0; 200]; + | error: an array of `Range` that is only one element --> tests/ui/single_range_in_vec_init.rs:28:5 @@ -38,12 +42,14 @@ LL | [0u8..200]; | help: if you wanted a `Vec` that contains the entire range, try | -LL | (0u8..200).collect::<std::vec::Vec<u8>>(); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - [0u8..200]; +LL + (0u8..200).collect::<std::vec::Vec<u8>>(); + | help: if you wanted an array of len 200, try | -LL | [0u8; 200]; - | ~~~~~~~~ +LL - [0u8..200]; +LL + [0u8; 200]; + | error: an array of `Range` that is only one element --> tests/ui/single_range_in_vec_init.rs:29:5 @@ -53,12 +59,14 @@ LL | [0usize..200]; | help: if you wanted a `Vec` that contains the entire range, try | -LL | (0usize..200).collect::<std::vec::Vec<usize>>(); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - [0usize..200]; +LL + (0usize..200).collect::<std::vec::Vec<usize>>(); + | help: if you wanted an array of len 200, try | -LL | [0usize; 200]; - | ~~~~~~~~~~~ +LL - [0usize..200]; +LL + [0usize; 200]; + | error: an array of `Range` that is only one element --> tests/ui/single_range_in_vec_init.rs:30:5 @@ -68,12 +76,14 @@ LL | [0..200usize]; | help: if you wanted a `Vec` that contains the entire range, try | -LL | (0..200usize).collect::<std::vec::Vec<usize>>(); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - [0..200usize]; +LL + (0..200usize).collect::<std::vec::Vec<usize>>(); + | help: if you wanted an array of len 200usize, try | -LL | [0; 200usize]; - | ~~~~~~~~~~~ +LL - [0..200usize]; +LL + [0; 200usize]; + | error: a `Vec` of `Range` that is only one element --> tests/ui/single_range_in_vec_init.rs:31:5 @@ -83,12 +93,14 @@ LL | vec![0u8..200]; | help: if you wanted a `Vec` that contains the entire range, try | -LL | (0u8..200).collect::<std::vec::Vec<u8>>(); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - vec![0u8..200]; +LL + (0u8..200).collect::<std::vec::Vec<u8>>(); + | help: if you wanted a `Vec` of len 200, try | -LL | vec![0u8; 200]; - | ~~~~~~~~ +LL - vec![0u8..200]; +LL + vec![0u8; 200]; + | error: a `Vec` of `Range` that is only one element --> tests/ui/single_range_in_vec_init.rs:32:5 @@ -98,12 +110,14 @@ LL | vec![0usize..200]; | help: if you wanted a `Vec` that contains the entire range, try | -LL | (0usize..200).collect::<std::vec::Vec<usize>>(); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - vec![0usize..200]; +LL + (0usize..200).collect::<std::vec::Vec<usize>>(); + | help: if you wanted a `Vec` of len 200, try | -LL | vec![0usize; 200]; - | ~~~~~~~~~~~ +LL - vec![0usize..200]; +LL + vec![0usize; 200]; + | error: a `Vec` of `Range` that is only one element --> tests/ui/single_range_in_vec_init.rs:33:5 @@ -113,12 +127,14 @@ LL | vec![0..200usize]; | help: if you wanted a `Vec` that contains the entire range, try | -LL | (0..200usize).collect::<std::vec::Vec<usize>>(); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - vec![0..200usize]; +LL + (0..200usize).collect::<std::vec::Vec<usize>>(); + | help: if you wanted a `Vec` of len 200usize, try | -LL | vec![0; 200usize]; - | ~~~~~~~~~~~ +LL - vec![0..200usize]; +LL + vec![0; 200usize]; + | error: an array of `Range` that is only one element --> tests/ui/single_range_in_vec_init.rs:35:5 @@ -128,8 +144,9 @@ LL | [0..200isize]; | help: if you wanted a `Vec` that contains the entire range, try | -LL | (0..200isize).collect::<std::vec::Vec<isize>>(); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - [0..200isize]; +LL + (0..200isize).collect::<std::vec::Vec<isize>>(); + | error: a `Vec` of `Range` that is only one element --> tests/ui/single_range_in_vec_init.rs:36:5 @@ -139,8 +156,9 @@ LL | vec![0..200isize]; | help: if you wanted a `Vec` that contains the entire range, try | -LL | (0..200isize).collect::<std::vec::Vec<isize>>(); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - vec![0..200isize]; +LL + (0..200isize).collect::<std::vec::Vec<isize>>(); + | error: aborting due to 10 previous errors diff --git a/src/tools/clippy/tests/ui/string_lit_chars_any.stderr b/src/tools/clippy/tests/ui/string_lit_chars_any.stderr index 4d3ca98e623..1e28ae7b163 100644 --- a/src/tools/clippy/tests/ui/string_lit_chars_any.stderr +++ b/src/tools/clippy/tests/ui/string_lit_chars_any.stderr @@ -8,8 +8,9 @@ LL | "\\.+*?()|[]{}^$#&-~".chars().any(|x| x == c); = help: to override `-D warnings` add `#[allow(clippy::string_lit_chars_any)]` help: use `matches!(...)` instead | -LL | matches!(c, '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~'); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - "\\.+*?()|[]{}^$#&-~".chars().any(|x| x == c); +LL + matches!(c, '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~'); + | error: usage of `.chars().any(...)` to check if a char matches any from a string literal --> tests/ui/string_lit_chars_any.rs:19:5 @@ -19,8 +20,9 @@ LL | r#"\.+*?()|[]{}^$#&-~"#.chars().any(|x| x == c); | help: use `matches!(...)` instead | -LL | matches!(c, '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~'); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - r#"\.+*?()|[]{}^$#&-~"#.chars().any(|x| x == c); +LL + matches!(c, '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~'); + | error: usage of `.chars().any(...)` to check if a char matches any from a string literal --> tests/ui/string_lit_chars_any.rs:20:5 @@ -30,8 +32,9 @@ LL | "\\.+*?()|[]{}^$#&-~".chars().any(|x| c == x); | help: use `matches!(...)` instead | -LL | matches!(c, '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~'); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - "\\.+*?()|[]{}^$#&-~".chars().any(|x| c == x); +LL + matches!(c, '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~'); + | error: usage of `.chars().any(...)` to check if a char matches any from a string literal --> tests/ui/string_lit_chars_any.rs:21:5 @@ -41,8 +44,9 @@ LL | r#"\.+*?()|[]{}^$#&-~"#.chars().any(|x| c == x); | help: use `matches!(...)` instead | -LL | matches!(c, '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~'); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - r#"\.+*?()|[]{}^$#&-~"#.chars().any(|x| c == x); +LL + matches!(c, '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~'); + | error: usage of `.chars().any(...)` to check if a char matches any from a string literal --> tests/ui/string_lit_chars_any.rs:23:5 @@ -52,8 +56,9 @@ LL | "\\.+*?()|[]{}^$#&-~".chars().any(|x| { x == c }); | help: use `matches!(...)` instead | -LL | matches!(c, '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~'); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - "\\.+*?()|[]{}^$#&-~".chars().any(|x| { x == c }); +LL + matches!(c, '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~'); + | error: aborting due to 5 previous errors diff --git a/src/tools/clippy/tests/ui/suspicious_command_arg_space.stderr b/src/tools/clippy/tests/ui/suspicious_command_arg_space.stderr index 6fd07d07d7b..8952a3ffe4b 100644 --- a/src/tools/clippy/tests/ui/suspicious_command_arg_space.stderr +++ b/src/tools/clippy/tests/ui/suspicious_command_arg_space.stderr @@ -8,8 +8,9 @@ LL | std::process::Command::new("echo").arg("-n hello").spawn().unwrap(); = help: to override `-D warnings` add `#[allow(clippy::suspicious_command_arg_space)]` help: consider splitting the argument | -LL | std::process::Command::new("echo").args(["-n", "hello"]).spawn().unwrap(); - | ~~~~ ~~~~~~~~~~~~~~~ +LL - std::process::Command::new("echo").arg("-n hello").spawn().unwrap(); +LL + std::process::Command::new("echo").args(["-n", "hello"]).spawn().unwrap(); + | error: single argument that looks like it should be multiple arguments --> tests/ui/suspicious_command_arg_space.rs:7:43 @@ -19,8 +20,9 @@ LL | std::process::Command::new("cat").arg("--number file").spawn().unwrap() | help: consider splitting the argument | -LL | std::process::Command::new("cat").args(["--number", "file"]).spawn().unwrap(); - | ~~~~ ~~~~~~~~~~~~~~~~~~~~ +LL - std::process::Command::new("cat").arg("--number file").spawn().unwrap(); +LL + std::process::Command::new("cat").args(["--number", "file"]).spawn().unwrap(); + | error: aborting due to 2 previous errors diff --git a/src/tools/clippy/tests/ui/suspicious_doc_comments.stderr b/src/tools/clippy/tests/ui/suspicious_doc_comments.stderr index c34e39cd0fc..7e5933df237 100644 --- a/src/tools/clippy/tests/ui/suspicious_doc_comments.stderr +++ b/src/tools/clippy/tests/ui/suspicious_doc_comments.stderr @@ -8,7 +8,8 @@ LL | ///! Fake module documentation. = help: to override `-D warnings` add `#[allow(clippy::suspicious_doc_comments)]` help: use an inner doc comment to document the parent module or crate | -LL | //! Fake module documentation. +LL - ///! Fake module documentation. +LL + //! Fake module documentation. | error: this is an outer doc comment and does not apply to the parent module or crate @@ -19,7 +20,8 @@ LL | ///! This module contains useful functions. | help: use an inner doc comment to document the parent module or crate | -LL | //! This module contains useful functions. +LL - ///! This module contains useful functions. +LL + //! This module contains useful functions. | error: this is an outer doc comment and does not apply to the parent module or crate @@ -71,7 +73,8 @@ LL | ///! a | help: use an inner doc comment to document the parent module or crate | -LL | //! a +LL - ///! a +LL + //! a | error: this is an outer doc comment and does not apply to the parent module or crate @@ -97,7 +100,8 @@ LL | ///! Very cool macro | help: use an inner doc comment to document the parent module or crate | -LL | //! Very cool macro +LL - ///! Very cool macro +LL + //! Very cool macro | error: this is an outer doc comment and does not apply to the parent module or crate @@ -108,7 +112,8 @@ LL | ///! Huh. | help: use an inner doc comment to document the parent module or crate | -LL | //! Huh. +LL - ///! Huh. +LL + //! Huh. | error: aborting due to 9 previous errors diff --git a/src/tools/clippy/tests/ui/suspicious_to_owned.stderr b/src/tools/clippy/tests/ui/suspicious_to_owned.stderr index 255f211e655..74bbcfcca51 100644 --- a/src/tools/clippy/tests/ui/suspicious_to_owned.stderr +++ b/src/tools/clippy/tests/ui/suspicious_to_owned.stderr @@ -8,12 +8,14 @@ LL | let _ = cow.to_owned(); = help: to override `-D warnings` add `#[allow(clippy::suspicious_to_owned)]` help: depending on intent, either make the Cow an Owned variant | -LL | let _ = cow.into_owned(); - | ~~~~~~~~~~~~~~~~ +LL - let _ = cow.to_owned(); +LL + let _ = cow.into_owned(); + | help: or clone the Cow itself | -LL | let _ = cow.clone(); - | ~~~~~~~~~~~ +LL - let _ = cow.to_owned(); +LL + let _ = cow.clone(); + | error: this `to_owned` call clones the Cow<'_, [char; 3]> itself and does not cause the Cow<'_, [char; 3]> contents to become owned --> tests/ui/suspicious_to_owned.rs:29:13 @@ -23,12 +25,14 @@ LL | let _ = cow.to_owned(); | help: depending on intent, either make the Cow an Owned variant | -LL | let _ = cow.into_owned(); - | ~~~~~~~~~~~~~~~~ +LL - let _ = cow.to_owned(); +LL + let _ = cow.into_owned(); + | help: or clone the Cow itself | -LL | let _ = cow.clone(); - | ~~~~~~~~~~~ +LL - let _ = cow.to_owned(); +LL + let _ = cow.clone(); + | error: this `to_owned` call clones the Cow<'_, Vec<char>> itself and does not cause the Cow<'_, Vec<char>> contents to become owned --> tests/ui/suspicious_to_owned.rs:40:13 @@ -38,12 +42,14 @@ LL | let _ = cow.to_owned(); | help: depending on intent, either make the Cow an Owned variant | -LL | let _ = cow.into_owned(); - | ~~~~~~~~~~~~~~~~ +LL - let _ = cow.to_owned(); +LL + let _ = cow.into_owned(); + | help: or clone the Cow itself | -LL | let _ = cow.clone(); - | ~~~~~~~~~~~ +LL - let _ = cow.to_owned(); +LL + let _ = cow.clone(); + | error: this `to_owned` call clones the Cow<'_, str> itself and does not cause the Cow<'_, str> contents to become owned --> tests/ui/suspicious_to_owned.rs:51:13 @@ -53,12 +59,14 @@ LL | let _ = cow.to_owned(); | help: depending on intent, either make the Cow an Owned variant | -LL | let _ = cow.into_owned(); - | ~~~~~~~~~~~~~~~~ +LL - let _ = cow.to_owned(); +LL + let _ = cow.into_owned(); + | help: or clone the Cow itself | -LL | let _ = cow.clone(); - | ~~~~~~~~~~~ +LL - let _ = cow.to_owned(); +LL + let _ = cow.clone(); + | error: implicitly cloning a `String` by calling `to_owned` on its dereferenced type --> tests/ui/suspicious_to_owned.rs:66:13 diff --git a/src/tools/clippy/tests/ui/suspicious_xor_used_as_pow.stderr b/src/tools/clippy/tests/ui/suspicious_xor_used_as_pow.stderr index 43b03676b1d..2a153169bd3 100644 --- a/src/tools/clippy/tests/ui/suspicious_xor_used_as_pow.stderr +++ b/src/tools/clippy/tests/ui/suspicious_xor_used_as_pow.stderr @@ -8,8 +8,9 @@ LL | let _ = 2 ^ 5; = help: to override `-D warnings` add `#[allow(clippy::suspicious_xor_used_as_pow)]` help: did you mean to write | -LL | let _ = 2.pow(5); - | ~~~~~~~~ +LL - let _ = 2 ^ 5; +LL + let _ = 2.pow(5); + | error: `^` is not the exponentiation operator --> tests/ui/suspicious_xor_used_as_pow.rs:22:13 @@ -19,8 +20,9 @@ LL | let _ = 2i32 ^ 9i32; | help: did you mean to write | -LL | let _ = 2i32.pow(9i32); - | ~~~~~~~~~~~~~~ +LL - let _ = 2i32 ^ 9i32; +LL + let _ = 2i32.pow(9i32); + | error: `^` is not the exponentiation operator --> tests/ui/suspicious_xor_used_as_pow.rs:24:13 @@ -30,8 +32,9 @@ LL | let _ = 2i32 ^ 2i32; | help: did you mean to write | -LL | let _ = 2i32.pow(2i32); - | ~~~~~~~~~~~~~~ +LL - let _ = 2i32 ^ 2i32; +LL + let _ = 2i32.pow(2i32); + | error: `^` is not the exponentiation operator --> tests/ui/suspicious_xor_used_as_pow.rs:26:13 @@ -41,8 +44,9 @@ LL | let _ = 50i32 ^ 3i32; | help: did you mean to write | -LL | let _ = 50i32.pow(3i32); - | ~~~~~~~~~~~~~~~ +LL - let _ = 50i32 ^ 3i32; +LL + let _ = 50i32.pow(3i32); + | error: `^` is not the exponentiation operator --> tests/ui/suspicious_xor_used_as_pow.rs:28:13 @@ -52,8 +56,9 @@ LL | let _ = 5i32 ^ 8i32; | help: did you mean to write | -LL | let _ = 5i32.pow(8i32); - | ~~~~~~~~~~~~~~ +LL - let _ = 5i32 ^ 8i32; +LL + let _ = 5i32.pow(8i32); + | error: `^` is not the exponentiation operator --> tests/ui/suspicious_xor_used_as_pow.rs:30:13 @@ -63,8 +68,9 @@ LL | let _ = 2i32 ^ 32i32; | help: did you mean to write | -LL | let _ = 2i32.pow(32i32); - | ~~~~~~~~~~~~~~~ +LL - let _ = 2i32 ^ 32i32; +LL + let _ = 2i32.pow(32i32); + | error: `^` is not the exponentiation operator --> tests/ui/suspicious_xor_used_as_pow.rs:13:9 @@ -78,8 +84,9 @@ LL | macro_test_inside!(); = note: this error originates in the macro `macro_test_inside` (in Nightly builds, run with -Z macro-backtrace for more info) help: did you mean to write | -LL | 1.pow(2) // should warn even if inside macro - | ~~~~~~~~ +LL - 1 ^ 2 // should warn even if inside macro +LL + 1.pow(2) // should warn even if inside macro + | error: aborting due to 7 previous errors diff --git a/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.stderr b/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.stderr index 8801eb943ce..f4f83cd7ac6 100644 --- a/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.stderr +++ b/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.stderr @@ -8,8 +8,9 @@ LL | let _: *const f32 = transmute(ptr); = help: to override `-D warnings` add `#[allow(clippy::transmute_ptr_to_ptr)]` help: use `pointer::cast` instead | -LL | let _: *const f32 = ptr.cast::<f32>(); - | ~~~~~~~~~~~~~~~~~ +LL - let _: *const f32 = transmute(ptr); +LL + let _: *const f32 = ptr.cast::<f32>(); + | error: transmute from a pointer to a pointer --> tests/ui/transmute_ptr_to_ptr.rs:34:27 @@ -19,8 +20,9 @@ LL | let _: *mut f32 = transmute(mut_ptr); | help: use `pointer::cast` instead | -LL | let _: *mut f32 = mut_ptr.cast::<f32>(); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - let _: *mut f32 = transmute(mut_ptr); +LL + let _: *mut f32 = mut_ptr.cast::<f32>(); + | error: transmute from a reference to a reference --> tests/ui/transmute_ptr_to_ptr.rs:37:23 @@ -60,8 +62,9 @@ LL | let _: *const u32 = transmute(mut_ptr); | help: use `pointer::cast_const` instead | -LL | let _: *const u32 = mut_ptr.cast_const(); - | ~~~~~~~~~~~~~~~~~~~~ +LL - let _: *const u32 = transmute(mut_ptr); +LL + let _: *const u32 = mut_ptr.cast_const(); + | error: transmute from a pointer to a pointer --> tests/ui/transmute_ptr_to_ptr.rs:52:27 @@ -71,8 +74,9 @@ LL | let _: *mut u32 = transmute(ptr); | help: use `pointer::cast_mut` instead | -LL | let _: *mut u32 = ptr.cast_mut(); - | ~~~~~~~~~~~~~~ +LL - let _: *mut u32 = transmute(ptr); +LL + let _: *mut u32 = ptr.cast_mut(); + | error: transmute from a pointer to a pointer --> tests/ui/transmute_ptr_to_ptr.rs:64:14 @@ -82,8 +86,9 @@ LL | unsafe { transmute(v) } | help: use an `as` cast instead | -LL | unsafe { v as *const &() } - | ~~~~~~~~~~~~~~~ +LL - unsafe { transmute(v) } +LL + unsafe { v as *const &() } + | error: transmute from a pointer to a pointer --> tests/ui/transmute_ptr_to_ptr.rs:79:28 @@ -93,8 +98,9 @@ LL | let _: *const i8 = transmute(ptr); | help: use an `as` cast instead | -LL | let _: *const i8 = ptr as *const i8; - | ~~~~~~~~~~~~~~~~ +LL - let _: *const i8 = transmute(ptr); +LL + let _: *const i8 = ptr as *const i8; + | error: transmute from a pointer to a pointer --> tests/ui/transmute_ptr_to_ptr.rs:86:28 @@ -104,8 +110,9 @@ LL | let _: *const i8 = transmute(ptr); | help: use `pointer::cast` instead | -LL | let _: *const i8 = ptr.cast::<i8>(); - | ~~~~~~~~~~~~~~~~ +LL - let _: *const i8 = transmute(ptr); +LL + let _: *const i8 = ptr.cast::<i8>(); + | error: transmute from a pointer to a pointer --> tests/ui/transmute_ptr_to_ptr.rs:93:26 @@ -115,8 +122,9 @@ LL | let _: *mut u8 = transmute(ptr); | help: use an `as` cast instead | -LL | let _: *mut u8 = ptr as *mut u8; - | ~~~~~~~~~~~~~~ +LL - let _: *mut u8 = transmute(ptr); +LL + let _: *mut u8 = ptr as *mut u8; + | error: transmute from a pointer to a pointer --> tests/ui/transmute_ptr_to_ptr.rs:94:28 @@ -126,8 +134,9 @@ LL | let _: *const u8 = transmute(mut_ptr); | help: use an `as` cast instead | -LL | let _: *const u8 = mut_ptr as *const u8; - | ~~~~~~~~~~~~~~~~~~~~ +LL - let _: *const u8 = transmute(mut_ptr); +LL + let _: *const u8 = mut_ptr as *const u8; + | error: transmute from a pointer to a pointer --> tests/ui/transmute_ptr_to_ptr.rs:101:26 @@ -137,8 +146,9 @@ LL | let _: *mut u8 = transmute(ptr); | help: use `pointer::cast_mut` instead | -LL | let _: *mut u8 = ptr.cast_mut(); - | ~~~~~~~~~~~~~~ +LL - let _: *mut u8 = transmute(ptr); +LL + let _: *mut u8 = ptr.cast_mut(); + | error: transmute from a pointer to a pointer --> tests/ui/transmute_ptr_to_ptr.rs:102:28 @@ -148,8 +158,9 @@ LL | let _: *const u8 = transmute(mut_ptr); | help: use `pointer::cast_const` instead | -LL | let _: *const u8 = mut_ptr.cast_const(); - | ~~~~~~~~~~~~~~~~~~~~ +LL - let _: *const u8 = transmute(mut_ptr); +LL + let _: *const u8 = mut_ptr.cast_const(); + | error: aborting due to 16 previous errors diff --git a/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.stderr b/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.stderr index 2d74967ede5..21edd39e7ad 100644 --- a/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.stderr +++ b/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.stderr @@ -17,8 +17,9 @@ LL | let _ptr_i8_transmute = unsafe { transmute::<*const i32, *const i8>(ptr = help: to override `-D warnings` add `#[allow(clippy::transmute_ptr_to_ptr)]` help: use `pointer::cast` instead | -LL | let _ptr_i8_transmute = unsafe { ptr_i32.cast::<i8>() }; - | ~~~~~~~~~~~~~~~~~~~~ +LL - let _ptr_i8_transmute = unsafe { transmute::<*const i32, *const i8>(ptr_i32) }; +LL + let _ptr_i8_transmute = unsafe { ptr_i32.cast::<i8>() }; + | error: transmute from a pointer to a pointer --> tests/ui/transmutes_expressible_as_ptr_casts.rs:27:46 @@ -28,8 +29,9 @@ LL | let _ptr_to_unsized_transmute = unsafe { transmute::<*const [i32], *con | help: use an `as` cast instead | -LL | let _ptr_to_unsized_transmute = unsafe { slice_ptr as *const [u32] }; - | ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _ptr_to_unsized_transmute = unsafe { transmute::<*const [i32], *const [u32]>(slice_ptr) }; +LL + let _ptr_to_unsized_transmute = unsafe { slice_ptr as *const [u32] }; + | error: transmute from `*const i32` to `usize` which could be expressed as a pointer cast instead --> tests/ui/transmutes_expressible_as_ptr_casts.rs:33:50 diff --git a/src/tools/clippy/tests/ui/unit_arg.stderr b/src/tools/clippy/tests/ui/unit_arg.stderr index 41ad1a2d383..bf79e93e444 100644 --- a/src/tools/clippy/tests/ui/unit_arg.stderr +++ b/src/tools/clippy/tests/ui/unit_arg.stderr @@ -10,7 +10,8 @@ LL | | }); = help: to override `-D warnings` add `#[allow(clippy::unit_arg)]` help: remove the semicolon from the last statement in the block | -LL | 1 +LL - 1; +LL + 1 | help: or move the expression in front of the call and replace it with the unit literal `()` | @@ -43,7 +44,8 @@ LL | | }); | help: remove the semicolon from the last statement in the block | -LL | foo(2) +LL - foo(2); +LL + foo(2) | help: or move the expression in front of the call and replace it with the unit literal `()` | @@ -64,7 +66,8 @@ LL | | }); | help: remove the semicolon from the last statement in the block | -LL | 1 +LL - 1; +LL + 1 | help: or move the expression in front of the call and replace it with the unit literal `()` | @@ -98,7 +101,8 @@ LL | | }); | help: remove the semicolon from the last statement in the block | -LL | foo(2) +LL - foo(2); +LL + foo(2) | help: or move the expressions in front of the call and replace them with the unit literal `()` | @@ -124,11 +128,13 @@ LL | | ); | help: remove the semicolon from the last statement in the block | -LL | foo(1) +LL - foo(1); +LL + foo(1) | help: remove the semicolon from the last statement in the block | -LL | foo(3) +LL - foo(3); +LL + foo(3) | help: or move the expressions in front of the call and replace them with the unit literal `()` | diff --git a/src/tools/clippy/tests/ui/unknown_clippy_lints.stderr b/src/tools/clippy/tests/ui/unknown_clippy_lints.stderr index aa2c2f3c0e2..ea925cd3a9f 100644 --- a/src/tools/clippy/tests/ui/unknown_clippy_lints.stderr +++ b/src/tools/clippy/tests/ui/unknown_clippy_lints.stderr @@ -39,8 +39,9 @@ LL | #[warn(clippy::dead_cod)] | help: a lint with a similar name exists in `rustc` lints | -LL | #[warn(dead_code)] - | ~~~~~~~~~ +LL - #[warn(clippy::dead_cod)] +LL + #[warn(dead_code)] + | error: unknown lint: `clippy::unused_colle` --> tests/ui/unknown_clippy_lints.rs:13:8 @@ -62,8 +63,9 @@ LL | #[warn(clippy::missing_docs)] | help: a lint with a similar name exists in `rustc` lints | -LL | #[warn(missing_docs)] - | ~~~~~~~~~~~~ +LL - #[warn(clippy::missing_docs)] +LL + #[warn(missing_docs)] + | error: aborting due to 9 previous errors diff --git a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr index 35a2144c389..9bb1b71f0ed 100644 --- a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr +++ b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr @@ -8,8 +8,9 @@ LL | let _ = opt.unwrap_or_else(|| 2); = help: to override `-D warnings` add `#[allow(clippy::unnecessary_lazy_evaluations)]` help: use `unwrap_or` instead | -LL | let _ = opt.unwrap_or(2); - | ~~~~~~~~~~~~ +LL - let _ = opt.unwrap_or_else(|| 2); +LL + let _ = opt.unwrap_or(2); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:84:13 @@ -19,8 +20,9 @@ LL | let _ = opt.unwrap_or_else(|| astronomers_pi); | help: use `unwrap_or` instead | -LL | let _ = opt.unwrap_or(astronomers_pi); - | ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _ = opt.unwrap_or_else(|| astronomers_pi); +LL + let _ = opt.unwrap_or(astronomers_pi); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:85:13 @@ -30,8 +32,9 @@ LL | let _ = opt.unwrap_or_else(|| ext_str.some_field); | help: use `unwrap_or` instead | -LL | let _ = opt.unwrap_or(ext_str.some_field); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _ = opt.unwrap_or_else(|| ext_str.some_field); +LL + let _ = opt.unwrap_or(ext_str.some_field); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:87:13 @@ -41,8 +44,9 @@ LL | let _ = opt.and_then(|_| ext_opt); | help: use `and` instead | -LL | let _ = opt.and(ext_opt); - | ~~~~~~~~~~~~ +LL - let _ = opt.and_then(|_| ext_opt); +LL + let _ = opt.and(ext_opt); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:88:13 @@ -52,8 +56,9 @@ LL | let _ = opt.or_else(|| ext_opt); | help: use `or` instead | -LL | let _ = opt.or(ext_opt); - | ~~~~~~~~~~~ +LL - let _ = opt.or_else(|| ext_opt); +LL + let _ = opt.or(ext_opt); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:89:13 @@ -63,8 +68,9 @@ LL | let _ = opt.or_else(|| None); | help: use `or` instead | -LL | let _ = opt.or(None); - | ~~~~~~~~ +LL - let _ = opt.or_else(|| None); +LL + let _ = opt.or(None); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:90:13 @@ -74,8 +80,9 @@ LL | let _ = opt.get_or_insert_with(|| 2); | help: use `get_or_insert` instead | -LL | let _ = opt.get_or_insert(2); - | ~~~~~~~~~~~~~~~~ +LL - let _ = opt.get_or_insert_with(|| 2); +LL + let _ = opt.get_or_insert(2); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:91:13 @@ -85,8 +92,9 @@ LL | let _ = opt.ok_or_else(|| 2); | help: use `ok_or` instead | -LL | let _ = opt.ok_or(2); - | ~~~~~~~~ +LL - let _ = opt.ok_or_else(|| 2); +LL + let _ = opt.ok_or(2); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:92:13 @@ -96,8 +104,9 @@ LL | let _ = nested_tuple_opt.unwrap_or_else(|| Some((1, 2))); | help: use `unwrap_or` instead | -LL | let _ = nested_tuple_opt.unwrap_or(Some((1, 2))); - | ~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _ = nested_tuple_opt.unwrap_or_else(|| Some((1, 2))); +LL + let _ = nested_tuple_opt.unwrap_or(Some((1, 2))); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:93:13 @@ -107,8 +116,9 @@ LL | let _ = cond.then(|| astronomers_pi); | help: use `then_some` instead | -LL | let _ = cond.then_some(astronomers_pi); - | ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _ = cond.then(|| astronomers_pi); +LL + let _ = cond.then_some(astronomers_pi); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:94:13 @@ -118,8 +128,9 @@ LL | let _ = true.then(|| -> _ {}); | help: use `then_some` instead | -LL | let _ = true.then_some({}); - | ~~~~~~~~~~~~~ +LL - let _ = true.then(|| -> _ {}); +LL + let _ = true.then_some({}); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:95:13 @@ -129,8 +140,9 @@ LL | let _ = true.then(|| {}); | help: use `then_some` instead | -LL | let _ = true.then_some({}); - | ~~~~~~~~~~~~~ +LL - let _ = true.then(|| {}); +LL + let _ = true.then_some({}); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:99:13 @@ -140,8 +152,9 @@ LL | let _ = Some(1).unwrap_or_else(|| *r); | help: use `unwrap_or` instead | -LL | let _ = Some(1).unwrap_or(*r); - | ~~~~~~~~~~~~~ +LL - let _ = Some(1).unwrap_or_else(|| *r); +LL + let _ = Some(1).unwrap_or(*r); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:101:13 @@ -151,8 +164,9 @@ LL | let _ = Some(1).unwrap_or_else(|| *b); | help: use `unwrap_or` instead | -LL | let _ = Some(1).unwrap_or(*b); - | ~~~~~~~~~~~~~ +LL - let _ = Some(1).unwrap_or_else(|| *b); +LL + let _ = Some(1).unwrap_or(*b); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:103:13 @@ -162,8 +176,9 @@ LL | let _ = Some(1).as_ref().unwrap_or_else(|| &r); | help: use `unwrap_or` instead | -LL | let _ = Some(1).as_ref().unwrap_or(&r); - | ~~~~~~~~~~~~~ +LL - let _ = Some(1).as_ref().unwrap_or_else(|| &r); +LL + let _ = Some(1).as_ref().unwrap_or(&r); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:104:13 @@ -173,8 +188,9 @@ LL | let _ = Some(1).as_ref().unwrap_or_else(|| &b); | help: use `unwrap_or` instead | -LL | let _ = Some(1).as_ref().unwrap_or(&b); - | ~~~~~~~~~~~~~ +LL - let _ = Some(1).as_ref().unwrap_or_else(|| &b); +LL + let _ = Some(1).as_ref().unwrap_or(&b); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:107:13 @@ -184,8 +200,9 @@ LL | let _ = Some(10).unwrap_or_else(|| 2); | help: use `unwrap_or` instead | -LL | let _ = Some(10).unwrap_or(2); - | ~~~~~~~~~~~~ +LL - let _ = Some(10).unwrap_or_else(|| 2); +LL + let _ = Some(10).unwrap_or(2); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:108:13 @@ -195,8 +212,9 @@ LL | let _ = Some(10).and_then(|_| ext_opt); | help: use `and` instead | -LL | let _ = Some(10).and(ext_opt); - | ~~~~~~~~~~~~ +LL - let _ = Some(10).and_then(|_| ext_opt); +LL + let _ = Some(10).and(ext_opt); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:109:28 @@ -206,8 +224,9 @@ LL | let _: Option<usize> = None.or_else(|| ext_opt); | help: use `or` instead | -LL | let _: Option<usize> = None.or(ext_opt); - | ~~~~~~~~~~~ +LL - let _: Option<usize> = None.or_else(|| ext_opt); +LL + let _: Option<usize> = None.or(ext_opt); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:110:13 @@ -217,8 +236,9 @@ LL | let _ = None.get_or_insert_with(|| 2); | help: use `get_or_insert` instead | -LL | let _ = None.get_or_insert(2); - | ~~~~~~~~~~~~~~~~ +LL - let _ = None.get_or_insert_with(|| 2); +LL + let _ = None.get_or_insert(2); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:111:35 @@ -228,8 +248,9 @@ LL | let _: Result<usize, usize> = None.ok_or_else(|| 2); | help: use `ok_or` instead | -LL | let _: Result<usize, usize> = None.ok_or(2); - | ~~~~~~~~ +LL - let _: Result<usize, usize> = None.ok_or_else(|| 2); +LL + let _: Result<usize, usize> = None.ok_or(2); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:112:28 @@ -239,8 +260,9 @@ LL | let _: Option<usize> = None.or_else(|| None); | help: use `or` instead | -LL | let _: Option<usize> = None.or(None); - | ~~~~~~~~ +LL - let _: Option<usize> = None.or_else(|| None); +LL + let _: Option<usize> = None.or(None); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:115:13 @@ -250,8 +272,9 @@ LL | let _ = deep.0.unwrap_or_else(|| 2); | help: use `unwrap_or` instead | -LL | let _ = deep.0.unwrap_or(2); - | ~~~~~~~~~~~~ +LL - let _ = deep.0.unwrap_or_else(|| 2); +LL + let _ = deep.0.unwrap_or(2); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:116:13 @@ -261,8 +284,9 @@ LL | let _ = deep.0.and_then(|_| ext_opt); | help: use `and` instead | -LL | let _ = deep.0.and(ext_opt); - | ~~~~~~~~~~~~ +LL - let _ = deep.0.and_then(|_| ext_opt); +LL + let _ = deep.0.and(ext_opt); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:117:13 @@ -272,8 +296,9 @@ LL | let _ = deep.0.or_else(|| None); | help: use `or` instead | -LL | let _ = deep.0.or(None); - | ~~~~~~~~ +LL - let _ = deep.0.or_else(|| None); +LL + let _ = deep.0.or(None); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:118:13 @@ -283,8 +308,9 @@ LL | let _ = deep.0.get_or_insert_with(|| 2); | help: use `get_or_insert` instead | -LL | let _ = deep.0.get_or_insert(2); - | ~~~~~~~~~~~~~~~~ +LL - let _ = deep.0.get_or_insert_with(|| 2); +LL + let _ = deep.0.get_or_insert(2); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:119:13 @@ -294,8 +320,9 @@ LL | let _ = deep.0.ok_or_else(|| 2); | help: use `ok_or` instead | -LL | let _ = deep.0.ok_or(2); - | ~~~~~~~~ +LL - let _ = deep.0.ok_or_else(|| 2); +LL + let _ = deep.0.ok_or(2); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:150:28 @@ -305,8 +332,9 @@ LL | let _: Option<usize> = None.or_else(|| Some(3)); | help: use `or` instead | -LL | let _: Option<usize> = None.or(Some(3)); - | ~~~~~~~~~~~ +LL - let _: Option<usize> = None.or_else(|| Some(3)); +LL + let _: Option<usize> = None.or(Some(3)); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:151:13 @@ -316,8 +344,9 @@ LL | let _ = deep.0.or_else(|| Some(3)); | help: use `or` instead | -LL | let _ = deep.0.or(Some(3)); - | ~~~~~~~~~~~ +LL - let _ = deep.0.or_else(|| Some(3)); +LL + let _ = deep.0.or(Some(3)); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:152:13 @@ -327,8 +356,9 @@ LL | let _ = opt.or_else(|| Some(3)); | help: use `or` instead | -LL | let _ = opt.or(Some(3)); - | ~~~~~~~~~~~ +LL - let _ = opt.or_else(|| Some(3)); +LL + let _ = opt.or(Some(3)); + | error: unnecessary closure used to substitute value for `Result::Err` --> tests/ui/unnecessary_lazy_eval.rs:158:13 @@ -338,8 +368,9 @@ LL | let _ = res2.unwrap_or_else(|_| 2); | help: use `unwrap_or` instead | -LL | let _ = res2.unwrap_or(2); - | ~~~~~~~~~~~~ +LL - let _ = res2.unwrap_or_else(|_| 2); +LL + let _ = res2.unwrap_or(2); + | error: unnecessary closure used to substitute value for `Result::Err` --> tests/ui/unnecessary_lazy_eval.rs:159:13 @@ -349,8 +380,9 @@ LL | let _ = res2.unwrap_or_else(|_| astronomers_pi); | help: use `unwrap_or` instead | -LL | let _ = res2.unwrap_or(astronomers_pi); - | ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _ = res2.unwrap_or_else(|_| astronomers_pi); +LL + let _ = res2.unwrap_or(astronomers_pi); + | error: unnecessary closure used to substitute value for `Result::Err` --> tests/ui/unnecessary_lazy_eval.rs:160:13 @@ -360,8 +392,9 @@ LL | let _ = res2.unwrap_or_else(|_| ext_str.some_field); | help: use `unwrap_or` instead | -LL | let _ = res2.unwrap_or(ext_str.some_field); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _ = res2.unwrap_or_else(|_| ext_str.some_field); +LL + let _ = res2.unwrap_or(ext_str.some_field); + | error: unnecessary closure used to substitute value for `Result::Err` --> tests/ui/unnecessary_lazy_eval.rs:182:35 @@ -371,8 +404,9 @@ LL | let _: Result<usize, usize> = res.and_then(|_| Err(2)); | help: use `and` instead | -LL | let _: Result<usize, usize> = res.and(Err(2)); - | ~~~~~~~~~~~ +LL - let _: Result<usize, usize> = res.and_then(|_| Err(2)); +LL + let _: Result<usize, usize> = res.and(Err(2)); + | error: unnecessary closure used to substitute value for `Result::Err` --> tests/ui/unnecessary_lazy_eval.rs:183:35 @@ -382,8 +416,9 @@ LL | let _: Result<usize, usize> = res.and_then(|_| Err(astronomers_pi)); | help: use `and` instead | -LL | let _: Result<usize, usize> = res.and(Err(astronomers_pi)); - | ~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _: Result<usize, usize> = res.and_then(|_| Err(astronomers_pi)); +LL + let _: Result<usize, usize> = res.and(Err(astronomers_pi)); + | error: unnecessary closure used to substitute value for `Result::Err` --> tests/ui/unnecessary_lazy_eval.rs:184:35 @@ -393,8 +428,9 @@ LL | let _: Result<usize, usize> = res.and_then(|_| Err(ext_str.some_field)) | help: use `and` instead | -LL | let _: Result<usize, usize> = res.and(Err(ext_str.some_field)); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _: Result<usize, usize> = res.and_then(|_| Err(ext_str.some_field)); +LL + let _: Result<usize, usize> = res.and(Err(ext_str.some_field)); + | error: unnecessary closure used to substitute value for `Result::Err` --> tests/ui/unnecessary_lazy_eval.rs:186:35 @@ -404,8 +440,9 @@ LL | let _: Result<usize, usize> = res.or_else(|_| Ok(2)); | help: use `or` instead | -LL | let _: Result<usize, usize> = res.or(Ok(2)); - | ~~~~~~~~~ +LL - let _: Result<usize, usize> = res.or_else(|_| Ok(2)); +LL + let _: Result<usize, usize> = res.or(Ok(2)); + | error: unnecessary closure used to substitute value for `Result::Err` --> tests/ui/unnecessary_lazy_eval.rs:187:35 @@ -415,8 +452,9 @@ LL | let _: Result<usize, usize> = res.or_else(|_| Ok(astronomers_pi)); | help: use `or` instead | -LL | let _: Result<usize, usize> = res.or(Ok(astronomers_pi)); - | ~~~~~~~~~~~~~~~~~~~~~~ +LL - let _: Result<usize, usize> = res.or_else(|_| Ok(astronomers_pi)); +LL + let _: Result<usize, usize> = res.or(Ok(astronomers_pi)); + | error: unnecessary closure used to substitute value for `Result::Err` --> tests/ui/unnecessary_lazy_eval.rs:188:35 @@ -426,8 +464,9 @@ LL | let _: Result<usize, usize> = res.or_else(|_| Ok(ext_str.some_field)); | help: use `or` instead | -LL | let _: Result<usize, usize> = res.or(Ok(ext_str.some_field)); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _: Result<usize, usize> = res.or_else(|_| Ok(ext_str.some_field)); +LL + let _: Result<usize, usize> = res.or(Ok(ext_str.some_field)); + | error: unnecessary closure used to substitute value for `Result::Err` --> tests/ui/unnecessary_lazy_eval.rs:189:35 @@ -440,8 +479,9 @@ LL | | or_else(|_| Ok(ext_str.some_field)); | help: use `or` instead | -LL | or(Ok(ext_str.some_field)); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - or_else(|_| Ok(ext_str.some_field)); +LL + or(Ok(ext_str.some_field)); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:219:14 @@ -451,8 +491,9 @@ LL | let _x = false.then(|| i32::MAX + 1); | help: use `then_some` instead | -LL | let _x = false.then_some(i32::MAX + 1); - | ~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| i32::MAX + 1); +LL + let _x = false.then_some(i32::MAX + 1); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:221:14 @@ -462,8 +503,9 @@ LL | let _x = false.then(|| i32::MAX * 2); | help: use `then_some` instead | -LL | let _x = false.then_some(i32::MAX * 2); - | ~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| i32::MAX * 2); +LL + let _x = false.then_some(i32::MAX * 2); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:223:14 @@ -473,8 +515,9 @@ LL | let _x = false.then(|| i32::MAX - 1); | help: use `then_some` instead | -LL | let _x = false.then_some(i32::MAX - 1); - | ~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| i32::MAX - 1); +LL + let _x = false.then_some(i32::MAX - 1); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:225:14 @@ -484,8 +527,9 @@ LL | let _x = false.then(|| i32::MIN - 1); | help: use `then_some` instead | -LL | let _x = false.then_some(i32::MIN - 1); - | ~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| i32::MIN - 1); +LL + let _x = false.then_some(i32::MIN - 1); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:227:14 @@ -495,8 +539,9 @@ LL | let _x = false.then(|| (1 + 2 * 3 - 2 / 3 + 9) << 2); | help: use `then_some` instead | -LL | let _x = false.then_some((1 + 2 * 3 - 2 / 3 + 9) << 2); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| (1 + 2 * 3 - 2 / 3 + 9) << 2); +LL + let _x = false.then_some((1 + 2 * 3 - 2 / 3 + 9) << 2); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:229:14 @@ -506,8 +551,9 @@ LL | let _x = false.then(|| 255u8 << 7); | help: use `then_some` instead | -LL | let _x = false.then_some(255u8 << 7); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| 255u8 << 7); +LL + let _x = false.then_some(255u8 << 7); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:231:14 @@ -517,8 +563,9 @@ LL | let _x = false.then(|| 255u8 << 8); | help: use `then_some` instead | -LL | let _x = false.then_some(255u8 << 8); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| 255u8 << 8); +LL + let _x = false.then_some(255u8 << 8); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:233:14 @@ -528,8 +575,9 @@ LL | let _x = false.then(|| 255u8 >> 8); | help: use `then_some` instead | -LL | let _x = false.then_some(255u8 >> 8); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| 255u8 >> 8); +LL + let _x = false.then_some(255u8 >> 8); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:236:14 @@ -539,8 +587,9 @@ LL | let _x = false.then(|| i32::MAX + -1); | help: use `then_some` instead | -LL | let _x = false.then_some(i32::MAX + -1); - | ~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| i32::MAX + -1); +LL + let _x = false.then_some(i32::MAX + -1); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:238:14 @@ -550,8 +599,9 @@ LL | let _x = false.then(|| -i32::MAX); | help: use `then_some` instead | -LL | let _x = false.then_some(-i32::MAX); - | ~~~~~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| -i32::MAX); +LL + let _x = false.then_some(-i32::MAX); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:240:14 @@ -561,8 +611,9 @@ LL | let _x = false.then(|| -i32::MIN); | help: use `then_some` instead | -LL | let _x = false.then_some(-i32::MIN); - | ~~~~~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| -i32::MIN); +LL + let _x = false.then_some(-i32::MIN); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:243:14 @@ -572,8 +623,9 @@ LL | let _x = false.then(|| 255 >> -7); | help: use `then_some` instead | -LL | let _x = false.then_some(255 >> -7); - | ~~~~~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| 255 >> -7); +LL + let _x = false.then_some(255 >> -7); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:245:14 @@ -583,8 +635,9 @@ LL | let _x = false.then(|| 255 << -1); | help: use `then_some` instead | -LL | let _x = false.then_some(255 << -1); - | ~~~~~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| 255 << -1); +LL + let _x = false.then_some(255 << -1); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:247:14 @@ -594,8 +647,9 @@ LL | let _x = false.then(|| 1 / 0); | help: use `then_some` instead | -LL | let _x = false.then_some(1 / 0); - | ~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| 1 / 0); +LL + let _x = false.then_some(1 / 0); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:249:14 @@ -605,8 +659,9 @@ LL | let _x = false.then(|| x << -1); | help: use `then_some` instead | -LL | let _x = false.then_some(x << -1); - | ~~~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| x << -1); +LL + let _x = false.then_some(x << -1); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:251:14 @@ -616,8 +671,9 @@ LL | let _x = false.then(|| x << 2); | help: use `then_some` instead | -LL | let _x = false.then_some(x << 2); - | ~~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| x << 2); +LL + let _x = false.then_some(x << 2); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:261:14 @@ -627,8 +683,9 @@ LL | let _x = false.then(|| x / 0); | help: use `then_some` instead | -LL | let _x = false.then_some(x / 0); - | ~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| x / 0); +LL + let _x = false.then_some(x / 0); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:263:14 @@ -638,8 +695,9 @@ LL | let _x = false.then(|| x % 0); | help: use `then_some` instead | -LL | let _x = false.then_some(x % 0); - | ~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| x % 0); +LL + let _x = false.then_some(x % 0); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:266:14 @@ -649,8 +707,9 @@ LL | let _x = false.then(|| 1 / -1); | help: use `then_some` instead | -LL | let _x = false.then_some(1 / -1); - | ~~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| 1 / -1); +LL + let _x = false.then_some(1 / -1); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:268:14 @@ -660,8 +719,9 @@ LL | let _x = false.then(|| i32::MIN / -1); | help: use `then_some` instead | -LL | let _x = false.then_some(i32::MIN / -1); - | ~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| i32::MIN / -1); +LL + let _x = false.then_some(i32::MIN / -1); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:271:14 @@ -671,8 +731,9 @@ LL | let _x = false.then(|| i32::MIN / 0); | help: use `then_some` instead | -LL | let _x = false.then_some(i32::MIN / 0); - | ~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| i32::MIN / 0); +LL + let _x = false.then_some(i32::MIN / 0); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:273:14 @@ -682,8 +743,9 @@ LL | let _x = false.then(|| 4 / 2); | help: use `then_some` instead | -LL | let _x = false.then_some(4 / 2); - | ~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| 4 / 2); +LL + let _x = false.then_some(4 / 2); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:281:14 @@ -693,8 +755,9 @@ LL | let _x = false.then(|| f1 + f2); | help: use `then_some` instead | -LL | let _x = false.then_some(f1 + f2); - | ~~~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| f1 + f2); +LL + let _x = false.then_some(f1 + f2); + | error: aborting due to 63 previous errors diff --git a/src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.stderr b/src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.stderr index 390235b2124..9688c44c914 100644 --- a/src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.stderr +++ b/src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.stderr @@ -8,8 +8,9 @@ LL | let _ = Ok(1).unwrap_or_else(|()| 2); = help: to override `-D warnings` add `#[allow(clippy::unnecessary_lazy_evaluations)]` help: use `unwrap_or` instead | -LL | let _ = Ok(1).unwrap_or(2); - | ~~~~~~~~~~~~ +LL - let _ = Ok(1).unwrap_or_else(|()| 2); +LL + let _ = Ok(1).unwrap_or(2); + | error: unnecessary closure used to substitute value for `Result::Err` --> tests/ui/unnecessary_lazy_eval_unfixable.rs:19:13 @@ -19,8 +20,9 @@ LL | let _ = Ok(1).unwrap_or_else(|e::E| 2); | help: use `unwrap_or` instead | -LL | let _ = Ok(1).unwrap_or(2); - | ~~~~~~~~~~~~ +LL - let _ = Ok(1).unwrap_or_else(|e::E| 2); +LL + let _ = Ok(1).unwrap_or(2); + | error: unnecessary closure used to substitute value for `Result::Err` --> tests/ui/unnecessary_lazy_eval_unfixable.rs:21:13 @@ -30,8 +32,9 @@ LL | let _ = Ok(1).unwrap_or_else(|SomeStruct { .. }| 2); | help: use `unwrap_or` instead | -LL | let _ = Ok(1).unwrap_or(2); - | ~~~~~~~~~~~~ +LL - let _ = Ok(1).unwrap_or_else(|SomeStruct { .. }| 2); +LL + let _ = Ok(1).unwrap_or(2); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval_unfixable.rs:31:13 @@ -41,8 +44,9 @@ LL | let _ = true.then(|| -> &[u8] { &[] }); | help: use `then_some` instead | -LL | let _ = true.then_some({ &[] }); - | ~~~~~~~~~~~~~~~~~~ +LL - let _ = true.then(|| -> &[u8] { &[] }); +LL + let _ = true.then_some({ &[] }); + | error: aborting due to 4 previous errors diff --git a/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.stderr b/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.stderr index 37ee9195fce..631bf083726 100644 --- a/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.stderr +++ b/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.stderr @@ -62,8 +62,9 @@ LL | let _val = None::<()>.expect("this always happens"); | help: remove the `None` and `expect()` | -LL | let _val = panic!("this always happens"); - | ~~~~~~~ +LL - let _val = None::<()>.expect("this always happens"); +LL + let _val = panic!("this always happens"); + | error: used `unwrap_or_default()` on `None` value --> tests/ui/unnecessary_literal_unwrap.rs:22:24 @@ -133,8 +134,9 @@ LL | None::<()>.expect("this always happens"); | help: remove the `None` and `expect()` | -LL | panic!("this always happens"); - | ~~~~~~~ +LL - None::<()>.expect("this always happens"); +LL + panic!("this always happens"); + | error: used `unwrap_or_default()` on `None` value --> tests/ui/unnecessary_literal_unwrap.rs:30:5 @@ -222,8 +224,9 @@ LL | let _val = Ok::<_, ()>(1).unwrap_err(); | help: remove the `Ok` and `unwrap_err()` | -LL | let _val = panic!("{:?}", 1); - | ~~~~~~~~~~~~~~ ~ +LL - let _val = Ok::<_, ()>(1).unwrap_err(); +LL + let _val = panic!("{:?}", 1); + | error: used `expect_err()` on `Ok` value --> tests/ui/unnecessary_literal_unwrap.rs:41:16 @@ -233,8 +236,9 @@ LL | let _val = Ok::<_, ()>(1).expect_err("this always happens"); | help: remove the `Ok` and `expect_err()` | -LL | let _val = panic!("{1}: {:?}", 1, "this always happens"); - | ~~~~~~~~~~~~~~~~~~~ ~ +LL - let _val = Ok::<_, ()>(1).expect_err("this always happens"); +LL + let _val = panic!("{1}: {:?}", 1, "this always happens"); + | error: used `unwrap()` on `Ok` value --> tests/ui/unnecessary_literal_unwrap.rs:43:5 @@ -268,8 +272,9 @@ LL | Ok::<_, ()>(1).unwrap_err(); | help: remove the `Ok` and `unwrap_err()` | -LL | panic!("{:?}", 1); - | ~~~~~~~~~~~~~~ ~ +LL - Ok::<_, ()>(1).unwrap_err(); +LL + panic!("{:?}", 1); + | error: used `expect_err()` on `Ok` value --> tests/ui/unnecessary_literal_unwrap.rs:46:5 @@ -279,8 +284,9 @@ LL | Ok::<_, ()>(1).expect_err("this always happens"); | help: remove the `Ok` and `expect_err()` | -LL | panic!("{1}: {:?}", 1, "this always happens"); - | ~~~~~~~~~~~~~~~~~~~ ~ +LL - Ok::<_, ()>(1).expect_err("this always happens"); +LL + panic!("{1}: {:?}", 1, "this always happens"); + | error: used `unwrap_err()` on `Err` value --> tests/ui/unnecessary_literal_unwrap.rs:50:16 @@ -314,8 +320,9 @@ LL | let _val = Err::<(), _>(1).unwrap(); | help: remove the `Err` and `unwrap()` | -LL | let _val = panic!("{:?}", 1); - | ~~~~~~~~~~~~~~ ~ +LL - let _val = Err::<(), _>(1).unwrap(); +LL + let _val = panic!("{:?}", 1); + | error: used `expect()` on `Err` value --> tests/ui/unnecessary_literal_unwrap.rs:53:16 @@ -325,8 +332,9 @@ LL | let _val = Err::<(), _>(1).expect("this always happens"); | help: remove the `Err` and `expect()` | -LL | let _val = panic!("{1}: {:?}", 1, "this always happens"); - | ~~~~~~~~~~~~~~~~~~~ ~ +LL - let _val = Err::<(), _>(1).expect("this always happens"); +LL + let _val = panic!("{1}: {:?}", 1, "this always happens"); + | error: used `unwrap_err()` on `Err` value --> tests/ui/unnecessary_literal_unwrap.rs:55:5 @@ -360,8 +368,9 @@ LL | Err::<(), _>(1).unwrap(); | help: remove the `Err` and `unwrap()` | -LL | panic!("{:?}", 1); - | ~~~~~~~~~~~~~~ ~ +LL - Err::<(), _>(1).unwrap(); +LL + panic!("{:?}", 1); + | error: used `expect()` on `Err` value --> tests/ui/unnecessary_literal_unwrap.rs:58:5 @@ -371,8 +380,9 @@ LL | Err::<(), _>(1).expect("this always happens"); | help: remove the `Err` and `expect()` | -LL | panic!("{1}: {:?}", 1, "this always happens"); - | ~~~~~~~~~~~~~~~~~~~ ~ +LL - Err::<(), _>(1).expect("this always happens"); +LL + panic!("{1}: {:?}", 1, "this always happens"); + | error: used `unwrap_or()` on `Some` value --> tests/ui/unnecessary_literal_unwrap.rs:62:16 diff --git a/src/tools/clippy/tests/ui/unnecessary_map_or.stderr b/src/tools/clippy/tests/ui/unnecessary_map_or.stderr index 2ae327f0bf8..9f38b8c8d93 100644 --- a/src/tools/clippy/tests/ui/unnecessary_map_or.stderr +++ b/src/tools/clippy/tests/ui/unnecessary_map_or.stderr @@ -8,8 +8,9 @@ LL | let _ = Some(5).map_or(false, |n| n == 5); = help: to override `-D warnings` add `#[allow(clippy::unnecessary_map_or)]` help: use a standard comparison instead | -LL | let _ = Some(5) == Some(5); - | ~~~~~~~~~~~~~~~~~~ +LL - let _ = Some(5).map_or(false, |n| n == 5); +LL + let _ = Some(5) == Some(5); + | error: this `map_or` can be simplified --> tests/ui/unnecessary_map_or.rs:14:13 @@ -19,8 +20,9 @@ LL | let _ = Some(5).map_or(true, |n| n != 5); | help: use a standard comparison instead | -LL | let _ = Some(5) != Some(5); - | ~~~~~~~~~~~~~~~~~~ +LL - let _ = Some(5).map_or(true, |n| n != 5); +LL + let _ = Some(5) != Some(5); + | error: this `map_or` can be simplified --> tests/ui/unnecessary_map_or.rs:15:13 @@ -34,8 +36,12 @@ LL | | }); | help: use a standard comparison instead | -LL | let _ = Some(5) == Some(5); - | ~~~~~~~~~~~~~~~~~~ +LL - let _ = Some(5).map_or(false, |n| { +LL - let _ = 1; +LL - n == 5 +LL - }); +LL + let _ = Some(5) == Some(5); + | error: this `map_or` can be simplified --> tests/ui/unnecessary_map_or.rs:19:13 @@ -121,8 +127,9 @@ LL | let _ = Ok::<i32, i32>(5).map_or(false, |n| n == 5); | help: use a standard comparison instead | -LL | let _ = Ok::<i32, i32>(5) == Ok(5); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _ = Ok::<i32, i32>(5).map_or(false, |n| n == 5); +LL + let _ = Ok::<i32, i32>(5) == Ok(5); + | error: this `map_or` can be simplified --> tests/ui/unnecessary_map_or.rs:29:13 @@ -132,8 +139,9 @@ LL | let _ = Some(5).map_or(false, |n| n == 5).then(|| 1); | help: use a standard comparison instead | -LL | let _ = (Some(5) == Some(5)).then(|| 1); - | ~~~~~~~~~~~~~~~~~~~~ +LL - let _ = Some(5).map_or(false, |n| n == 5).then(|| 1); +LL + let _ = (Some(5) == Some(5)).then(|| 1); + | error: this `map_or` can be simplified --> tests/ui/unnecessary_map_or.rs:30:13 @@ -167,8 +175,9 @@ LL | let _ = !Some(5).map_or(false, |n| n == 5); | help: use a standard comparison instead | -LL | let _ = !(Some(5) == Some(5)); - | ~~~~~~~~~~~~~~~~~~~~ +LL - let _ = !Some(5).map_or(false, |n| n == 5); +LL + let _ = !(Some(5) == Some(5)); + | error: this `map_or` can be simplified --> tests/ui/unnecessary_map_or.rs:33:13 @@ -178,8 +187,9 @@ LL | let _ = Some(5).map_or(false, |n| n == 5) || false; | help: use a standard comparison instead | -LL | let _ = (Some(5) == Some(5)) || false; - | ~~~~~~~~~~~~~~~~~~~~ +LL - let _ = Some(5).map_or(false, |n| n == 5) || false; +LL + let _ = (Some(5) == Some(5)) || false; + | error: this `map_or` can be simplified --> tests/ui/unnecessary_map_or.rs:34:13 @@ -189,8 +199,9 @@ LL | let _ = Some(5).map_or(false, |n| n == 5) as usize; | help: use a standard comparison instead | -LL | let _ = (Some(5) == Some(5)) as usize; - | ~~~~~~~~~~~~~~~~~~~~ +LL - let _ = Some(5).map_or(false, |n| n == 5) as usize; +LL + let _ = (Some(5) == Some(5)) as usize; + | error: this `map_or` can be simplified --> tests/ui/unnecessary_map_or.rs:58:13 @@ -248,8 +259,9 @@ LL | let _ = r.map_or(false, |x| x == 8); | help: use a standard comparison instead | -LL | let _ = r == Ok(8); - | ~~~~~~~~~~ +LL - let _ = r.map_or(false, |x| x == 8); +LL + let _ = r == Ok(8); + | error: this `map_or` can be simplified --> tests/ui/unnecessary_map_or.rs:90:5 diff --git a/src/tools/clippy/tests/ui/unnecessary_wraps.stderr b/src/tools/clippy/tests/ui/unnecessary_wraps.stderr index b304d4dce6e..b06ab91dc8d 100644 --- a/src/tools/clippy/tests/ui/unnecessary_wraps.stderr +++ b/src/tools/clippy/tests/ui/unnecessary_wraps.stderr @@ -13,8 +13,9 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::unnecessary_wraps)]` help: remove `Option` from the return type... | -LL | fn func1(a: bool, b: bool) -> i32 { - | ~~~ +LL - fn func1(a: bool, b: bool) -> Option<i32> { +LL + fn func1(a: bool, b: bool) -> i32 { + | help: ...and then change returning expressions | LL ~ return 42; @@ -40,8 +41,9 @@ LL | | } | help: remove `Option` from the return type... | -LL | fn func2(a: bool, b: bool) -> i32 { - | ~~~ +LL - fn func2(a: bool, b: bool) -> Option<i32> { +LL + fn func2(a: bool, b: bool) -> i32 { + | help: ...and then change returning expressions | LL ~ return 10; @@ -60,11 +62,13 @@ LL | | } | help: remove `Option` from the return type... | -LL | fn func5() -> i32 { - | ~~~ +LL - fn func5() -> Option<i32> { +LL + fn func5() -> i32 { + | help: ...and then change returning expressions | -LL | 1 +LL - Some(1) +LL + 1 | error: this function's return value is unnecessarily wrapped by `Result` @@ -78,11 +82,13 @@ LL | | } | help: remove `Result` from the return type... | -LL | fn func7() -> i32 { - | ~~~ +LL - fn func7() -> Result<i32, ()> { +LL + fn func7() -> i32 { + | help: ...and then change returning expressions | -LL | 1 +LL - Ok(1) +LL + 1 | error: this function's return value is unnecessarily wrapped by `Option` @@ -96,11 +102,13 @@ LL | | } | help: remove `Option` from the return type... | -LL | fn func12() -> i32 { - | ~~~ +LL - fn func12() -> Option<i32> { +LL + fn func12() -> i32 { + | help: ...and then change returning expressions | -LL | 1 +LL - Some(1) +LL + 1 | error: this function's return value is unnecessary @@ -116,8 +124,9 @@ LL | | } | help: remove the return type... | -LL | fn issue_6640_1(a: bool, b: bool) -> () { - | ~~ +LL - fn issue_6640_1(a: bool, b: bool) -> Option<()> { +LL + fn issue_6640_1(a: bool, b: bool) -> () { + | help: ...and then remove returned values | LL ~ return ; @@ -142,8 +151,9 @@ LL | | } | help: remove the return type... | -LL | fn issue_6640_2(a: bool, b: bool) -> () { - | ~~ +LL - fn issue_6640_2(a: bool, b: bool) -> Result<(), i32> { +LL + fn issue_6640_2(a: bool, b: bool) -> () { + | help: ...and then remove returned values | LL ~ return ; diff --git a/src/tools/clippy/tests/ui/unnested_or_patterns.stderr b/src/tools/clippy/tests/ui/unnested_or_patterns.stderr index bd15ef62368..4325df14304 100644 --- a/src/tools/clippy/tests/ui/unnested_or_patterns.stderr +++ b/src/tools/clippy/tests/ui/unnested_or_patterns.stderr @@ -8,8 +8,9 @@ LL | if let box 0 | box 2 = Box::new(0) {} = help: to override `-D warnings` add `#[allow(clippy::unnested_or_patterns)]` help: nest the patterns | -LL | if let box (0 | 2) = Box::new(0) {} - | ~~~~~~~~~~~ +LL - if let box 0 | box 2 = Box::new(0) {} +LL + if let box (0 | 2) = Box::new(0) {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns.rs:17:12 @@ -19,8 +20,9 @@ LL | if let box ((0 | 1)) | box (2 | 3) | box 4 = Box::new(0) {} | help: nest the patterns | -LL | if let box (0 | 1 | 2 | 3 | 4) = Box::new(0) {} - | ~~~~~~~~~~~~~~~~~~~~~~~ +LL - if let box ((0 | 1)) | box (2 | 3) | box 4 = Box::new(0) {} +LL + if let box (0 | 1 | 2 | 3 | 4) = Box::new(0) {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns.rs:19:12 @@ -30,8 +32,9 @@ LL | if let Some(1) | C0 | Some(2) = None {} | help: nest the patterns | -LL | if let Some(1 | 2) | C0 = None {} - | ~~~~~~~~~~~~~~~~ +LL - if let Some(1) | C0 | Some(2) = None {} +LL + if let Some(1 | 2) | C0 = None {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns.rs:20:12 @@ -41,8 +44,9 @@ LL | if let &mut 0 | &mut 2 = &mut 0 {} | help: nest the patterns | -LL | if let &mut (0 | 2) = &mut 0 {} - | ~~~~~~~~~~~~ +LL - if let &mut 0 | &mut 2 = &mut 0 {} +LL + if let &mut (0 | 2) = &mut 0 {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns.rs:21:12 @@ -52,8 +56,9 @@ LL | if let x @ 0 | x @ 2 = 0 {} | help: nest the patterns | -LL | if let x @ (0 | 2) = 0 {} - | ~~~~~~~~~~~ +LL - if let x @ 0 | x @ 2 = 0 {} +LL + if let x @ (0 | 2) = 0 {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns.rs:22:12 @@ -63,8 +68,9 @@ LL | if let (0, 1) | (0, 2) | (0, 3) = (0, 0) {} | help: nest the patterns | -LL | if let (0, 1 | 2 | 3) = (0, 0) {} - | ~~~~~~~~~~~~~~ +LL - if let (0, 1) | (0, 2) | (0, 3) = (0, 0) {} +LL + if let (0, 1 | 2 | 3) = (0, 0) {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns.rs:23:12 @@ -74,8 +80,9 @@ LL | if let (1, 0) | (2, 0) | (3, 0) = (0, 0) {} | help: nest the patterns | -LL | if let (1 | 2 | 3, 0) = (0, 0) {} - | ~~~~~~~~~~~~~~ +LL - if let (1, 0) | (2, 0) | (3, 0) = (0, 0) {} +LL + if let (1 | 2 | 3, 0) = (0, 0) {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns.rs:24:12 @@ -85,8 +92,9 @@ LL | if let (x, ..) | (x, 1) | (x, 2) = (0, 1) {} | help: nest the patterns | -LL | if let (x, ..) | (x, 1 | 2) = (0, 1) {} - | ~~~~~~~~~~~~~~~~~~~~ +LL - if let (x, ..) | (x, 1) | (x, 2) = (0, 1) {} +LL + if let (x, ..) | (x, 1 | 2) = (0, 1) {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns.rs:25:12 @@ -96,8 +104,9 @@ LL | if let [0] | [1] = [0] {} | help: nest the patterns | -LL | if let [0 | 1] = [0] {} - | ~~~~~~~ +LL - if let [0] | [1] = [0] {} +LL + if let [0 | 1] = [0] {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns.rs:26:12 @@ -107,8 +116,9 @@ LL | if let [x, 0] | [x, 1] = [0, 1] {} | help: nest the patterns | -LL | if let [x, 0 | 1] = [0, 1] {} - | ~~~~~~~~~~ +LL - if let [x, 0] | [x, 1] = [0, 1] {} +LL + if let [x, 0 | 1] = [0, 1] {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns.rs:27:12 @@ -118,8 +128,9 @@ LL | if let [x, 0] | [x, 1] | [x, 2] = [0, 1] {} | help: nest the patterns | -LL | if let [x, 0 | 1 | 2] = [0, 1] {} - | ~~~~~~~~~~~~~~ +LL - if let [x, 0] | [x, 1] | [x, 2] = [0, 1] {} +LL + if let [x, 0 | 1 | 2] = [0, 1] {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns.rs:28:12 @@ -129,8 +140,9 @@ LL | if let [x, ..] | [x, 1] | [x, 2] = [0, 1] {} | help: nest the patterns | -LL | if let [x, ..] | [x, 1 | 2] = [0, 1] {} - | ~~~~~~~~~~~~~~~~~~~~ +LL - if let [x, ..] | [x, 1] | [x, 2] = [0, 1] {} +LL + if let [x, ..] | [x, 1 | 2] = [0, 1] {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns.rs:30:12 @@ -140,8 +152,9 @@ LL | if let TS(0, x) | TS(1, x) = TS(0, 0) {} | help: nest the patterns | -LL | if let TS(0 | 1, x) = TS(0, 0) {} - | ~~~~~~~~~~~~ +LL - if let TS(0, x) | TS(1, x) = TS(0, 0) {} +LL + if let TS(0 | 1, x) = TS(0, 0) {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns.rs:31:12 @@ -151,8 +164,9 @@ LL | if let TS(1, 0) | TS(2, 0) | TS(3, 0) = TS(0, 0) {} | help: nest the patterns | -LL | if let TS(1 | 2 | 3, 0) = TS(0, 0) {} - | ~~~~~~~~~~~~~~~~ +LL - if let TS(1, 0) | TS(2, 0) | TS(3, 0) = TS(0, 0) {} +LL + if let TS(1 | 2 | 3, 0) = TS(0, 0) {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns.rs:32:12 @@ -162,8 +176,9 @@ LL | if let TS(x, ..) | TS(x, 1) | TS(x, 2) = TS(0, 0) {} | help: nest the patterns | -LL | if let TS(x, ..) | TS(x, 1 | 2) = TS(0, 0) {} - | ~~~~~~~~~~~~~~~~~~~~~~~~ +LL - if let TS(x, ..) | TS(x, 1) | TS(x, 2) = TS(0, 0) {} +LL + if let TS(x, ..) | TS(x, 1 | 2) = TS(0, 0) {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns.rs:37:12 @@ -173,8 +188,9 @@ LL | if let S { x: 0, y } | S { y, x: 1 } = (S { x: 0, y: 1 }) {} | help: nest the patterns | -LL | if let S { x: 0 | 1, y } = (S { x: 0, y: 1 }) {} - | ~~~~~~~~~~~~~~~~~ +LL - if let S { x: 0, y } | S { y, x: 1 } = (S { x: 0, y: 1 }) {} +LL + if let S { x: 0 | 1, y } = (S { x: 0, y: 1 }) {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns.rs:48:12 @@ -184,8 +200,9 @@ LL | if let [1] | [53] = [0] {} | help: nest the patterns | -LL | if let [1 | 53] = [0] {} - | ~~~~~~~~ +LL - if let [1] | [53] = [0] {} +LL + if let [1 | 53] = [0] {} + | error: aborting due to 17 previous errors diff --git a/src/tools/clippy/tests/ui/unnested_or_patterns2.stderr b/src/tools/clippy/tests/ui/unnested_or_patterns2.stderr index 54f03937508..3d8968551b9 100644 --- a/src/tools/clippy/tests/ui/unnested_or_patterns2.stderr +++ b/src/tools/clippy/tests/ui/unnested_or_patterns2.stderr @@ -8,8 +8,9 @@ LL | if let Some(Some(0)) | Some(Some(1)) = None {} = help: to override `-D warnings` add `#[allow(clippy::unnested_or_patterns)]` help: nest the patterns | -LL | if let Some(Some(0 | 1)) = None {} - | ~~~~~~~~~~~~~~~~~ +LL - if let Some(Some(0)) | Some(Some(1)) = None {} +LL + if let Some(Some(0 | 1)) = None {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns2.rs:13:12 @@ -19,8 +20,9 @@ LL | if let Some(Some(0)) | Some(Some(1) | Some(2)) = None {} | help: nest the patterns | -LL | if let Some(Some(0 | 1 | 2)) = None {} - | ~~~~~~~~~~~~~~~~~~~~~ +LL - if let Some(Some(0)) | Some(Some(1) | Some(2)) = None {} +LL + if let Some(Some(0 | 1 | 2)) = None {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns2.rs:14:12 @@ -30,8 +32,9 @@ LL | if let Some(Some(0 | 1) | Some(2)) | Some(Some(3) | Some(4)) = None {} | help: nest the patterns | -LL | if let Some(Some(0 | 1 | 2 | 3 | 4)) = None {} - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - if let Some(Some(0 | 1) | Some(2)) | Some(Some(3) | Some(4)) = None {} +LL + if let Some(Some(0 | 1 | 2 | 3 | 4)) = None {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns2.rs:15:12 @@ -41,8 +44,9 @@ LL | if let Some(Some(0) | Some(1 | 2)) = None {} | help: nest the patterns | -LL | if let Some(Some(0 | 1 | 2)) = None {} - | ~~~~~~~~~~~~~~~~~~~~~ +LL - if let Some(Some(0) | Some(1 | 2)) = None {} +LL + if let Some(Some(0 | 1 | 2)) = None {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns2.rs:16:12 @@ -52,8 +56,9 @@ LL | if let ((0,),) | ((1,) | (2,),) = ((0,),) {} | help: nest the patterns | -LL | if let ((0 | 1 | 2,),) = ((0,),) {} - | ~~~~~~~~~~~~~~~ +LL - if let ((0,),) | ((1,) | (2,),) = ((0,),) {} +LL + if let ((0 | 1 | 2,),) = ((0,),) {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns2.rs:17:12 @@ -63,8 +68,9 @@ LL | if let 0 | (1 | 2) = 0 {} | help: nest the patterns | -LL | if let 0 | 1 | 2 = 0 {} - | ~~~~~~~~~ +LL - if let 0 | (1 | 2) = 0 {} +LL + if let 0 | 1 | 2 = 0 {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns2.rs:18:12 @@ -74,8 +80,9 @@ LL | if let box (0 | 1) | (box 2 | box (3 | 4)) = Box::new(0) {} | help: nest the patterns | -LL | if let box (0 | 1 | 2 | 3 | 4) = Box::new(0) {} - | ~~~~~~~~~~~~~~~~~~~~~~~ +LL - if let box (0 | 1) | (box 2 | box (3 | 4)) = Box::new(0) {} +LL + if let box (0 | 1 | 2 | 3 | 4) = Box::new(0) {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns2.rs:19:12 @@ -85,8 +92,9 @@ LL | if let box box 0 | box (box 2 | box 4) = Box::new(Box::new(0)) {} | help: nest the patterns | -LL | if let box box (0 | 2 | 4) = Box::new(Box::new(0)) {} - | ~~~~~~~~~~~~~~~~~~~ +LL - if let box box 0 | box (box 2 | box 4) = Box::new(Box::new(0)) {} +LL + if let box box (0 | 2 | 4) = Box::new(Box::new(0)) {} + | error: aborting due to 8 previous errors diff --git a/src/tools/clippy/tests/ui/unused_enumerate_index.stderr b/src/tools/clippy/tests/ui/unused_enumerate_index.stderr index 6ec07dcbff0..02d65f06430 100644 --- a/src/tools/clippy/tests/ui/unused_enumerate_index.stderr +++ b/src/tools/clippy/tests/ui/unused_enumerate_index.stderr @@ -8,8 +8,9 @@ LL | for (_, x) in v.iter().enumerate() { = help: to override `-D warnings` add `#[allow(clippy::unused_enumerate_index)]` help: remove the `.enumerate()` call | -LL | for x in v.iter() { - | ~ ~~~~~~~~ +LL - for (_, x) in v.iter().enumerate() { +LL + for x in v.iter() { + | error: you seem to use `.enumerate()` and immediately discard the index --> tests/ui/unused_enumerate_index.rs:59:19 @@ -19,8 +20,9 @@ LL | for (_, x) in dummy.enumerate() { | help: remove the `.enumerate()` call | -LL | for x in dummy { - | ~ ~~~~~ +LL - for (_, x) in dummy.enumerate() { +LL + for x in dummy { + | error: you seem to use `.enumerate()` and immediately discard the index --> tests/ui/unused_enumerate_index.rs:63:39 diff --git a/src/tools/clippy/tests/ui/unused_format_specs.stderr b/src/tools/clippy/tests/ui/unused_format_specs.stderr index df61d59130e..d3c0530ced4 100644 --- a/src/tools/clippy/tests/ui/unused_format_specs.stderr +++ b/src/tools/clippy/tests/ui/unused_format_specs.stderr @@ -8,8 +8,9 @@ LL | println!("{:5}.", format_args!("")); = help: to override `-D warnings` add `#[allow(clippy::unused_format_specs)]` help: for the width to apply consider using `format!()` | -LL | println!("{:5}.", format!("")); - | ~~~~~~ +LL - println!("{:5}.", format_args!("")); +LL + println!("{:5}.", format!("")); + | help: if the current behavior is intentional, remove the format specifiers | LL - println!("{:5}.", format_args!("")); @@ -24,8 +25,9 @@ LL | println!("{:.3}", format_args!("abcde")); | help: for the precision to apply consider using `format!()` | -LL | println!("{:.3}", format!("abcde")); - | ~~~~~~ +LL - println!("{:.3}", format_args!("abcde")); +LL + println!("{:.3}", format!("abcde")); + | help: if the current behavior is intentional, remove the format specifiers | LL - println!("{:.3}", format_args!("abcde")); @@ -66,8 +68,9 @@ LL | usr_println!(true, "{:5}.", format_args!("")); | help: for the width to apply consider using `format!()` | -LL | usr_println!(true, "{:5}.", format!("")); - | ~~~~~~ +LL - usr_println!(true, "{:5}.", format_args!("")); +LL + usr_println!(true, "{:5}.", format!("")); + | help: if the current behavior is intentional, remove the format specifiers | LL - usr_println!(true, "{:5}.", format_args!("")); @@ -82,8 +85,9 @@ LL | usr_println!(true, "{:.3}", format_args!("abcde")); | help: for the precision to apply consider using `format!()` | -LL | usr_println!(true, "{:.3}", format!("abcde")); - | ~~~~~~ +LL - usr_println!(true, "{:.3}", format_args!("abcde")); +LL + usr_println!(true, "{:.3}", format!("abcde")); + | help: if the current behavior is intentional, remove the format specifiers | LL - usr_println!(true, "{:.3}", format_args!("abcde")); diff --git a/src/tools/clippy/tests/ui/unused_result_ok.stderr b/src/tools/clippy/tests/ui/unused_result_ok.stderr index 241e0c71261..024aafa6bbb 100644 --- a/src/tools/clippy/tests/ui/unused_result_ok.stderr +++ b/src/tools/clippy/tests/ui/unused_result_ok.stderr @@ -8,8 +8,9 @@ LL | x.parse::<u32>().ok(); = help: to override `-D warnings` add `#[allow(clippy::unused_result_ok)]` help: consider using `let _ =` and removing the call to `.ok()` instead | -LL | let _ = x.parse::<u32>(); - | ~~~~~~~~~~~~~~~~~~~~~~~~ +LL - x.parse::<u32>().ok(); +LL + let _ = x.parse::<u32>(); + | error: ignoring a result with `.ok()` is misleading --> tests/ui/unused_result_ok.rs:18:5 @@ -19,8 +20,9 @@ LL | x . parse::<i32>() . ok (); | help: consider using `let _ =` and removing the call to `.ok()` instead | -LL | let _ = x . parse::<i32>(); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - x . parse::<i32>() . ok (); +LL + let _ = x . parse::<i32>(); + | error: ignoring a result with `.ok()` is misleading --> tests/ui/unused_result_ok.rs:34:5 @@ -30,8 +32,9 @@ LL | v!().ok(); | help: consider using `let _ =` and removing the call to `.ok()` instead | -LL | let _ = v!(); - | ~~~~~~~~~~~~ +LL - v!().ok(); +LL + let _ = v!(); + | error: ignoring a result with `.ok()` is misleading --> tests/ui/unused_result_ok.rs:29:9 @@ -45,8 +48,9 @@ LL | w!(); = note: this error originates in the macro `w` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider using `let _ =` and removing the call to `.ok()` instead | -LL | let _ = Ok::<(), ()>(()); - | ~~~~~~~~~~~~~~~~~~~~~~~~ +LL - Ok::<(), ()>(()).ok(); +LL + let _ = Ok::<(), ()>(()); + | error: aborting due to 4 previous errors diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 00821fc9f9d..1614c35cb1c 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -224,7 +224,9 @@ pub struct Config { /// The directory containing the compiler sysroot pub sysroot_base: PathBuf, - /// The name of the stage being built (stage1, etc) + /// The number of the stage under test. + pub stage: u32, + /// The id of the stage under test (stage1-xxx, etc). pub stage_id: String, /// The test mode, e.g. ui or debuginfo. @@ -515,6 +517,7 @@ pub struct TargetCfgs { pub all_abis: HashSet<String>, pub all_families: HashSet<String>, pub all_pointer_widths: HashSet<String>, + pub all_rustc_abis: HashSet<String>, } impl TargetCfgs { @@ -534,6 +537,9 @@ impl TargetCfgs { let mut all_abis = HashSet::new(); let mut all_families = HashSet::new(); let mut all_pointer_widths = HashSet::new(); + // NOTE: for distinction between `abi` and `rustc_abi`, see comment on + // `TargetCfg::rustc_abi`. + let mut all_rustc_abis = HashSet::new(); // If current target is not included in the `--print=all-target-specs-json` output, // we check whether it is a custom target from the user or a synthetic target from bootstrap. @@ -574,7 +580,9 @@ impl TargetCfgs { all_families.insert(family.clone()); } all_pointer_widths.insert(format!("{}bit", cfg.pointer_width)); - + if let Some(rustc_abi) = &cfg.rustc_abi { + all_rustc_abis.insert(rustc_abi.clone()); + } all_targets.insert(target.clone()); } @@ -588,6 +596,7 @@ impl TargetCfgs { all_abis, all_families, all_pointer_widths, + all_rustc_abis, } } @@ -674,6 +683,10 @@ pub struct TargetCfg { pub(crate) xray: bool, #[serde(default = "default_reloc_model")] pub(crate) relocation_model: String, + // NOTE: `rustc_abi` should not be confused with `abi`. `rustc_abi` was introduced in #137037 to + // make SSE2 *required* by the ABI (kind of a hack to make a target feature *required* via the + // target spec). + pub(crate) rustc_abi: Option<String>, // Not present in target cfg json output, additional derived information. #[serde(skip)] diff --git a/src/tools/compiletest/src/directive-list.rs b/src/tools/compiletest/src/directive-list.rs index a7ac875d0a3..8c909bcb195 100644 --- a/src/tools/compiletest/src/directive-list.rs +++ b/src/tools/compiletest/src/directive-list.rs @@ -87,6 +87,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "ignore-remote", "ignore-riscv64", "ignore-rustc-debug-assertions", + "ignore-rustc_abi-x86-sse2", "ignore-s390x", "ignore-sgx", "ignore-sparc64", @@ -198,6 +199,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "only-nvptx64", "only-powerpc", "only-riscv64", + "only-rustc_abi-x86-sse2", "only-s390x", "only-sparc", "only-sparc64", diff --git a/src/tools/compiletest/src/header/cfg.rs b/src/tools/compiletest/src/header/cfg.rs index 6e5ced17c20..72a3b9d85c8 100644 --- a/src/tools/compiletest/src/header/cfg.rs +++ b/src/tools/compiletest/src/header/cfg.rs @@ -192,7 +192,7 @@ fn parse_cfg_name_directive<'a>( message: "on big-endian targets", } condition! { - name: config.stage_id.split('-').next().unwrap(), + name: format!("stage{}", config.stage).as_str(), allowed_names: &["stage0", "stage1", "stage2"], message: "when the bootstrapping stage is {name}", } @@ -234,6 +234,14 @@ fn parse_cfg_name_directive<'a>( allowed_names: ["coverage-map", "coverage-run"], message: "when the test mode is {name}", } + condition! { + name: target_cfg.rustc_abi.as_ref().map(|abi| format!("rustc_abi-{abi}")).unwrap_or_default(), + allowed_names: ContainsPrefixed { + prefix: "rustc_abi-", + inner: target_cfgs.all_rustc_abis.clone(), + }, + message: "when the target `rustc_abi` is {name}", + } condition! { name: "dist", diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs index 023658a3dd4..55292c46bba 100644 --- a/src/tools/compiletest/src/header/tests.rs +++ b/src/tools/compiletest/src/header/tests.rs @@ -72,6 +72,7 @@ struct ConfigBuilder { channel: Option<String>, host: Option<String>, target: Option<String>, + stage: Option<u32>, stage_id: Option<String>, llvm_version: Option<String>, git_hash: bool, @@ -102,6 +103,11 @@ impl ConfigBuilder { self } + fn stage(&mut self, n: u32) -> &mut Self { + self.stage = Some(n); + self + } + fn stage_id(&mut self, s: &str) -> &mut Self { self.stage_id = Some(s.to_owned()); self @@ -156,6 +162,8 @@ impl ConfigBuilder { "--cxxflags=", "--llvm-components=", "--android-cross-path=", + "--stage", + &self.stage.unwrap_or(2).to_string(), "--stage-id", self.stage_id.as_deref().unwrap_or("stage2-x86_64-unknown-linux-gnu"), "--channel", @@ -388,7 +396,7 @@ fn std_debug_assertions() { #[test] fn stage() { - let config: Config = cfg().stage_id("stage1-x86_64-unknown-linux-gnu").build(); + let config: Config = cfg().stage(1).stage_id("stage1-x86_64-unknown-linux-gnu").build(); assert!(check_ignore(&config, "//@ ignore-stage1")); assert!(!check_ignore(&config, "//@ ignore-stage2")); @@ -881,3 +889,17 @@ fn test_needs_target_has_atomic() { assert!(!check_ignore(&config, "//@ needs-target-has-atomic: 8, ptr")); assert!(check_ignore(&config, "//@ needs-target-has-atomic: 8, ptr, 128")); } + +#[test] +// FIXME: this test will fail against stage 0 until #137037 changes reach beta. +#[cfg_attr(bootstrap, ignore)] +fn test_rustc_abi() { + let config = cfg().target("i686-unknown-linux-gnu").build(); + assert_eq!(config.target_cfg().rustc_abi, Some("x86-sse2".to_string())); + assert!(check_ignore(&config, "//@ ignore-rustc_abi-x86-sse2")); + assert!(!check_ignore(&config, "//@ only-rustc_abi-x86-sse2")); + let config = cfg().target("x86_64-unknown-linux-gnu").build(); + assert_eq!(config.target_cfg().rustc_abi, None); + assert!(!check_ignore(&config, "//@ ignore-rustc_abi-x86-sse2")); + assert!(check_ignore(&config, "//@ only-rustc_abi-x86-sse2")); +} diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index 27a046ba5bc..d0a83cab9cd 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -64,6 +64,7 @@ pub fn parse_config(args: Vec<String>) -> Config { .reqopt("", "src-base", "directory to scan for test files", "PATH") .reqopt("", "build-base", "directory to deposit test outputs", "PATH") .reqopt("", "sysroot-base", "directory containing the compiler sysroot", "PATH") + .reqopt("", "stage", "stage number under test", "N") .reqopt("", "stage-id", "the target-stage identifier", "stageN-TARGET") .reqopt( "", @@ -294,6 +295,11 @@ pub fn parse_config(args: Vec<String>) -> Config { panic!("`--nocapture` is deprecated; please use `--no-capture`"); } + let stage = match matches.opt_str("stage") { + Some(stage) => stage.parse::<u32>().expect("expected `--stage` to be an unsigned integer"), + None => panic!("`--stage` is required"), + }; + Config { bless: matches.opt_present("bless"), compile_lib_path: make_absolute(opt_path(matches, "compile-lib-path")), @@ -311,7 +317,10 @@ pub fn parse_config(args: Vec<String>) -> Config { src_base, build_base: opt_path(matches, "build-base"), sysroot_base: opt_path(matches, "sysroot-base"), + + stage, stage_id: matches.opt_str("stage-id").unwrap(), + mode, suite: matches.opt_str("suite").unwrap(), debugger: matches.opt_str("debugger").map(|debugger| { @@ -415,6 +424,7 @@ pub fn log_config(config: &Config) { logv(c, format!("rustdoc_path: {:?}", config.rustdoc_path)); logv(c, format!("src_base: {:?}", config.src_base.display())); logv(c, format!("build_base: {:?}", config.build_base.display())); + logv(c, format!("stage: {}", config.stage)); logv(c, format!("stage_id: {}", config.stage_id)); logv(c, format!("mode: {}", config.mode)); logv(c, format!("run_ignored: {}", config.run_ignored)); diff --git a/src/tools/compiletest/src/runtest/run_make.rs b/src/tools/compiletest/src/runtest/run_make.rs index 7ef16e4a966..16c46fc1339 100644 --- a/src/tools/compiletest/src/runtest/run_make.rs +++ b/src/tools/compiletest/src/runtest/run_make.rs @@ -239,30 +239,6 @@ impl TestCx<'_> { } } - // `self.config.stage_id` looks like `stage1-<target_triple>`, but we only want - // the `stage1` part as that is what the output directories of bootstrap are prefixed with. - // Note that this *assumes* build layout from bootstrap is produced as: - // - // ``` - // build/<target_triple>/ // <- this is `build_root` - // ├── stage0 - // ├── stage0-bootstrap-tools - // ├── stage0-codegen - // ├── stage0-rustc - // ├── stage0-std - // ├── stage0-sysroot - // ├── stage0-tools - // ├── stage0-tools-bin - // ├── stage1 - // ├── stage1-std - // ├── stage1-tools - // ├── stage1-tools-bin - // └── test - // ``` - // FIXME(jieyouxu): improve the communication between bootstrap and compiletest here so - // we don't have to hack out a `stageN`. - let stage = self.config.stage_id.split('-').next().unwrap(); - // In order to link in the support library as a rlib when compiling recipes, we need three // paths: // 1. Path of the built support library rlib itself. @@ -284,10 +260,12 @@ impl TestCx<'_> { // support lib and its deps are organized, can't we copy them to the tools-bin dir as // well?), but this seems to work for now. - let stage_tools_bin = build_root.join(format!("{stage}-tools-bin")); + let stage_number = self.config.stage; + + let stage_tools_bin = build_root.join(format!("stage{stage_number}-tools-bin")); let support_lib_path = stage_tools_bin.join("librun_make_support.rlib"); - let stage_tools = build_root.join(format!("{stage}-tools")); + let stage_tools = build_root.join(format!("stage{stage_number}-tools")); let support_lib_deps = stage_tools.join(&self.config.host).join("release").join("deps"); let support_lib_deps_deps = stage_tools.join("release").join("deps"); @@ -368,7 +346,7 @@ impl TestCx<'_> { // provided through env vars. // Compute stage-specific standard library paths. - let stage_std_path = build_root.join(&stage).join("lib"); + let stage_std_path = build_root.join(format!("stage{stage_number}")).join("lib"); // Compute dynamic library search paths for recipes. let recipe_dylib_search_paths = { diff --git a/src/tools/enzyme b/src/tools/enzyme -Subproject 0e5fa4a3d475f4dece489c9e06b11164f83789f +Subproject 7f3b207c4413c9d715fd54b36b8a8fd3179e0b6 diff --git a/src/tools/generate-windows-sys/Cargo.toml b/src/tools/generate-windows-sys/Cargo.toml index 882d3d63525..f5c0e56bb3c 100644 --- a/src/tools/generate-windows-sys/Cargo.toml +++ b/src/tools/generate-windows-sys/Cargo.toml @@ -4,4 +4,4 @@ version = "0.1.0" edition = "2021" [dependencies.windows-bindgen] -version = "0.58.0" +version = "0.59.0" diff --git a/src/tools/generate-windows-sys/src/main.rs b/src/tools/generate-windows-sys/src/main.rs index 6dbf29d957f..6bf47e84062 100644 --- a/src/tools/generate-windows-sys/src/main.rs +++ b/src/tools/generate-windows-sys/src/main.rs @@ -29,8 +29,7 @@ fn main() -> Result<(), Box<dyn Error>> { sort_bindings("bindings.txt")?; - let info = windows_bindgen::bindgen(["--etc", "bindings.txt"])?; - println!("{info}"); + windows_bindgen::bindgen(["--etc", "bindings.txt"]); let mut f = std::fs::File::options().append(true).open("windows_sys.rs")?; f.write_all(ARM32_SHIM.as_bytes())?; diff --git a/src/tools/miri/src/intrinsics/atomic.rs b/src/tools/miri/src/intrinsics/atomic.rs index 8507b0f49de..6d2a575ed76 100644 --- a/src/tools/miri/src/intrinsics/atomic.rs +++ b/src/tools/miri/src/intrinsics/atomic.rs @@ -189,7 +189,7 @@ trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> { let place = this.deref_pointer(place)?; let rhs = this.read_immediate(rhs)?; - if !place.layout.ty.is_integral() && !place.layout.ty.is_unsafe_ptr() { + if !place.layout.ty.is_integral() && !place.layout.ty.is_raw_ptr() { span_bug!( this.cur_span(), "atomic arithmetic operations only work on integer and raw pointer types", diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index a717d8ccf28..44e4f1a2932 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -2,6 +2,7 @@ #![feature(rustc_private)] #![feature(cell_update)] #![feature(float_gamma)] +#![feature(float_erf)] #![feature(map_try_insert)] #![feature(never_type)] #![feature(try_blocks)] diff --git a/src/tools/miri/src/operator.rs b/src/tools/miri/src/operator.rs index c588b6fc7f1..81f22b2d0b2 100644 --- a/src/tools/miri/src/operator.rs +++ b/src/tools/miri/src/operator.rs @@ -52,8 +52,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Some more operations are possible with atomics. // The return value always has the provenance of the *left* operand. Add | Sub | BitOr | BitAnd | BitXor => { - assert!(left.layout.ty.is_unsafe_ptr()); - assert!(right.layout.ty.is_unsafe_ptr()); + assert!(left.layout.ty.is_raw_ptr()); + assert!(right.layout.ty.is_raw_ptr()); let ptr = left.to_scalar().to_pointer(this)?; // We do the actual operation with usize-typed scalars. let left = ImmTy::from_uint(ptr.addr().bytes(), this.machine.layouts.usize); diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index 97bfb04f1f4..bedc1ebdc95 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -742,6 +742,8 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { | "log1pf" | "expm1f" | "tgammaf" + | "erff" + | "erfcf" => { let [f] = this.check_shim(abi, Conv::C , link_name, args)?; let f = this.read_scalar(f)?.to_f32()?; @@ -759,6 +761,8 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { "log1pf" => f_host.ln_1p(), "expm1f" => f_host.exp_m1(), "tgammaf" => f_host.gamma(), + "erff" => f_host.erf(), + "erfcf" => f_host.erfc(), _ => bug!(), }; let res = res.to_soft(); @@ -799,6 +803,8 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { | "log1p" | "expm1" | "tgamma" + | "erf" + | "erfc" => { let [f] = this.check_shim(abi, Conv::C , link_name, args)?; let f = this.read_scalar(f)?.to_f64()?; @@ -816,6 +822,8 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { "log1p" => f_host.ln_1p(), "expm1" => f_host.exp_m1(), "tgamma" => f_host.gamma(), + "erf" => f_host.erf(), + "erfc" => f_host.erfc(), _ => bug!(), }; let res = res.to_soft(); diff --git a/src/tools/miri/tests/fail/panic/panic_abort1.rs b/src/tools/miri/tests/fail/panic/panic_abort1.rs index 300bfa32ecb..7552c7b7e80 100644 --- a/src/tools/miri/tests/fail/panic/panic_abort1.rs +++ b/src/tools/miri/tests/fail/panic/panic_abort1.rs @@ -1,6 +1,6 @@ //@error-in-other-file: the program aborted execution //@normalize-stderr-test: "\| +\^+" -> "| ^" -//@normalize-stderr-test: "libc::abort\(\);|core::intrinsics::abort\(\);" -> "ABORT();" +//@normalize-stderr-test: "unsafe \{ libc::abort\(\); \}|core::intrinsics::abort\(\);" -> "ABORT();" //@compile-flags: -C panic=abort fn main() { diff --git a/src/tools/miri/tests/fail/panic/panic_abort2.rs b/src/tools/miri/tests/fail/panic/panic_abort2.rs index 5d691350577..624f9933545 100644 --- a/src/tools/miri/tests/fail/panic/panic_abort2.rs +++ b/src/tools/miri/tests/fail/panic/panic_abort2.rs @@ -1,6 +1,6 @@ //@error-in-other-file: the program aborted execution //@normalize-stderr-test: "\| +\^+" -> "| ^" -//@normalize-stderr-test: "libc::abort\(\);|core::intrinsics::abort\(\);" -> "ABORT();" +//@normalize-stderr-test: "unsafe \{ libc::abort\(\); \}|core::intrinsics::abort\(\);" -> "ABORT();" //@compile-flags: -C panic=abort fn main() { diff --git a/src/tools/miri/tests/fail/panic/panic_abort3.rs b/src/tools/miri/tests/fail/panic/panic_abort3.rs index 25afc315628..d1435b55946 100644 --- a/src/tools/miri/tests/fail/panic/panic_abort3.rs +++ b/src/tools/miri/tests/fail/panic/panic_abort3.rs @@ -1,6 +1,6 @@ //@error-in-other-file: the program aborted execution //@normalize-stderr-test: "\| +\^+" -> "| ^" -//@normalize-stderr-test: "libc::abort\(\);|core::intrinsics::abort\(\);" -> "ABORT();" +//@normalize-stderr-test: "unsafe \{ libc::abort\(\); \}|core::intrinsics::abort\(\);" -> "ABORT();" //@compile-flags: -C panic=abort fn main() { diff --git a/src/tools/miri/tests/fail/panic/panic_abort4.rs b/src/tools/miri/tests/fail/panic/panic_abort4.rs index 025b51a5cf5..54b9c9cbfdb 100644 --- a/src/tools/miri/tests/fail/panic/panic_abort4.rs +++ b/src/tools/miri/tests/fail/panic/panic_abort4.rs @@ -1,6 +1,6 @@ //@error-in-other-file: the program aborted execution //@normalize-stderr-test: "\| +\^+" -> "| ^" -//@normalize-stderr-test: "libc::abort\(\);|core::intrinsics::abort\(\);" -> "ABORT();" +//@normalize-stderr-test: "unsafe \{ libc::abort\(\); \}|core::intrinsics::abort\(\);" -> "ABORT();" //@compile-flags: -C panic=abort fn main() { diff --git a/src/tools/miri/tests/fail/ptr_swap_nonoverlapping.rs b/src/tools/miri/tests/fail/ptr_swap_nonoverlapping.rs new file mode 100644 index 00000000000..6f627c416b0 --- /dev/null +++ b/src/tools/miri/tests/fail/ptr_swap_nonoverlapping.rs @@ -0,0 +1,15 @@ +//! This is a regression test for <https://github.com/rust-lang/miri/issues/4188>: The precondition +//! check in `ptr::swap_nonoverlapping` was incorrectly disabled in Miri. +//@normalize-stderr-test: "unsafe \{ libc::abort\(\) \}|crate::intrinsics::abort\(\);" -> "ABORT();" +//@normalize-stderr-test: "\| +\^+" -> "| ^" +//@normalize-stderr-test: "\n +[0-9]+:[^\n]+" -> "" +//@normalize-stderr-test: "\n +at [^\n]+" -> "" +//@error-in-other-file: aborted execution + +fn main() { + let mut data = 0usize; + let ptr = std::ptr::addr_of_mut!(data); + unsafe { + std::ptr::swap_nonoverlapping(ptr, ptr, 1); + } +} diff --git a/src/tools/miri/tests/fail/ptr_swap_nonoverlapping.stderr b/src/tools/miri/tests/fail/ptr_swap_nonoverlapping.stderr new file mode 100644 index 00000000000..782303d5f3f --- /dev/null +++ b/src/tools/miri/tests/fail/ptr_swap_nonoverlapping.stderr @@ -0,0 +1,31 @@ + +thread 'main' panicked at RUSTLIB/core/src/panicking.rs:LL:CC: +unsafe precondition(s) violated: ptr::swap_nonoverlapping requires that both pointer arguments are aligned and non-null and the specified memory ranges do not overlap +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace +note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect +thread caused non-unwinding panic. aborting. +error: abnormal termination: the program aborted execution + --> RUSTLIB/std/src/sys/pal/PLATFORM/mod.rs:LL:CC + | +LL | ABORT(); + | ^ the program aborted execution + | + = note: BACKTRACE: + = note: inside `std::sys::pal::PLATFORM::abort_internal` at RUSTLIB/std/src/sys/pal/PLATFORM/mod.rs:LL:CC + = note: inside `std::panicking::rust_panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC + = note: inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::begin_panic_handler::{closure#0}}, !>` at RUSTLIB/std/src/sys/backtrace.rs:LL:CC + = note: inside `std::panicking::begin_panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC + = note: inside `core::panicking::panic_nounwind` at RUSTLIB/core/src/panicking.rs:LL:CC + = note: inside `std::ptr::swap_nonoverlapping::precondition_check` at RUSTLIB/core/src/ub_checks.rs:LL:CC + = note: inside `std::ptr::swap_nonoverlapping::<usize>` at RUSTLIB/core/src/ub_checks.rs:LL:CC +note: inside `main` + --> tests/fail/ptr_swap_nonoverlapping.rs:LL:CC + | +LL | std::ptr::swap_nonoverlapping(ptr, ptr, 1); + | ^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/pass/float.rs b/src/tools/miri/tests/pass/float.rs index 2f4f64b1aa8..51cafbb3f43 100644 --- a/src/tools/miri/tests/pass/float.rs +++ b/src/tools/miri/tests/pass/float.rs @@ -1,4 +1,5 @@ #![feature(stmt_expr_attributes)] +#![feature(float_erf)] #![feature(float_gamma)] #![feature(core_intrinsics)] #![feature(f128)] @@ -1076,6 +1077,11 @@ pub fn libm() { let (val, sign) = (-0.5f64).ln_gamma(); assert_approx_eq!(val, (2.0 * f64::consts::PI.sqrt()).ln()); assert_eq!(sign, -1); + + assert_approx_eq!(1.0f32.erf(), 0.84270079294971486934122063508260926f32); + assert_approx_eq!(1.0f64.erf(), 0.84270079294971486934122063508260926f64); + assert_approx_eq!(1.0f32.erfc(), 0.15729920705028513065877936491739074f32); + assert_approx_eq!(1.0f64.erfc(), 0.15729920705028513065877936491739074f64); } fn test_fast() { diff --git a/src/tools/miri/tests/pass/intrinsics/portable-simd.rs b/src/tools/miri/tests/pass/intrinsics/portable-simd.rs index 0d0d79098d5..b6c5522b3d2 100644 --- a/src/tools/miri/tests/pass/intrinsics/portable-simd.rs +++ b/src/tools/miri/tests/pass/intrinsics/portable-simd.rs @@ -299,27 +299,6 @@ fn simd_mask() { } } - // This used to cause an ICE. It exercises simd_select_bitmask with an array as input. - let bitmask = u8x4::from_array([0b00001101, 0, 0, 0]); - assert_eq!( - mask32x4::from_bitmask_vector(bitmask), - mask32x4::from_array([true, false, true, true]), - ); - let bitmask = u8x8::from_array([0b01000101, 0, 0, 0, 0, 0, 0, 0]); - assert_eq!( - mask32x8::from_bitmask_vector(bitmask), - mask32x8::from_array([true, false, true, false, false, false, true, false]), - ); - let bitmask = - u8x16::from_array([0b01000101, 0b11110000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); - assert_eq!( - mask32x16::from_bitmask_vector(bitmask), - mask32x16::from_array([ - true, false, true, false, false, false, true, false, false, false, false, false, true, - true, true, true, - ]), - ); - // Also directly call simd_select_bitmask, to test both kinds of argument types. unsafe { // These masks are exactly the results we got out above in the `simd_bitmask` tests. diff --git a/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-pause-without-sse2.stderr b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-pause-without-sse2.stderr new file mode 100644 index 00000000000..171bf0c82d5 --- /dev/null +++ b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-pause-without-sse2.stderr @@ -0,0 +1,5 @@ +warning: target feature `sse2` must be enabled to ensure that the ABI of the current target can be implemented correctly + | + = note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116344 <https://github.com/rust-lang/rust/issues/116344> + diff --git a/src/tools/run-make-support/src/external_deps/rustc.rs b/src/tools/run-make-support/src/external_deps/rustc.rs index 33dc57cbc07..fd4a20278ad 100644 --- a/src/tools/run-make-support/src/external_deps/rustc.rs +++ b/src/tools/run-make-support/src/external_deps/rustc.rs @@ -84,7 +84,7 @@ impl Rustc { self } - /// Specify default optimization level `-O` (alias for `-C opt-level=2`). + /// Specify default optimization level `-O` (alias for `-C opt-level=3`). pub fn opt(&mut self) -> &mut Self { self.cmd.arg("-O"); self diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs index 2b854310a15..3312da470c0 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs @@ -95,7 +95,7 @@ impl<'db> MatchCheckCtx<'db> { let place_validity = PlaceValidity::from_bool(known_valid_scrutinee.unwrap_or(true)); // Measured to take ~100ms on modern hardware. - let complexity_limit = Some(500000); + let complexity_limit = 500000; compute_match_usefulness(self, arms, scrut_ty, place_validity, complexity_limit) } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs index b490a31f68f..acd86b1f3ed 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs @@ -399,7 +399,7 @@ impl InferenceTable<'_> { // Check that the types which they point at are compatible. let from_raw = TyKind::Raw(to_mt, from_inner.clone()).intern(Interner); - // Although references and unsafe ptrs have the same + // Although references and raw ptrs have the same // representation, we still register an Adjust::DerefRef so that // regionck knows that the region for `a` must be valid here. if is_ref { diff --git a/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs b/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs index 14af22c3193..ed9d6c67501 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs @@ -9107,8 +9107,8 @@ The tracking issue for this feature is: [#27721] deny_since: None, }, Lint { - label: "pattern_complexity", - description: r##"# `pattern_complexity` + label: "pattern_complexity_limit", + description: r##"# `pattern_complexity_limit` This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. diff --git a/src/tools/rustfmt/src/patterns.rs b/src/tools/rustfmt/src/patterns.rs index 1d88726d945..bafed41e39f 100644 --- a/src/tools/rustfmt/src/patterns.rs +++ b/src/tools/rustfmt/src/patterns.rs @@ -75,12 +75,12 @@ fn is_short_pattern_inner(context: &RewriteContext<'_>, pat: &ast::Pat) -> bool } } -pub(crate) struct RangeOperand<'a> { - operand: &'a Option<ptr::P<ast::Expr>>, - pub(crate) span: Span, +pub(crate) struct RangeOperand<'a, T> { + pub operand: &'a Option<ptr::P<T>>, + pub span: Span, } -impl<'a> Rewrite for RangeOperand<'a> { +impl<'a, T: Rewrite> Rewrite for RangeOperand<'a, T> { fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> { self.rewrite_result(context, shape).ok() } @@ -259,40 +259,7 @@ impl Rewrite for Pat { } PatKind::Never => Err(RewriteError::Unknown), PatKind::Range(ref lhs, ref rhs, ref end_kind) => { - let infix = match end_kind.node { - RangeEnd::Included(RangeSyntax::DotDotDot) => "...", - RangeEnd::Included(RangeSyntax::DotDotEq) => "..=", - RangeEnd::Excluded => "..", - }; - let infix = if context.config.spaces_around_ranges() { - let lhs_spacing = match lhs { - None => "", - Some(_) => " ", - }; - let rhs_spacing = match rhs { - None => "", - Some(_) => " ", - }; - format!("{lhs_spacing}{infix}{rhs_spacing}") - } else { - infix.to_owned() - }; - let lspan = self.span.with_hi(end_kind.span.lo()); - let rspan = self.span.with_lo(end_kind.span.hi()); - rewrite_pair( - &RangeOperand { - operand: lhs, - span: lspan, - }, - &RangeOperand { - operand: rhs, - span: rspan, - }, - PairParts::infix(&infix), - context, - shape, - SeparatorPlace::Front, - ) + rewrite_range_pat(context, shape, lhs, rhs, end_kind, self.span) } PatKind::Ref(ref pat, mutability) => { let prefix = format!("&{}", format_mutability(mutability)); @@ -359,6 +326,50 @@ impl Rewrite for Pat { } } +pub fn rewrite_range_pat<T: Rewrite>( + context: &RewriteContext<'_>, + shape: Shape, + lhs: &Option<ptr::P<T>>, + rhs: &Option<ptr::P<T>>, + end_kind: &rustc_span::source_map::Spanned<RangeEnd>, + span: Span, +) -> RewriteResult { + let infix = match end_kind.node { + RangeEnd::Included(RangeSyntax::DotDotDot) => "...", + RangeEnd::Included(RangeSyntax::DotDotEq) => "..=", + RangeEnd::Excluded => "..", + }; + let infix = if context.config.spaces_around_ranges() { + let lhs_spacing = match lhs { + None => "", + Some(_) => " ", + }; + let rhs_spacing = match rhs { + None => "", + Some(_) => " ", + }; + format!("{lhs_spacing}{infix}{rhs_spacing}") + } else { + infix.to_owned() + }; + let lspan = span.with_hi(end_kind.span.lo()); + let rspan = span.with_lo(end_kind.span.hi()); + rewrite_pair( + &RangeOperand { + operand: lhs, + span: lspan, + }, + &RangeOperand { + operand: rhs, + span: rspan, + }, + PairParts::infix(&infix), + context, + shape, + SeparatorPlace::Front, + ) +} + fn rewrite_struct_pat( qself: &Option<ptr::P<ast::QSelf>>, path: &ast::Path, diff --git a/src/tools/rustfmt/src/spanned.rs b/src/tools/rustfmt/src/spanned.rs index 6b3e40b9115..e93eb53cd87 100644 --- a/src/tools/rustfmt/src/spanned.rs +++ b/src/tools/rustfmt/src/spanned.rs @@ -211,7 +211,7 @@ impl Spanned for ast::PreciseCapturingArg { } } -impl<'a> Spanned for RangeOperand<'a> { +impl<'a, T> Spanned for RangeOperand<'a, T> { fn span(&self) -> Span { self.span } diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs index f8b713117f4..0009490e86f 100644 --- a/src/tools/rustfmt/src/types.rs +++ b/src/tools/rustfmt/src/types.rs @@ -18,6 +18,7 @@ use crate::lists::{ use crate::macros::{MacroPosition, rewrite_macro}; use crate::overflow; use crate::pairs::{PairParts, rewrite_pair}; +use crate::patterns::rewrite_range_pat; use crate::rewrite::{Rewrite, RewriteContext, RewriteError, RewriteErrorExt, RewriteResult}; use crate::shape::Shape; use crate::source_map::SpanUtils; @@ -1045,6 +1046,21 @@ impl Rewrite for ast::Ty { } } +impl Rewrite for ast::TyPat { + fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> { + self.rewrite_result(context, shape).ok() + } + + fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult { + match self.kind { + ast::TyPatKind::Range(ref lhs, ref rhs, ref end_kind) => { + rewrite_range_pat(context, shape, lhs, rhs, end_kind, self.span) + } + ast::TyPatKind::Err(_) => Err(RewriteError::Unknown), + } + } +} + fn rewrite_bare_fn( bare_fn: &ast::BareFnTy, span: Span, diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index faa0db27b2b..e8e7dfe0d84 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -132,6 +132,7 @@ const EXCEPTIONS_CARGO: ExceptionList = &[ ("dunce", "CC0-1.0 OR MIT-0 OR Apache-2.0"), ("encoding_rs", "(Apache-2.0 OR MIT) AND BSD-3-Clause"), ("fiat-crypto", "MIT OR Apache-2.0 OR BSD-1-Clause"), + ("foldhash", "Zlib"), ("im-rc", "MPL-2.0+"), ("normalize-line-endings", "Apache-2.0"), ("openssl", "Apache-2.0"), @@ -285,7 +286,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "expect-test", "fallible-iterator", // dependency of `thorin` "fastrand", - "field-offset", "flate2", "fluent-bundle", "fluent-langneg", @@ -327,7 +327,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "measureme", "memchr", "memmap2", - "memoffset", "miniz_oxide", "nix", "nu-ansi-term", @@ -367,14 +366,12 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "rustc-rayon-core", "rustc-stable-hash", "rustc_apfloat", - "rustc_version", "rustix", "ruzstd", // via object in thorin-dwp "ryu", "scoped-tls", "scopeguard", "self_cell", - "semver", "serde", "serde_derive", "serde_json", @@ -480,6 +477,8 @@ const PERMITTED_STDLIB_DEPENDENCIES: &[&str] = &[ "memchr", "miniz_oxide", "object", + "proc-macro2", + "quote", "r-efi", "r-efi-alloc", "rand", @@ -487,6 +486,8 @@ const PERMITTED_STDLIB_DEPENDENCIES: &[&str] = &[ "rand_xorshift", "rustc-demangle", "shlex", + "syn", + "unicode-ident", "unicode-width", "unwinding", "wasi", @@ -500,6 +501,8 @@ const PERMITTED_STDLIB_DEPENDENCIES: &[&str] = &[ "windows_x86_64_gnu", "windows_x86_64_gnullvm", "windows_x86_64_msvc", + "zerocopy", + "zerocopy-derive", // tidy-alphabetical-end ]; diff --git a/src/version b/src/version index b7844a6ffdc..f6342716723 100644 --- a/src/version +++ b/src/version @@ -1 +1 @@ -1.86.0 +1.87.0 |
