diff options
Diffstat (limited to 'src')
266 files changed, 16817 insertions, 4299 deletions
diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index 71750022145..a86c20d46bd 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -246,6 +246,11 @@ v( "mips64el-unknown-linux-muslabi64 install directory", ) v( + "musl-root-powerpc64le", + "target.powerpc64le-unknown-linux-musl.musl-root", + "powerpc64le-unknown-linux-musl install directory", +) +v( "musl-root-riscv32gc", "target.riscv32gc-unknown-linux-musl.musl-root", "riscv32gc-unknown-linux-musl install directory", diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 0cacd6e4f37..6700f3ba680 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -523,6 +523,11 @@ pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, car let mut features = String::new(); + if stage != 0 && builder.config.default_codegen_backend(target).as_deref() == Some("cranelift") + { + features += "compiler-builtins-no-f16-f128 "; + } + if builder.no_std(target) == Some(true) { features += " compiler-builtins-mem"; if !target.starts_with("bpf") { @@ -1892,12 +1897,6 @@ impl Step for Assemble { }); } - let lld_install = if builder.config.lld_enabled { - Some(builder.ensure(llvm::Lld { target: target_compiler.host })) - } else { - None - }; - let stage = target_compiler.stage; let host = target_compiler.host; let (host_info, dir_name) = if build_compiler.host == host { @@ -1958,22 +1957,11 @@ impl Step for Assemble { copy_codegen_backends_to_sysroot(builder, build_compiler, target_compiler); - if let Some(lld_install) = lld_install { - let src_exe = exe("lld", target_compiler.host); - let dst_exe = exe("rust-lld", target_compiler.host); - builder.copy_link(&lld_install.join("bin").join(src_exe), &libdir_bin.join(dst_exe)); - let self_contained_lld_dir = libdir_bin.join("gcc-ld"); - t!(fs::create_dir_all(&self_contained_lld_dir)); - let lld_wrapper_exe = builder.ensure(crate::core::build_steps::tool::LldWrapper { - compiler: build_compiler, - target: target_compiler.host, + if builder.config.lld_enabled { + builder.ensure(crate::core::build_steps::tool::LldWrapper { + build_compiler, + target_compiler, }); - for name in crate::LLD_FILE_NAMES { - builder.copy_link( - &lld_wrapper_exe, - &self_contained_lld_dir.join(exe(name, target_compiler.host)), - ); - } } if builder.config.llvm_enabled(target_compiler.host) && builder.config.llvm_tools_enabled { diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index ffb7d9a9e0e..be5b4057051 100644 --- a/src/bootstrap/src/core/build_steps/llvm.rs +++ b/src/bootstrap/src/core/build_steps/llvm.rs @@ -217,6 +217,7 @@ pub(crate) fn is_ci_llvm_available(config: &Config, asserts: bool) -> bool { ("powerpc-unknown-linux-gnu", false), ("powerpc64-unknown-linux-gnu", false), ("powerpc64le-unknown-linux-gnu", false), + ("powerpc64le-unknown-linux-musl", false), ("riscv64gc-unknown-linux-gnu", false), ("s390x-unknown-linux-gnu", false), ("x86_64-unknown-freebsd", false), diff --git a/src/bootstrap/src/core/build_steps/setup.rs b/src/bootstrap/src/core/build_steps/setup.rs index 7ed01f25c94..fbd0dc3ec30 100644 --- a/src/bootstrap/src/core/build_steps/setup.rs +++ b/src/bootstrap/src/core/build_steps/setup.rs @@ -209,7 +209,7 @@ pub fn setup(config: &Config, profile: Profile) { setup_config_toml(path, profile, config); } -fn setup_config_toml(path: &PathBuf, profile: Profile, config: &Config) { +fn setup_config_toml(path: &Path, profile: Profile, config: &Config) { if profile == Profile::None { return; } diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 30fdea7e19e..8d9d2b6b6a1 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -2442,7 +2442,9 @@ impl Step for ErrorIndex { const ONLY_HOSTS: bool = true; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.path("src/tools/error_index_generator") + // Also add `error-index` here since that is what appears in the error message + // when this fails. + run.path("src/tools/error_index_generator").alias("error-index") } fn make_run(run: RunConfig<'_>) { diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 3cfbef27f87..04f1e10f493 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -1,8 +1,8 @@ use std::path::PathBuf; use std::{env, fs}; -use crate::core::build_steps::compile; use crate::core::build_steps::toolstate::ToolState; +use crate::core::build_steps::{compile, llvm}; use crate::core::builder; use crate::core::builder::{Builder, Cargo as CargoCommand, RunConfig, ShouldRun, Step}; use crate::core::config::TargetSelection; @@ -722,21 +722,27 @@ impl Step for Cargo { #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct LldWrapper { - pub compiler: Compiler, - pub target: TargetSelection, + pub build_compiler: Compiler, + pub target_compiler: Compiler, } impl Step for LldWrapper { - type Output = PathBuf; + type Output = (); fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { run.never() } - fn run(self, builder: &Builder<'_>) -> PathBuf { - builder.ensure(ToolBuild { - compiler: self.compiler, - target: self.target, + fn run(self, builder: &Builder<'_>) { + if builder.config.dry_run() { + return; + } + + let target = self.target_compiler.host; + + let executable = builder.ensure(ToolBuild { + compiler: self.build_compiler, + target, tool: "lld-wrapper", mode: Mode::ToolStd, path: "src/tools/lld-wrapper", @@ -744,7 +750,22 @@ impl Step for LldWrapper { extra_features: Vec::new(), allow_features: "", cargo_args: Vec::new(), - }) + }); + + let libdir_bin = builder.sysroot_target_bindir(self.target_compiler, target); + t!(fs::create_dir_all(&libdir_bin)); + + let lld_install = builder.ensure(llvm::Lld { target }); + let src_exe = exe("lld", target); + let dst_exe = exe("rust-lld", target); + + builder.copy_link(&lld_install.join("bin").join(src_exe), &libdir_bin.join(dst_exe)); + let self_contained_lld_dir = libdir_bin.join("gcc-ld"); + t!(fs::create_dir_all(&self_contained_lld_dir)); + + for name in crate::LLD_FILE_NAMES { + builder.copy_link(&executable, &self_contained_lld_dir.join(exe(name, target))); + } } } diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index 026c26479d3..98f765dbd0f 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -613,7 +613,9 @@ impl<'a> ShouldRun<'a> { self } - // single, non-aliased path + /// single, non-aliased path + /// + /// Must be an on-disk path; use `alias` for names that do not correspond to on-disk paths. pub fn path(self, path: &str) -> Self { self.paths(&[path]) } @@ -622,7 +624,7 @@ impl<'a> ShouldRun<'a> { /// /// This differs from [`path`] in that multiple calls to path will end up calling `make_run` /// multiple times, whereas a single call to `paths` will only ever generate a single call to - /// `paths`. + /// `make_run`. /// /// This is analogous to `all_krates`, although `all_krates` is gone now. Prefer [`path`] where possible. /// diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index b2ffbd9c70f..819a552093b 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -91,7 +91,7 @@ macro_rules! rustc { #[test] fn test_valid() { // make sure multi suite paths are accepted - check_cli(["test", "tests/ui/attr-start.rs", "tests/ui/attr-shebang.rs"]); + check_cli(["test", "tests/ui/bootstrap/self-test/a.rs", "tests/ui/bootstrap/self-test/b.rs"]); } #[test] diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 22d361ff091..435216ef534 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -1942,7 +1942,7 @@ impl Config { ); let channel = config - .read_file_by_commit(&PathBuf::from("src/ci/channel"), commit) + .read_file_by_commit(Path::new("src/ci/channel"), commit) .trim() .to_owned(); @@ -2383,12 +2383,10 @@ impl Config { /// Return the version it would have used for the given commit. pub(crate) fn artifact_version_part(&self, commit: &str) -> String { let (channel, version) = if self.rust_info.is_managed_git_subrepository() { - let channel = self - .read_file_by_commit(&PathBuf::from("src/ci/channel"), commit) - .trim() - .to_owned(); + let channel = + self.read_file_by_commit(Path::new("src/ci/channel"), commit).trim().to_owned(); let version = - self.read_file_by_commit(&PathBuf::from("src/version"), commit).trim().to_owned(); + self.read_file_by_commit(Path::new("src/version"), commit).trim().to_owned(); (channel, version) } else { let channel = fs::read_to_string(self.src.join("src/ci/channel")); diff --git a/src/bootstrap/src/utils/render_tests.rs b/src/bootstrap/src/utils/render_tests.rs index eb2c8254dc0..46b250555f2 100644 --- a/src/bootstrap/src/utils/render_tests.rs +++ b/src/bootstrap/src/utils/render_tests.rs @@ -242,7 +242,7 @@ impl<'a> Renderer<'a> { for bench in &self.benches { rows.push(( &bench.name, - format!("{:.2?}/iter", bench.median), + format!("{:.2?}ns/iter", bench.median), format!("+/- {:.2?}", bench.deviation), )); } diff --git a/src/ci/docker/host-aarch64/dist-arm-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-arm-linux/Dockerfile index 4a749473004..420c42bc9d8 100644 --- a/src/ci/docker/host-aarch64/dist-arm-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-arm-linux/Dockerfile @@ -19,7 +19,7 @@ RUN sh /scripts/rustbuild-setup.sh WORKDIR /tmp COPY scripts/crosstool-ng-build.sh /scripts/ -COPY host-aarch64/dist-arm-linux/arm-linux-gnueabi.defconfig /tmp/crosstool.defconfig +COPY host-x86_64/dist-arm-linux/arm-linux-gnueabi.defconfig /tmp/crosstool.defconfig RUN /scripts/crosstool-ng-build.sh COPY scripts/sccache.sh /scripts/ diff --git a/src/ci/docker/host-aarch64/dist-arm-linux/arm-linux-gnueabi.defconfig b/src/ci/docker/host-x86_64/dist-arm-linux/arm-linux-gnueabi.defconfig index e7afdbe9d4d..e7afdbe9d4d 100644 --- a/src/ci/docker/host-aarch64/dist-arm-linux/arm-linux-gnueabi.defconfig +++ b/src/ci/docker/host-x86_64/dist-arm-linux/arm-linux-gnueabi.defconfig 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 5dc282403be..9ef39189249 100644 --- a/src/ci/docker/host-x86_64/dist-powerpc64le-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-powerpc64le-linux/Dockerfile @@ -3,23 +3,46 @@ 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/rustbuild-setup.sh /scripts/ RUN sh /scripts/rustbuild-setup.sh + WORKDIR /tmp +COPY scripts/crosstool-ng-build.sh /scripts/ +COPY host-x86_64/dist-powerpc64le-linux/powerpc64le-unknown-linux-musl.defconfig /tmp/crosstool.defconfig +RUN /scripts/crosstool-ng-build.sh + +WORKDIR /build + RUN apt-get install -y --no-install-recommends rpm2cpio cpio -COPY host-x86_64/dist-powerpc64le-linux/shared.sh host-x86_64/dist-powerpc64le-linux/build-powerpc64le-toolchain.sh /tmp/ +COPY host-x86_64/dist-powerpc64le-linux/shared.sh host-x86_64/dist-powerpc64le-linux/build-powerpc64le-toolchain.sh /build/ RUN ./build-powerpc64le-toolchain.sh COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh +ENV PATH=$PATH:/x-tools/powerpc64le-unknown-linux-musl/bin + ENV \ AR_powerpc64le_unknown_linux_gnu=powerpc64le-linux-gnu-ar \ CC_powerpc64le_unknown_linux_gnu=powerpc64le-linux-gnu-gcc \ - CXX_powerpc64le_unknown_linux_gnu=powerpc64le-linux-gnu-g++ + CXX_powerpc64le_unknown_linux_gnu=powerpc64le-linux-gnu-g++ \ + AR_powerpc64le_unknown_linux_musl=powerpc64le-unknown-linux-musl-ar \ + CC_powerpc64le_unknown_linux_musl=powerpc64le-unknown-linux-musl-gcc \ + CXX_powerpc64le_unknown_linux_musl=powerpc64le-unknown-linux-musl-g++ + +ENV HOSTS=powerpc64le-unknown-linux-gnu,powerpc64le-unknown-linux-musl -ENV HOSTS=powerpc64le-unknown-linux-gnu +ENV RUST_CONFIGURE_ARGS \ + --enable-extended \ + --enable-full-tools \ + --enable-profiler \ + --enable-sanitizers \ + --disable-docs \ + --set target.powerpc64le-unknown-linux-musl.crt-static=false \ + --musl-root-powerpc64le=/x-tools/powerpc64le-unknown-linux-musl/powerpc64le-unknown-linux-musl/sysroot/usr -ENV RUST_CONFIGURE_ARGS --enable-extended --enable-profiler --disable-docs ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/ci/docker/host-x86_64/dist-powerpc64le-linux/powerpc64le-unknown-linux-musl.defconfig b/src/ci/docker/host-x86_64/dist-powerpc64le-linux/powerpc64le-unknown-linux-musl.defconfig new file mode 100644 index 00000000000..c6cde30b2a4 --- /dev/null +++ b/src/ci/docker/host-x86_64/dist-powerpc64le-linux/powerpc64le-unknown-linux-musl.defconfig @@ -0,0 +1,16 @@ +CT_CONFIG_VERSION="4" +CT_EXPERIMENTAL=y +CT_PREFIX_DIR="/x-tools/${CT_TARGET}" +CT_USE_MIRROR=y +CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc" +CT_ARCH_POWERPC=y +CT_ARCH_LE=y +CT_ARCH_64=y +# CT_DEMULTILIB is not set +CT_ARCH_ARCH="powerpc64le" +CT_KERNEL_LINUX=y +CT_LINUX_V_4_19=y +CT_LIBC_MUSL=y +CT_MUSL_V_1_2_3=y +CT_CC_LANG_CXX=y +CT_GETTEXT_NEEDED=y diff --git a/src/ci/docker/host-x86_64/i686-gnu-nopt/Dockerfile b/src/ci/docker/host-x86_64/i686-gnu-nopt/Dockerfile index e2736720607..241199d3baf 100644 --- a/src/ci/docker/host-x86_64/i686-gnu-nopt/Dockerfile +++ b/src/ci/docker/host-x86_64/i686-gnu-nopt/Dockerfile @@ -28,4 +28,6 @@ RUN echo "optimize = false" >> /config/nopt-std-config.toml ENV RUST_CONFIGURE_ARGS --build=i686-unknown-linux-gnu --disable-optimize-tests ARG SCRIPT_ARG -ENV SCRIPT=${SCRIPT_ARG} +COPY scripts/stage_2_test_set1.sh /scripts/ +COPY scripts/stage_2_test_set2.sh /scripts/ +ENV SCRIPT ${SCRIPT_ARG} diff --git a/src/ci/docker/host-x86_64/i686-gnu/Dockerfile b/src/ci/docker/host-x86_64/i686-gnu/Dockerfile index dec25461bb4..a715f7182d2 100644 --- a/src/ci/docker/host-x86_64/i686-gnu/Dockerfile +++ b/src/ci/docker/host-x86_64/i686-gnu/Dockerfile @@ -25,4 +25,6 @@ RUN sh /scripts/sccache.sh ENV RUST_CONFIGURE_ARGS --build=i686-unknown-linux-gnu ARG SCRIPT_ARG -ENV SCRIPT=${SCRIPT_ARG} +COPY scripts/stage_2_test_set1.sh /scripts/ +COPY scripts/stage_2_test_set2.sh /scripts/ +ENV SCRIPT /scripts/${SCRIPT_ARG} diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-18/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-18/Dockerfile index 487da580152..e157debfd09 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-18/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-18/Dockerfile @@ -59,5 +59,13 @@ COPY host-x86_64/dist-x86_64-linux/build-gccjit.sh /scripts/ RUN /scripts/build-gccjit.sh /scripts -COPY scripts/x86_64-gnu-llvm.sh /tmp/script.sh -ENV SCRIPT /tmp/script.sh +ARG SCRIPT_ARG + +COPY scripts/add_dummy_commit.sh /tmp/ +COPY scripts/x86_64-gnu-llvm.sh /tmp/ +COPY scripts/x86_64-gnu-llvm2.sh /tmp/ +COPY scripts/x86_64-gnu-llvm3.sh /tmp/ +COPY scripts/stage_2_test_set1.sh /tmp/ +COPY scripts/stage_2_test_set2.sh /tmp/ + +ENV SCRIPT "/tmp/add_dummy_commit.sh && /tmp/${SCRIPT_ARG}" diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-19/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-19/Dockerfile index 4991908fe77..e7016e7d3c0 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-19/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-19/Dockerfile @@ -59,5 +59,13 @@ COPY host-x86_64/dist-x86_64-linux/build-gccjit.sh /scripts/ RUN /scripts/build-gccjit.sh /scripts -COPY scripts/x86_64-gnu-llvm.sh /tmp/script.sh -ENV SCRIPT /tmp/script.sh +ARG SCRIPT_ARG + +COPY scripts/add_dummy_commit.sh /tmp/ +COPY scripts/x86_64-gnu-llvm.sh /tmp/ +COPY scripts/x86_64-gnu-llvm2.sh /tmp/ +COPY scripts/x86_64-gnu-llvm3.sh /tmp/ +COPY scripts/stage_2_test_set1.sh /tmp/ +COPY scripts/stage_2_test_set2.sh /tmp/ + +ENV SCRIPT "/tmp/add_dummy_commit.sh && /tmp/${SCRIPT_ARG}" diff --git a/src/ci/docker/scripts/add_dummy_commit.sh b/src/ci/docker/scripts/add_dummy_commit.sh new file mode 100755 index 00000000000..029e4ae141f --- /dev/null +++ b/src/ci/docker/scripts/add_dummy_commit.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +set -ex + +if [ "$READ_ONLY_SRC" = "0" ]; then + # `core::builder::tests::ci_rustc_if_unchanged_logic` bootstrap test ensures that + # "download-rustc=if-unchanged" logic don't use CI rustc while there are changes on + # compiler and/or library. Here we are adding a dummy commit on compiler and running + # that test to make sure we never download CI rustc with a change on the compiler tree. + echo "" >> ../compiler/rustc/src/main.rs + git config --global user.email "dummy@dummy.com" + git config --global user.name "dummy" + git add ../compiler/rustc/src/main.rs + git commit -m "test commit for rust.download-rustc=if-unchanged logic" + DISABLE_CI_RUSTC_IF_INCOMPATIBLE=0 ../x.py test bootstrap \ + -- core::builder::tests::ci_rustc_if_unchanged_logic + # Revert the dummy commit + git reset --hard HEAD~1 +fi diff --git a/src/ci/docker/scripts/build-fuchsia-toolchain.sh b/src/ci/docker/scripts/build-fuchsia-toolchain.sh index 027d412d250..3c65a52ada7 100755 --- a/src/ci/docker/scripts/build-fuchsia-toolchain.sh +++ b/src/ci/docker/scripts/build-fuchsia-toolchain.sh @@ -4,13 +4,13 @@ set -ex source shared.sh FUCHSIA_SDK_URL=https://chrome-infra-packages.appspot.com/dl/fuchsia/sdk/core/linux-amd64 -FUCHSIA_SDK_ID=version:21.20240610.2.1 -FUCHSIA_SDK_SHA256=2d2d057fc3f0404197cced2200f88cbcdaaf5fbf6475955045091f8676791ce7 +FUCHSIA_SDK_ID=version:26.20241211.7.1 +FUCHSIA_SDK_SHA256=2cb7a9a0419f7413a46e0ccef7dad89f7c9979940d7c1ee87fac70ff499757d6 FUCHSIA_SDK_USR_DIR=/usr/local/core-linux-amd64-fuchsia-sdk CLANG_DOWNLOAD_URL=\ https://chrome-infra-packages.appspot.com/dl/fuchsia/third_party/clang/linux-amd64 -CLANG_DOWNLOAD_ID=git_revision:3809e20afc68d7d03821f0ec59b928dcf9befbf4 -CLANG_DOWNLOAD_SHA256=3c2c442b61cd9e8f1b567738f6d53cffe11b3fc820e7dae87a82a0859be8f204 +CLANG_DOWNLOAD_ID=git_revision:388d7f144880dcd85ff31f06793304405a9f44b6 +CLANG_DOWNLOAD_SHA256=970d1f427b9c9a3049d8622c80c86830ff31b5334ad8da47a2f1e81143197e8b install_clang() { mkdir -p clang_download diff --git a/src/ci/docker/scripts/stage_2_test_set1.sh b/src/ci/docker/scripts/stage_2_test_set1.sh new file mode 100755 index 00000000000..3baff4b5221 --- /dev/null +++ b/src/ci/docker/scripts/stage_2_test_set1.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +set -ex + +# Run a subset of tests. Used to run tests in parallel in multiple jobs. + +../x.py --stage 2 test \ + --skip compiler \ + --skip src diff --git a/src/ci/docker/scripts/stage_2_test_set2.sh b/src/ci/docker/scripts/stage_2_test_set2.sh new file mode 100755 index 00000000000..872d758dce3 --- /dev/null +++ b/src/ci/docker/scripts/stage_2_test_set2.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +set -ex + +# Run a subset of tests. Used to run tests in parallel in multiple jobs. + +../x.py --stage 2 test \ + --skip tests \ + --skip coverage-map \ + --skip coverage-run \ + --skip library \ + --skip tidyselftest diff --git a/src/ci/docker/scripts/x86_64-gnu-llvm.sh b/src/ci/docker/scripts/x86_64-gnu-llvm.sh index dea38b6fd2a..e0435a3ff5c 100755 --- a/src/ci/docker/scripts/x86_64-gnu-llvm.sh +++ b/src/ci/docker/scripts/x86_64-gnu-llvm.sh @@ -2,43 +2,6 @@ set -ex -if [ "$READ_ONLY_SRC" = "0" ]; then - # `core::builder::tests::ci_rustc_if_unchanged_logic` bootstrap test ensures that - # "download-rustc=if-unchanged" logic don't use CI rustc while there are changes on - # compiler and/or library. Here we are adding a dummy commit on compiler and running - # that test to make sure we never download CI rustc with a change on the compiler tree. - echo "" >> ../compiler/rustc/src/main.rs - git config --global user.email "dummy@dummy.com" - git config --global user.name "dummy" - git add ../compiler/rustc/src/main.rs - git commit -m "test commit for rust.download-rustc=if-unchanged logic" - DISABLE_CI_RUSTC_IF_INCOMPATIBLE=0 ../x.py test bootstrap \ - -- core::builder::tests::ci_rustc_if_unchanged_logic - # Revert the dummy commit - git reset --hard HEAD~1 -fi - -# Only run the stage 1 tests on merges, not on PR CI jobs. -if [[ -z "${PR_CI_JOB}" ]]; then - ../x.py --stage 1 test --skip src/tools/tidy - - # Run the `mir-opt` tests again but this time for a 32-bit target. - # This enforces that tests using `// EMIT_MIR_FOR_EACH_BIT_WIDTH` have - # both 32-bit and 64-bit outputs updated by the PR author, before - # the PR is approved and tested for merging. - # It will also detect tests lacking `// EMIT_MIR_FOR_EACH_BIT_WIDTH`, - # despite having different output on 32-bit vs 64-bit targets. - ../x.py --stage 1 test tests/mir-opt --host='' --target=i686-unknown-linux-gnu - - # Run `ui-fulldeps` in `--stage=1`, which actually uses the stage0 - # compiler, and is sensitive to the addition of new flags. - ../x.py --stage 1 test tests/ui-fulldeps - - # Rebuild the stdlib with the size optimizations enabled and run tests again. - RUSTFLAGS_NOT_BOOTSTRAP="--cfg feature=\"optimize_for_size\"" ../x.py --stage 1 test \ - library/std library/alloc library/core -fi - # NOTE: intentionally uses all of `x.py`, `x`, and `x.ps1` to make sure they all work on Linux. ../x.py --stage 2 test --skip src/tools/tidy diff --git a/src/ci/docker/scripts/x86_64-gnu-llvm2.sh b/src/ci/docker/scripts/x86_64-gnu-llvm2.sh new file mode 100755 index 00000000000..fe5382aaa48 --- /dev/null +++ b/src/ci/docker/scripts/x86_64-gnu-llvm2.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +set -ex + +##### Test stage 2 ##### + +/tmp/stage_2_test_set1.sh + +# Run the `mir-opt` tests again but this time for a 32-bit target. +# This enforces that tests using `// EMIT_MIR_FOR_EACH_BIT_WIDTH` have +# both 32-bit and 64-bit outputs updated by the PR author, before +# the PR is approved and tested for merging. +# It will also detect tests lacking `// EMIT_MIR_FOR_EACH_BIT_WIDTH`, +# despite having different output on 32-bit vs 64-bit targets. +../x --stage 2 test tests/mir-opt --host='' --target=i686-unknown-linux-gnu + +# Run the UI test suite again, but in `--pass=check` mode +# +# This is intended to make sure that both `--pass=check` continues to +# work. +../x.ps1 --stage 2 test tests/ui --pass=check --host='' --target=i686-unknown-linux-gnu diff --git a/src/ci/docker/scripts/x86_64-gnu-llvm3.sh b/src/ci/docker/scripts/x86_64-gnu-llvm3.sh new file mode 100755 index 00000000000..d1bf2dab1e2 --- /dev/null +++ b/src/ci/docker/scripts/x86_64-gnu-llvm3.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +set -ex + +/tmp/add_dummy_commit.sh + +##### Test stage 1 ##### + +../x.py --stage 1 test --skip src/tools/tidy + +# Run the `mir-opt` tests again but this time for a 32-bit target. +# This enforces that tests using `// EMIT_MIR_FOR_EACH_BIT_WIDTH` have +# both 32-bit and 64-bit outputs updated by the PR author, before +# the PR is approved and tested for merging. +# It will also detect tests lacking `// EMIT_MIR_FOR_EACH_BIT_WIDTH`, +# despite having different output on 32-bit vs 64-bit targets. +../x.py --stage 1 test tests/mir-opt --host='' --target=i686-unknown-linux-gnu + +# Run `ui-fulldeps` in `--stage=1`, which actually uses the stage0 +# compiler, and is sensitive to the addition of new flags. +../x.py --stage 1 test tests/ui-fulldeps + +# Rebuild the stdlib with the size optimizations enabled and run tests again. +RUSTFLAGS_NOT_BOOTSTRAP="--cfg feature=\"optimize_for_size\"" ../x.py --stage 1 test \ + library/std library/alloc library/core diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index 959a9580e60..876a7793592 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -5,22 +5,22 @@ runners: env: { } - &job-linux-4c - os: ubuntu-20.04 + os: ubuntu-22.04 # Free some disk space to avoid running out of space during the build. free_disk: true <<: *base-job # Large runner used mainly for its bigger disk capacity - &job-linux-4c-largedisk - os: ubuntu-20.04-4core-16gb + os: ubuntu-22.04-4core-16gb <<: *base-job - &job-linux-8c - os: ubuntu-20.04-8core-32gb + os: ubuntu-22.04-8core-32gb <<: *base-job - &job-linux-16c - os: ubuntu-20.04-16core-64gb + os: ubuntu-22.04-16core-64gb <<: *base-job - &job-macos-xl @@ -43,7 +43,7 @@ runners: os: windows-2022-16core-64gb <<: *base-job - - &job-linux-8c-aarch64 + - &job-aarch64-linux os: ubuntu-22.04-arm64-8core-32gb envs: @@ -58,22 +58,6 @@ envs: NO_DEBUG_ASSERTIONS: 1 NO_OVERFLOW_CHECKS: 1 - # Different set of tests to run tests in parallel in multiple jobs. - stage_2_test_set1: &stage_2_test_set1 - DOCKER_SCRIPT: >- - python3 ../x.py --stage 2 test - --skip compiler - --skip src - - stage_2_test_set2: &stage_2_test_set2 - DOCKER_SCRIPT: >- - python3 ../x.py --stage 2 test - --skip tests - --skip coverage-map - --skip coverage-run - --skip library - --skip tidyselftest - production: &production DEPLOY_BUCKET: rust-lang-ci2 @@ -117,6 +101,7 @@ pr: ENABLE_GCC_CODEGEN: "1" # We are adding (temporarily) a dummy commit on the compiler READ_ONLY_SRC: "0" + DOCKER_SCRIPT: x86_64-gnu-llvm.sh <<: *job-linux-16c - image: x86_64-gnu-tools <<: *job-linux-16c @@ -139,10 +124,10 @@ auto: ############################# - image: aarch64-gnu - <<: *job-linux-8c-aarch64 + <<: *job-aarch64-linux - image: aarch64-gnu-debug - <<: *job-linux-8c-aarch64 + <<: *job-aarch64-linux - image: arm-android <<: *job-linux-4c @@ -159,7 +144,7 @@ auto: <<: *job-linux-4c - image: dist-arm-linux - <<: *job-linux-8c-aarch64 + <<: *job-linux-8c - image: dist-armhf-linux <<: *job-linux-4c @@ -189,7 +174,7 @@ auto: <<: *job-linux-4c - image: dist-powerpc64le-linux - <<: *job-linux-4c + <<: *job-linux-4c-largedisk - image: dist-riscv64-linux <<: *job-linux-4c @@ -233,14 +218,14 @@ auto: - image: i686-gnu-1 env: IMAGE: i686-gnu - <<: *stage_2_test_set1 + DOCKER_SCRIPT: stage_2_test_set1.sh <<: *job-linux-4c # Skip tests that run in i686-gnu-1 - image: i686-gnu-2 env: IMAGE: i686-gnu - <<: *stage_2_test_set2 + DOCKER_SCRIPT: stage_2_test_set2.sh <<: *job-linux-4c # The i686-gnu-nopt job is split into multiple jobs to run tests in parallel. @@ -248,7 +233,7 @@ auto: - image: i686-gnu-nopt-1 env: IMAGE: i686-gnu-nopt - <<: *stage_2_test_set1 + DOCKER_SCRIPT: /scripts/stage_2_test_set1.sh <<: *job-linux-4c # Skip tests that run in i686-gnu-nopt-1 @@ -257,12 +242,7 @@ auto: IMAGE: i686-gnu-nopt DOCKER_SCRIPT: >- python3 ../x.py test --stage 0 --config /config/nopt-std-config.toml library/std && - python3 ../x.py --stage 2 test - --skip tests - --skip coverage-map - --skip coverage-run - --skip library - --skip tidyselftest + /scripts/stage_2_test_set2.sh <<: *job-linux-4c - image: mingw-check @@ -312,16 +292,58 @@ auto: - image: x86_64-gnu-distcheck <<: *job-linux-8c - - image: x86_64-gnu-llvm-19 + # The x86_64-gnu-llvm-19 job is split into multiple jobs to run tests in parallel. + # x86_64-gnu-llvm-19-1 skips tests that run in x86_64-gnu-llvm-19-{2,3}. + - image: x86_64-gnu-llvm-19-1 env: RUST_BACKTRACE: 1 - <<: *job-linux-8c + IMAGE: x86_64-gnu-llvm-19 + DOCKER_SCRIPT: stage_2_test_set1.sh + <<: *job-linux-4c - - image: x86_64-gnu-llvm-18 + # Skip tests that run in x86_64-gnu-llvm-19-{1,3} + - image: x86_64-gnu-llvm-19-2 + env: + RUST_BACKTRACE: 1 + IMAGE: x86_64-gnu-llvm-19 + DOCKER_SCRIPT: x86_64-gnu-llvm2.sh + <<: *job-linux-4c + + # Skip tests that run in x86_64-gnu-llvm-19-{1,2} + - image: x86_64-gnu-llvm-19-3 + env: + RUST_BACKTRACE: 1 + IMAGE: x86_64-gnu-llvm-19 + DOCKER_SCRIPT: x86_64-gnu-llvm3.sh + <<: *job-linux-4c + + # The x86_64-gnu-llvm-18 job is split into multiple jobs to run tests in parallel. + # x86_64-gnu-llvm-18-1 skips tests that run in x86_64-gnu-llvm-18-{2,3}. + - image: x86_64-gnu-llvm-18-1 env: RUST_BACKTRACE: 1 READ_ONLY_SRC: "0" - <<: *job-linux-8c + IMAGE: x86_64-gnu-llvm-18 + DOCKER_SCRIPT: stage_2_test_set1.sh + <<: *job-linux-4c + + # Skip tests that run in x86_64-gnu-llvm-18-{1,3} + - image: x86_64-gnu-llvm-18-2 + env: + RUST_BACKTRACE: 1 + READ_ONLY_SRC: "0" + IMAGE: x86_64-gnu-llvm-18 + DOCKER_SCRIPT: x86_64-gnu-llvm2.sh + <<: *job-linux-4c + + # Skip tests that run in x86_64-gnu-llvm-18-{1,2} + - image: x86_64-gnu-llvm-18-3 + env: + RUST_BACKTRACE: 1 + READ_ONLY_SRC: "0" + IMAGE: x86_64-gnu-llvm-18 + DOCKER_SCRIPT: x86_64-gnu-llvm3.sh + <<: *job-linux-4c - image: x86_64-gnu-nopt <<: *job-linux-4c diff --git a/src/ci/package-lock.json b/src/ci/package-lock.json new file mode 100644 index 00000000000..6bbdc6adcfd --- /dev/null +++ b/src/ci/package-lock.json @@ -0,0 +1,5004 @@ +{ + "name": "ci", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "@datadog/datadog-ci": "^2.45.1" + } + }, + "node_modules/@aws-crypto/crc32": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-5.2.0.tgz", + "integrity": "sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-crypto/sha256-browser": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz", + "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-js": "^5.2.0", + "@aws-crypto/supports-web-crypto": "^5.2.0", + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha256-js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", + "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-crypto/supports-web-crypto": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz", + "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/util": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", + "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.222.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/util/node_modules/@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/util/node_modules/@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/util/node_modules/@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-cloudwatch-logs": { + "version": "3.703.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudwatch-logs/-/client-cloudwatch-logs-3.703.0.tgz", + "integrity": "sha512-KkLMwrNhkLZr3OCRWakJY16OF8pUZCoexxZkWzHfR/Pw3WBcDtBMEiEO13P6oHlGAn1VvIDxxMBSxeg/89xyJA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/client-sso-oidc": "3.699.0", + "@aws-sdk/client-sts": "3.699.0", + "@aws-sdk/core": "3.696.0", + "@aws-sdk/credential-provider-node": "3.699.0", + "@aws-sdk/middleware-host-header": "3.696.0", + "@aws-sdk/middleware-logger": "3.696.0", + "@aws-sdk/middleware-recursion-detection": "3.696.0", + "@aws-sdk/middleware-user-agent": "3.696.0", + "@aws-sdk/region-config-resolver": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@aws-sdk/util-endpoints": "3.696.0", + "@aws-sdk/util-user-agent-browser": "3.696.0", + "@aws-sdk/util-user-agent-node": "3.696.0", + "@smithy/config-resolver": "^3.0.12", + "@smithy/core": "^2.5.3", + "@smithy/eventstream-serde-browser": "^3.0.13", + "@smithy/eventstream-serde-config-resolver": "^3.0.10", + "@smithy/eventstream-serde-node": "^3.0.12", + "@smithy/fetch-http-handler": "^4.1.1", + "@smithy/hash-node": "^3.0.10", + "@smithy/invalid-dependency": "^3.0.10", + "@smithy/middleware-content-length": "^3.0.12", + "@smithy/middleware-endpoint": "^3.2.3", + "@smithy/middleware-retry": "^3.0.27", + "@smithy/middleware-serde": "^3.0.10", + "@smithy/middleware-stack": "^3.0.10", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/node-http-handler": "^3.3.1", + "@smithy/protocol-http": "^4.1.7", + "@smithy/smithy-client": "^3.4.4", + "@smithy/types": "^3.7.1", + "@smithy/url-parser": "^3.0.10", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.27", + "@smithy/util-defaults-mode-node": "^3.0.27", + "@smithy/util-endpoints": "^2.1.6", + "@smithy/util-middleware": "^3.0.10", + "@smithy/util-retry": "^3.0.10", + "@smithy/util-utf8": "^3.0.0", + "@types/uuid": "^9.0.1", + "tslib": "^2.6.2", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cloudwatch-logs/node_modules/@smithy/util-retry": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.11.tgz", + "integrity": "sha512-hJUC6W7A3DQgaee3Hp9ZFcOxVDZzmBIRBPlUAk8/fSOEl7pE/aX7Dci0JycNOnm9Mfr0KV2XjIlUOcGWXQUdVQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/service-error-classification": "^3.0.11", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity": { + "version": "3.699.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.699.0.tgz", + "integrity": "sha512-9tFt+we6AIvj/f1+nrLHuCWcQmyfux5gcBSOy9d9+zIG56YxGEX7S9TaZnybogpVV8A0BYWml36WvIHS9QjIpA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/client-sso-oidc": "3.699.0", + "@aws-sdk/client-sts": "3.699.0", + "@aws-sdk/core": "3.696.0", + "@aws-sdk/credential-provider-node": "3.699.0", + "@aws-sdk/middleware-host-header": "3.696.0", + "@aws-sdk/middleware-logger": "3.696.0", + "@aws-sdk/middleware-recursion-detection": "3.696.0", + "@aws-sdk/middleware-user-agent": "3.696.0", + "@aws-sdk/region-config-resolver": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@aws-sdk/util-endpoints": "3.696.0", + "@aws-sdk/util-user-agent-browser": "3.696.0", + "@aws-sdk/util-user-agent-node": "3.696.0", + "@smithy/config-resolver": "^3.0.12", + "@smithy/core": "^2.5.3", + "@smithy/fetch-http-handler": "^4.1.1", + "@smithy/hash-node": "^3.0.10", + "@smithy/invalid-dependency": "^3.0.10", + "@smithy/middleware-content-length": "^3.0.12", + "@smithy/middleware-endpoint": "^3.2.3", + "@smithy/middleware-retry": "^3.0.27", + "@smithy/middleware-serde": "^3.0.10", + "@smithy/middleware-stack": "^3.0.10", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/node-http-handler": "^3.3.1", + "@smithy/protocol-http": "^4.1.7", + "@smithy/smithy-client": "^3.4.4", + "@smithy/types": "^3.7.1", + "@smithy/url-parser": "^3.0.10", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.27", + "@smithy/util-defaults-mode-node": "^3.0.27", + "@smithy/util-endpoints": "^2.1.6", + "@smithy/util-middleware": "^3.0.10", + "@smithy/util-retry": "^3.0.10", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity/node_modules/@smithy/util-retry": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.11.tgz", + "integrity": "sha512-hJUC6W7A3DQgaee3Hp9ZFcOxVDZzmBIRBPlUAk8/fSOEl7pE/aX7Dci0JycNOnm9Mfr0KV2XjIlUOcGWXQUdVQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/service-error-classification": "^3.0.11", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-iam": { + "version": "3.699.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-iam/-/client-iam-3.699.0.tgz", + "integrity": "sha512-JBVcmkGaV7tW/mEntqt6KdkhsyYU2oIMUbkNHJextKqu6odSkuB1mN70TgctwFP8x2LDgFzvT6WcWVCKc/g3Ng==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/client-sso-oidc": "3.699.0", + "@aws-sdk/client-sts": "3.699.0", + "@aws-sdk/core": "3.696.0", + "@aws-sdk/credential-provider-node": "3.699.0", + "@aws-sdk/middleware-host-header": "3.696.0", + "@aws-sdk/middleware-logger": "3.696.0", + "@aws-sdk/middleware-recursion-detection": "3.696.0", + "@aws-sdk/middleware-user-agent": "3.696.0", + "@aws-sdk/region-config-resolver": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@aws-sdk/util-endpoints": "3.696.0", + "@aws-sdk/util-user-agent-browser": "3.696.0", + "@aws-sdk/util-user-agent-node": "3.696.0", + "@smithy/config-resolver": "^3.0.12", + "@smithy/core": "^2.5.3", + "@smithy/fetch-http-handler": "^4.1.1", + "@smithy/hash-node": "^3.0.10", + "@smithy/invalid-dependency": "^3.0.10", + "@smithy/middleware-content-length": "^3.0.12", + "@smithy/middleware-endpoint": "^3.2.3", + "@smithy/middleware-retry": "^3.0.27", + "@smithy/middleware-serde": "^3.0.10", + "@smithy/middleware-stack": "^3.0.10", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/node-http-handler": "^3.3.1", + "@smithy/protocol-http": "^4.1.7", + "@smithy/smithy-client": "^3.4.4", + "@smithy/types": "^3.7.1", + "@smithy/url-parser": "^3.0.10", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.27", + "@smithy/util-defaults-mode-node": "^3.0.27", + "@smithy/util-endpoints": "^2.1.6", + "@smithy/util-middleware": "^3.0.10", + "@smithy/util-retry": "^3.0.10", + "@smithy/util-utf8": "^3.0.0", + "@smithy/util-waiter": "^3.1.9", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-iam/node_modules/@smithy/util-retry": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.11.tgz", + "integrity": "sha512-hJUC6W7A3DQgaee3Hp9ZFcOxVDZzmBIRBPlUAk8/fSOEl7pE/aX7Dci0JycNOnm9Mfr0KV2XjIlUOcGWXQUdVQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/service-error-classification": "^3.0.11", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-lambda": { + "version": "3.699.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-lambda/-/client-lambda-3.699.0.tgz", + "integrity": "sha512-K9TGvQB8hkjwNhfWSfYllUpttqxTcd78ShSRCIhlcwzzsmQphET10xEb0Tm1k8sqriSQ+CiVOFSkX78gqoHzBg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/client-sso-oidc": "3.699.0", + "@aws-sdk/client-sts": "3.699.0", + "@aws-sdk/core": "3.696.0", + "@aws-sdk/credential-provider-node": "3.699.0", + "@aws-sdk/middleware-host-header": "3.696.0", + "@aws-sdk/middleware-logger": "3.696.0", + "@aws-sdk/middleware-recursion-detection": "3.696.0", + "@aws-sdk/middleware-user-agent": "3.696.0", + "@aws-sdk/region-config-resolver": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@aws-sdk/util-endpoints": "3.696.0", + "@aws-sdk/util-user-agent-browser": "3.696.0", + "@aws-sdk/util-user-agent-node": "3.696.0", + "@smithy/config-resolver": "^3.0.12", + "@smithy/core": "^2.5.3", + "@smithy/eventstream-serde-browser": "^3.0.13", + "@smithy/eventstream-serde-config-resolver": "^3.0.10", + "@smithy/eventstream-serde-node": "^3.0.12", + "@smithy/fetch-http-handler": "^4.1.1", + "@smithy/hash-node": "^3.0.10", + "@smithy/invalid-dependency": "^3.0.10", + "@smithy/middleware-content-length": "^3.0.12", + "@smithy/middleware-endpoint": "^3.2.3", + "@smithy/middleware-retry": "^3.0.27", + "@smithy/middleware-serde": "^3.0.10", + "@smithy/middleware-stack": "^3.0.10", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/node-http-handler": "^3.3.1", + "@smithy/protocol-http": "^4.1.7", + "@smithy/smithy-client": "^3.4.4", + "@smithy/types": "^3.7.1", + "@smithy/url-parser": "^3.0.10", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.27", + "@smithy/util-defaults-mode-node": "^3.0.27", + "@smithy/util-endpoints": "^2.1.6", + "@smithy/util-middleware": "^3.0.10", + "@smithy/util-retry": "^3.0.10", + "@smithy/util-stream": "^3.3.1", + "@smithy/util-utf8": "^3.0.0", + "@smithy/util-waiter": "^3.1.9", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-lambda/node_modules/@smithy/util-retry": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.11.tgz", + "integrity": "sha512-hJUC6W7A3DQgaee3Hp9ZFcOxVDZzmBIRBPlUAk8/fSOEl7pE/aX7Dci0JycNOnm9Mfr0KV2XjIlUOcGWXQUdVQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/service-error-classification": "^3.0.11", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-sfn": { + "version": "3.699.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sfn/-/client-sfn-3.699.0.tgz", + "integrity": "sha512-66/+rOMVvjKRhKDDsrxtfRzXXsAfVu/RbhxPYepcVhO+0/ii6DL2uQCeNhMN3+MPg+HWX695H5RyBVJ6QGli8w==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/client-sso-oidc": "3.699.0", + "@aws-sdk/client-sts": "3.699.0", + "@aws-sdk/core": "3.696.0", + "@aws-sdk/credential-provider-node": "3.699.0", + "@aws-sdk/middleware-host-header": "3.696.0", + "@aws-sdk/middleware-logger": "3.696.0", + "@aws-sdk/middleware-recursion-detection": "3.696.0", + "@aws-sdk/middleware-user-agent": "3.696.0", + "@aws-sdk/region-config-resolver": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@aws-sdk/util-endpoints": "3.696.0", + "@aws-sdk/util-user-agent-browser": "3.696.0", + "@aws-sdk/util-user-agent-node": "3.696.0", + "@smithy/config-resolver": "^3.0.12", + "@smithy/core": "^2.5.3", + "@smithy/fetch-http-handler": "^4.1.1", + "@smithy/hash-node": "^3.0.10", + "@smithy/invalid-dependency": "^3.0.10", + "@smithy/middleware-content-length": "^3.0.12", + "@smithy/middleware-endpoint": "^3.2.3", + "@smithy/middleware-retry": "^3.0.27", + "@smithy/middleware-serde": "^3.0.10", + "@smithy/middleware-stack": "^3.0.10", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/node-http-handler": "^3.3.1", + "@smithy/protocol-http": "^4.1.7", + "@smithy/smithy-client": "^3.4.4", + "@smithy/types": "^3.7.1", + "@smithy/url-parser": "^3.0.10", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.27", + "@smithy/util-defaults-mode-node": "^3.0.27", + "@smithy/util-endpoints": "^2.1.6", + "@smithy/util-middleware": "^3.0.10", + "@smithy/util-retry": "^3.0.10", + "@smithy/util-utf8": "^3.0.0", + "@types/uuid": "^9.0.1", + "tslib": "^2.6.2", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-sfn/node_modules/@smithy/util-retry": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.11.tgz", + "integrity": "sha512-hJUC6W7A3DQgaee3Hp9ZFcOxVDZzmBIRBPlUAk8/fSOEl7pE/aX7Dci0JycNOnm9Mfr0KV2XjIlUOcGWXQUdVQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/service-error-classification": "^3.0.11", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-sso": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.696.0.tgz", + "integrity": "sha512-q5TTkd08JS0DOkHfUL853tuArf7NrPeqoS5UOvqJho8ibV9Ak/a/HO4kNvy9Nj3cib/toHYHsQIEtecUPSUUrQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.696.0", + "@aws-sdk/middleware-host-header": "3.696.0", + "@aws-sdk/middleware-logger": "3.696.0", + "@aws-sdk/middleware-recursion-detection": "3.696.0", + "@aws-sdk/middleware-user-agent": "3.696.0", + "@aws-sdk/region-config-resolver": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@aws-sdk/util-endpoints": "3.696.0", + "@aws-sdk/util-user-agent-browser": "3.696.0", + "@aws-sdk/util-user-agent-node": "3.696.0", + "@smithy/config-resolver": "^3.0.12", + "@smithy/core": "^2.5.3", + "@smithy/fetch-http-handler": "^4.1.1", + "@smithy/hash-node": "^3.0.10", + "@smithy/invalid-dependency": "^3.0.10", + "@smithy/middleware-content-length": "^3.0.12", + "@smithy/middleware-endpoint": "^3.2.3", + "@smithy/middleware-retry": "^3.0.27", + "@smithy/middleware-serde": "^3.0.10", + "@smithy/middleware-stack": "^3.0.10", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/node-http-handler": "^3.3.1", + "@smithy/protocol-http": "^4.1.7", + "@smithy/smithy-client": "^3.4.4", + "@smithy/types": "^3.7.1", + "@smithy/url-parser": "^3.0.10", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.27", + "@smithy/util-defaults-mode-node": "^3.0.27", + "@smithy/util-endpoints": "^2.1.6", + "@smithy/util-middleware": "^3.0.10", + "@smithy/util-retry": "^3.0.10", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-sso-oidc": { + "version": "3.699.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.699.0.tgz", + "integrity": "sha512-u8a1GorY5D1l+4FQAf4XBUC1T10/t7neuwT21r0ymrtMFSK2a9QqVHKMoLkvavAwyhJnARSBM9/UQC797PFOFw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.696.0", + "@aws-sdk/credential-provider-node": "3.699.0", + "@aws-sdk/middleware-host-header": "3.696.0", + "@aws-sdk/middleware-logger": "3.696.0", + "@aws-sdk/middleware-recursion-detection": "3.696.0", + "@aws-sdk/middleware-user-agent": "3.696.0", + "@aws-sdk/region-config-resolver": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@aws-sdk/util-endpoints": "3.696.0", + "@aws-sdk/util-user-agent-browser": "3.696.0", + "@aws-sdk/util-user-agent-node": "3.696.0", + "@smithy/config-resolver": "^3.0.12", + "@smithy/core": "^2.5.3", + "@smithy/fetch-http-handler": "^4.1.1", + "@smithy/hash-node": "^3.0.10", + "@smithy/invalid-dependency": "^3.0.10", + "@smithy/middleware-content-length": "^3.0.12", + "@smithy/middleware-endpoint": "^3.2.3", + "@smithy/middleware-retry": "^3.0.27", + "@smithy/middleware-serde": "^3.0.10", + "@smithy/middleware-stack": "^3.0.10", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/node-http-handler": "^3.3.1", + "@smithy/protocol-http": "^4.1.7", + "@smithy/smithy-client": "^3.4.4", + "@smithy/types": "^3.7.1", + "@smithy/url-parser": "^3.0.10", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.27", + "@smithy/util-defaults-mode-node": "^3.0.27", + "@smithy/util-endpoints": "^2.1.6", + "@smithy/util-middleware": "^3.0.10", + "@smithy/util-retry": "^3.0.10", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@aws-sdk/client-sts": "^3.699.0" + } + }, + "node_modules/@aws-sdk/client-sso-oidc/node_modules/@smithy/util-retry": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.11.tgz", + "integrity": "sha512-hJUC6W7A3DQgaee3Hp9ZFcOxVDZzmBIRBPlUAk8/fSOEl7pE/aX7Dci0JycNOnm9Mfr0KV2XjIlUOcGWXQUdVQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/service-error-classification": "^3.0.11", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-sso/node_modules/@smithy/util-retry": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.11.tgz", + "integrity": "sha512-hJUC6W7A3DQgaee3Hp9ZFcOxVDZzmBIRBPlUAk8/fSOEl7pE/aX7Dci0JycNOnm9Mfr0KV2XjIlUOcGWXQUdVQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/service-error-classification": "^3.0.11", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-sts": { + "version": "3.699.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.699.0.tgz", + "integrity": "sha512-++lsn4x2YXsZPIzFVwv3fSUVM55ZT0WRFmPeNilYIhZClxHLmVAWKH4I55cY9ry60/aTKYjzOXkWwyBKGsGvQg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/client-sso-oidc": "3.699.0", + "@aws-sdk/core": "3.696.0", + "@aws-sdk/credential-provider-node": "3.699.0", + "@aws-sdk/middleware-host-header": "3.696.0", + "@aws-sdk/middleware-logger": "3.696.0", + "@aws-sdk/middleware-recursion-detection": "3.696.0", + "@aws-sdk/middleware-user-agent": "3.696.0", + "@aws-sdk/region-config-resolver": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@aws-sdk/util-endpoints": "3.696.0", + "@aws-sdk/util-user-agent-browser": "3.696.0", + "@aws-sdk/util-user-agent-node": "3.696.0", + "@smithy/config-resolver": "^3.0.12", + "@smithy/core": "^2.5.3", + "@smithy/fetch-http-handler": "^4.1.1", + "@smithy/hash-node": "^3.0.10", + "@smithy/invalid-dependency": "^3.0.10", + "@smithy/middleware-content-length": "^3.0.12", + "@smithy/middleware-endpoint": "^3.2.3", + "@smithy/middleware-retry": "^3.0.27", + "@smithy/middleware-serde": "^3.0.10", + "@smithy/middleware-stack": "^3.0.10", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/node-http-handler": "^3.3.1", + "@smithy/protocol-http": "^4.1.7", + "@smithy/smithy-client": "^3.4.4", + "@smithy/types": "^3.7.1", + "@smithy/url-parser": "^3.0.10", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.27", + "@smithy/util-defaults-mode-node": "^3.0.27", + "@smithy/util-endpoints": "^2.1.6", + "@smithy/util-middleware": "^3.0.10", + "@smithy/util-retry": "^3.0.10", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-sts/node_modules/@smithy/util-retry": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.11.tgz", + "integrity": "sha512-hJUC6W7A3DQgaee3Hp9ZFcOxVDZzmBIRBPlUAk8/fSOEl7pE/aX7Dci0JycNOnm9Mfr0KV2XjIlUOcGWXQUdVQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/service-error-classification": "^3.0.11", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/core": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.696.0.tgz", + "integrity": "sha512-3c9III1k03DgvRZWg8vhVmfIXPG6hAciN9MzQTzqGngzWAELZF/WONRTRQuDFixVtarQatmLHYVw/atGeA2Byw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.696.0", + "@smithy/core": "^2.5.3", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/property-provider": "^3.1.9", + "@smithy/protocol-http": "^4.1.7", + "@smithy/signature-v4": "^4.2.2", + "@smithy/smithy-client": "^3.4.4", + "@smithy/types": "^3.7.1", + "@smithy/util-middleware": "^3.0.10", + "fast-xml-parser": "4.4.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/core/node_modules/@smithy/property-provider": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz", + "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/core/node_modules/fast-xml-parser": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.1.tgz", + "integrity": "sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + }, + { + "type": "paypal", + "url": "https://paypal.me/naturalintelligence" + } + ], + "license": "MIT", + "dependencies": { + "strnum": "^1.0.5" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "node_modules/@aws-sdk/credential-provider-cognito-identity": { + "version": "3.699.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.699.0.tgz", + "integrity": "sha512-iuaTnudaBfEET+o444sDwf71Awe6UiZfH+ipUPmswAi2jZDwdFF1nxMKDEKL8/LV5WpXsdKSfwgS0RQeupURew==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/client-cognito-identity": "3.699.0", + "@aws-sdk/types": "3.696.0", + "@smithy/property-provider": "^3.1.9", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-cognito-identity/node_modules/@smithy/property-provider": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz", + "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-env": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.696.0.tgz", + "integrity": "sha512-T9iMFnJL7YTlESLpVFT3fg1Lkb1lD+oiaIC8KMpepb01gDUBIpj9+Y+pA/cgRWW0yRxmkDXNazAE2qQTVFGJzA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@smithy/property-provider": "^3.1.9", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-env/node_modules/@smithy/property-provider": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz", + "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-http": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.696.0.tgz", + "integrity": "sha512-GV6EbvPi2eq1+WgY/o2RFA3P7HGmnkIzCNmhwtALFlqMroLYWKE7PSeHw66Uh1dFQeVESn0/+hiUNhu1mB0emA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@smithy/fetch-http-handler": "^4.1.1", + "@smithy/node-http-handler": "^3.3.1", + "@smithy/property-provider": "^3.1.9", + "@smithy/protocol-http": "^4.1.7", + "@smithy/smithy-client": "^3.4.4", + "@smithy/types": "^3.7.1", + "@smithy/util-stream": "^3.3.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/property-provider": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz", + "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-ini": { + "version": "3.699.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.699.0.tgz", + "integrity": "sha512-dXmCqjJnKmG37Q+nLjPVu22mNkrGHY8hYoOt3Jo9R2zr5MYV7s/NHsCHr+7E+BZ+tfZYLRPeB1wkpTeHiEcdRw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.696.0", + "@aws-sdk/credential-provider-env": "3.696.0", + "@aws-sdk/credential-provider-http": "3.696.0", + "@aws-sdk/credential-provider-process": "3.696.0", + "@aws-sdk/credential-provider-sso": "3.699.0", + "@aws-sdk/credential-provider-web-identity": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@smithy/credential-provider-imds": "^3.2.6", + "@smithy/property-provider": "^3.1.9", + "@smithy/shared-ini-file-loader": "^3.1.10", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@aws-sdk/client-sts": "^3.699.0" + } + }, + "node_modules/@aws-sdk/credential-provider-ini/node_modules/@smithy/property-provider": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz", + "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-node": { + "version": "3.699.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.699.0.tgz", + "integrity": "sha512-MmEmNDo1bBtTgRmdNfdQksXu4uXe66s0p1hi1YPrn1h59Q605eq/xiWbGL6/3KdkViH6eGUuABeV2ODld86ylg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.696.0", + "@aws-sdk/credential-provider-http": "3.696.0", + "@aws-sdk/credential-provider-ini": "3.699.0", + "@aws-sdk/credential-provider-process": "3.696.0", + "@aws-sdk/credential-provider-sso": "3.699.0", + "@aws-sdk/credential-provider-web-identity": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@smithy/credential-provider-imds": "^3.2.6", + "@smithy/property-provider": "^3.1.9", + "@smithy/shared-ini-file-loader": "^3.1.10", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-node/node_modules/@smithy/property-provider": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz", + "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-process": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.696.0.tgz", + "integrity": "sha512-mL1RcFDe9sfmyU5K1nuFkO8UiJXXxLX4JO1gVaDIOvPqwStpUAwi3A1BoeZhWZZNQsiKI810RnYGo0E0WB/hUA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@smithy/property-provider": "^3.1.9", + "@smithy/shared-ini-file-loader": "^3.1.10", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-process/node_modules/@smithy/property-provider": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz", + "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-sso": { + "version": "3.699.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.699.0.tgz", + "integrity": "sha512-Ekp2cZG4pl9D8+uKWm4qO1xcm8/MeiI8f+dnlZm8aQzizeC+aXYy9GyoclSf6daK8KfRPiRfM7ZHBBL5dAfdMA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/client-sso": "3.696.0", + "@aws-sdk/core": "3.696.0", + "@aws-sdk/token-providers": "3.699.0", + "@aws-sdk/types": "3.696.0", + "@smithy/property-provider": "^3.1.9", + "@smithy/shared-ini-file-loader": "^3.1.10", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-sso/node_modules/@smithy/property-provider": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz", + "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-web-identity": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.696.0.tgz", + "integrity": "sha512-XJ/CVlWChM0VCoc259vWguFUjJDn/QwDqHwbx+K9cg3v6yrqXfK5ai+p/6lx0nQpnk4JzPVeYYxWRpaTsGC9rg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@smithy/property-provider": "^3.1.9", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@aws-sdk/client-sts": "^3.696.0" + } + }, + "node_modules/@aws-sdk/credential-provider-web-identity/node_modules/@smithy/property-provider": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz", + "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/credential-providers": { + "version": "3.699.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.699.0.tgz", + "integrity": "sha512-jBjOntl9zN9Nvb0jmbMGRbiTzemDz64ij7W6BDavxBJRZpRoNeN0QCz6RolkCyXnyUJjo5mF2unY2wnv00A+LQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/client-cognito-identity": "3.699.0", + "@aws-sdk/client-sso": "3.696.0", + "@aws-sdk/client-sts": "3.699.0", + "@aws-sdk/core": "3.696.0", + "@aws-sdk/credential-provider-cognito-identity": "3.699.0", + "@aws-sdk/credential-provider-env": "3.696.0", + "@aws-sdk/credential-provider-http": "3.696.0", + "@aws-sdk/credential-provider-ini": "3.699.0", + "@aws-sdk/credential-provider-node": "3.699.0", + "@aws-sdk/credential-provider-process": "3.696.0", + "@aws-sdk/credential-provider-sso": "3.699.0", + "@aws-sdk/credential-provider-web-identity": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@smithy/credential-provider-imds": "^3.2.6", + "@smithy/property-provider": "^3.1.9", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/credential-providers/node_modules/@smithy/property-provider": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz", + "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/middleware-host-header": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.696.0.tgz", + "integrity": "sha512-zELJp9Ta2zkX7ELggMN9qMCgekqZhFC5V2rOr4hJDEb/Tte7gpfKSObAnw/3AYiVqt36sjHKfdkoTsuwGdEoDg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.696.0", + "@smithy/protocol-http": "^4.1.7", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/middleware-logger": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.696.0.tgz", + "integrity": "sha512-KhkHt+8AjCxcR/5Zp3++YPJPpFQzxpr+jmONiT/Jw2yqnSngZ0Yspm5wGoRx2hS1HJbyZNuaOWEGuJoxLeBKfA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.696.0", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/middleware-recursion-detection": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.696.0.tgz", + "integrity": "sha512-si/maV3Z0hH7qa99f9ru2xpS5HlfSVcasRlNUXKSDm611i7jFMWwGNLUOXFAOLhXotPX5G3Z6BLwL34oDeBMug==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.696.0", + "@smithy/protocol-http": "^4.1.7", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/middleware-user-agent": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.696.0.tgz", + "integrity": "sha512-Lvyj8CTyxrHI6GHd2YVZKIRI5Fmnugt3cpJo0VrKKEgK5zMySwEZ1n4dqPK6czYRWKd5+WnYHYAuU+Wdk6Jsjw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@aws-sdk/util-endpoints": "3.696.0", + "@smithy/core": "^2.5.3", + "@smithy/protocol-http": "^4.1.7", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/region-config-resolver": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.696.0.tgz", + "integrity": "sha512-7EuH142lBXjI8yH6dVS/CZeiK/WZsmb/8zP6bQbVYpMrppSTgB3MzZZdxVZGzL5r8zPQOU10wLC4kIMy0qdBVQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.696.0", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/types": "^3.7.1", + "@smithy/util-config-provider": "^3.0.0", + "@smithy/util-middleware": "^3.0.10", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/token-providers": { + "version": "3.699.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.699.0.tgz", + "integrity": "sha512-kuiEW9DWs7fNos/SM+y58HCPhcIzm1nEZLhe2/7/6+TvAYLuEWURYsbK48gzsxXlaJ2k/jGY3nIsA7RptbMOwA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.696.0", + "@smithy/property-provider": "^3.1.9", + "@smithy/shared-ini-file-loader": "^3.1.10", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@aws-sdk/client-sso-oidc": "^3.699.0" + } + }, + "node_modules/@aws-sdk/token-providers/node_modules/@smithy/property-provider": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz", + "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/types": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.696.0.tgz", + "integrity": "sha512-9rTvUJIAj5d3//U5FDPWGJ1nFJLuWb30vugGOrWk7aNZ6y9tuA3PI7Cc9dP8WEXKVyK1vuuk8rSFP2iqXnlgrw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/util-endpoints": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.696.0.tgz", + "integrity": "sha512-T5s0IlBVX+gkb9g/I6CLt4yAZVzMSiGnbUqWihWsHvQR1WOoIcndQy/Oz/IJXT9T2ipoy7a80gzV6a5mglrioA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.696.0", + "@smithy/types": "^3.7.1", + "@smithy/util-endpoints": "^2.1.6", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/util-locate-window": { + "version": "3.693.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.693.0.tgz", + "integrity": "sha512-ttrag6haJLWABhLqtg1Uf+4LgHWIMOVSYL+VYZmAp2v4PUGOwWmWQH0Zk8RM7YuQcLfH/EoR72/Yxz6A4FKcuw==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/util-user-agent-browser": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.696.0.tgz", + "integrity": "sha512-Z5rVNDdmPOe6ELoM5AhF/ja5tSjbe6ctSctDPb0JdDf4dT0v2MfwhJKzXju2RzX8Es/77Glh7MlaXLE0kCB9+Q==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.696.0", + "@smithy/types": "^3.7.1", + "bowser": "^2.11.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-sdk/util-user-agent-node": { + "version": "3.696.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.696.0.tgz", + "integrity": "sha512-KhKqcfyXIB0SCCt+qsu4eJjsfiOrNzK5dCV7RAW2YIpp+msxGUUX0NdRE9rkzjiv+3EMktgJm3eEIS+yxtlVdQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/middleware-user-agent": "3.696.0", + "@aws-sdk/types": "3.696.0", + "@smithy/node-config-provider": "^3.1.11", + "@smithy/types": "^3.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "aws-crt": ">=1.0.0" + }, + "peerDependenciesMeta": { + "aws-crt": { + "optional": true + } + } + }, + "node_modules/@datadog/datadog-ci": { + "version": "2.45.1", + "resolved": "https://registry.npmjs.org/@datadog/datadog-ci/-/datadog-ci-2.45.1.tgz", + "integrity": "sha512-na4c4UuhT2jGFTOh+/uUVGR0CVj7c2B6Q7pRp9AMxb6NF2o3McjnSFJzmVc7YFdZwr+eHXeKXKf6bEYw/PjNWw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/client-cloudwatch-logs": "^3.624.0", + "@aws-sdk/client-iam": "^3.624.0", + "@aws-sdk/client-lambda": "^3.624.0", + "@aws-sdk/client-sfn": "^3.624.0", + "@aws-sdk/core": "^3.624.0", + "@aws-sdk/credential-provider-ini": "^3.624.0", + "@aws-sdk/credential-providers": "^3.624.0", + "@google-cloud/logging": "^11.1.0", + "@google-cloud/run": "^1.4.0", + "@smithy/property-provider": "^2.0.12", + "@smithy/util-retry": "^2.0.4", + "@types/datadog-metrics": "0.6.1", + "ajv": "^8.12.0", + "ajv-formats": "^2.1.1", + "async-retry": "1.3.1", + "axios": "^1.7.4", + "chalk": "3.0.0", + "clipanion": "^3.2.1", + "datadog-metrics": "0.9.3", + "deep-extend": "0.6.0", + "deep-object-diff": "^1.1.9", + "fast-levenshtein": "^3.0.0", + "fast-xml-parser": "^4.4.1", + "form-data": "4.0.0", + "fuzzy": "^0.1.3", + "glob": "^7.1.4", + "google-auth-library": "^9.12.0", + "inquirer": "^8.2.5", + "inquirer-checkbox-plus-prompt": "^1.4.2", + "js-yaml": "3.13.1", + "jszip": "^3.10.1", + "ora": "5.4.1", + "proxy-agent": "^6.4.0", + "rimraf": "^3.0.2", + "semver": "^7.5.3", + "simple-git": "3.16.0", + "ssh2": "^1.15.0", + "ssh2-streams": "0.4.10", + "sshpk": "1.16.1", + "terminal-link": "2.1.1", + "tiny-async-pool": "^2.1.0", + "typanion": "^3.14.0", + "uuid": "^9.0.0", + "ws": "^7.5.10", + "xml2js": "0.5.0", + "yamux-js": "0.1.2" + }, + "bin": { + "datadog-ci": "dist/cli.js" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@google-cloud/common": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-5.0.2.tgz", + "integrity": "sha512-V7bmBKYQyu0eVG2BFejuUjlBt+zrya6vtsKdY+JxMM/dNntPF41vZ9+LhOshEUH01zOHEqBSvI7Dad7ZS6aUeA==", + "license": "Apache-2.0", + "dependencies": { + "@google-cloud/projectify": "^4.0.0", + "@google-cloud/promisify": "^4.0.0", + "arrify": "^2.0.1", + "duplexify": "^4.1.1", + "extend": "^3.0.2", + "google-auth-library": "^9.0.0", + "html-entities": "^2.5.2", + "retry-request": "^7.0.0", + "teeny-request": "^9.0.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@google-cloud/logging": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/@google-cloud/logging/-/logging-11.2.0.tgz", + "integrity": "sha512-Ma94jvuoMpbgNniwtelOt8w82hxK62FuOXZonEv0Hyk3B+/YVuLG/SWNyY9yMso/RXnPEc1fP2qo9kDrjf/b2w==", + "license": "Apache-2.0", + "dependencies": { + "@google-cloud/common": "^5.0.0", + "@google-cloud/paginator": "^5.0.0", + "@google-cloud/projectify": "^4.0.0", + "@google-cloud/promisify": "^4.0.0", + "@opentelemetry/api": "^1.7.0", + "arrify": "^2.0.1", + "dot-prop": "^6.0.0", + "eventid": "^2.0.0", + "extend": "^3.0.2", + "gcp-metadata": "^6.0.0", + "google-auth-library": "^9.0.0", + "google-gax": "^4.0.3", + "on-finished": "^2.3.0", + "pumpify": "^2.0.1", + "stream-events": "^1.0.5", + "uuid": "^9.0.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@google-cloud/paginator": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-5.0.2.tgz", + "integrity": "sha512-DJS3s0OVH4zFDB1PzjxAsHqJT6sKVbRwwML0ZBP9PbU7Yebtu/7SWMRzvO2J3nUi9pRNITCfu4LJeooM2w4pjg==", + "license": "Apache-2.0", + "dependencies": { + "arrify": "^2.0.0", + "extend": "^3.0.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@google-cloud/projectify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-4.0.0.tgz", + "integrity": "sha512-MmaX6HeSvyPbWGwFq7mXdo0uQZLGBYCwziiLIGq5JVX+/bdI3SAq6bP98trV5eTWfLuvsMcIC1YJOF2vfteLFA==", + "license": "Apache-2.0", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@google-cloud/promisify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-4.0.0.tgz", + "integrity": "sha512-Orxzlfb9c67A15cq2JQEyVc7wEsmFBmHjZWZYQMUyJ1qivXyMwdyNOs9odi79hze+2zqdTtu1E19IM/FtqZ10g==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@google-cloud/run": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@google-cloud/run/-/run-1.5.0.tgz", + "integrity": "sha512-Ct0ZIuicd2O6fJHv7Lbwl4CcCWKK7NjACvUc4pOJVbKo75B5proOa7/9TrXVpI6oWu1n7EFx1s8xsavYHLxRAg==", + "license": "Apache-2.0", + "dependencies": { + "google-gax": "^4.0.3" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@grpc/grpc-js": { + "version": "1.12.4", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.12.4.tgz", + "integrity": "sha512-NBhrxEWnFh0FxeA0d//YP95lRFsSx2TNLEUQg4/W+5f/BMxcCjgOOIT24iD+ZB/tZw057j44DaIxja7w4XMrhg==", + "license": "Apache-2.0", + "dependencies": { + "@grpc/proto-loader": "^0.7.13", + "@js-sdsl/ordered-map": "^4.4.2" + }, + "engines": { + "node": ">=12.10.0" + } + }, + "node_modules/@grpc/proto-loader": { + "version": "0.7.13", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.13.tgz", + "integrity": "sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw==", + "license": "Apache-2.0", + "dependencies": { + "lodash.camelcase": "^4.3.0", + "long": "^5.0.0", + "protobufjs": "^7.2.5", + "yargs": "^17.7.2" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@js-sdsl/ordered-map": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", + "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, + "node_modules/@kwsites/file-exists": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", + "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==", + "license": "MIT", + "dependencies": { + "debug": "^4.1.1" + } + }, + "node_modules/@kwsites/file-exists/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@kwsites/file-exists/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/@kwsites/promise-deferred": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz", + "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==", + "license": "MIT" + }, + "node_modules/@opentelemetry/api": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", + "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", + "license": "Apache-2.0", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "license": "BSD-3-Clause" + }, + "node_modules/@smithy/abort-controller": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-3.1.9.tgz", + "integrity": "sha512-yiW0WI30zj8ZKoSYNx90no7ugVn3khlyH/z5W8qtKBtVE6awRALbhSG+2SAHA1r6bO/6M9utxYKVZ3PCJ1rWxw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/config-resolver": { + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-3.0.13.tgz", + "integrity": "sha512-Gr/qwzyPaTL1tZcq8WQyHhTZREER5R1Wytmz4WnVGL4onA3dNk6Btll55c8Vr58pLdvWZmtG8oZxJTw3t3q7Jg==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^3.1.12", + "@smithy/types": "^3.7.2", + "@smithy/util-config-provider": "^3.0.0", + "@smithy/util-middleware": "^3.0.11", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/core": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-2.5.5.tgz", + "integrity": "sha512-G8G/sDDhXA7o0bOvkc7bgai6POuSld/+XhNnWAbpQTpLv2OZPvyqQ58tLPPlz0bSNsXktldDDREIv1LczFeNEw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/middleware-serde": "^3.0.11", + "@smithy/protocol-http": "^4.1.8", + "@smithy/types": "^3.7.2", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-middleware": "^3.0.11", + "@smithy/util-stream": "^3.3.2", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/credential-provider-imds": { + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-3.2.8.tgz", + "integrity": "sha512-ZCY2yD0BY+K9iMXkkbnjo+08T2h8/34oHd0Jmh6BZUSZwaaGlGCyBT/3wnS7u7Xl33/EEfN4B6nQr3Gx5bYxgw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^3.1.12", + "@smithy/property-provider": "^3.1.11", + "@smithy/types": "^3.7.2", + "@smithy/url-parser": "^3.0.11", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/credential-provider-imds/node_modules/@smithy/property-provider": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz", + "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/eventstream-codec": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-3.1.10.tgz", + "integrity": "sha512-323B8YckSbUH0nMIpXn7HZsAVKHYHFUODa8gG9cHo0ySvA1fr5iWaNT+iIL0UCqUzG6QPHA3BSsBtRQou4mMqQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/crc32": "5.2.0", + "@smithy/types": "^3.7.2", + "@smithy/util-hex-encoding": "^3.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@smithy/eventstream-serde-browser": { + "version": "3.0.14", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-3.0.14.tgz", + "integrity": "sha512-kbrt0vjOIihW3V7Cqj1SXQvAI5BR8SnyQYsandva0AOR307cXAc+IhPngxIPslxTLfxwDpNu0HzCAq6g42kCPg==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/eventstream-serde-universal": "^3.0.13", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-config-resolver": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-3.0.11.tgz", + "integrity": "sha512-P2pnEp4n75O+QHjyO7cbw/vsw5l93K/8EWyjNCAAybYwUmj3M+hjSQZ9P5TVdUgEG08ueMAP5R4FkuSkElZ5tQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-node": { + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-3.0.13.tgz", + "integrity": "sha512-zqy/9iwbj8Wysmvi7Lq7XFLeDgjRpTbCfwBhJa8WbrylTAHiAu6oQTwdY7iu2lxigbc9YYr9vPv5SzYny5tCXQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/eventstream-serde-universal": "^3.0.13", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-universal": { + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-3.0.13.tgz", + "integrity": "sha512-L1Ib66+gg9uTnqp/18Gz4MDpJPKRE44geOjOQ2SVc0eiaO5l255ADziATZgjQjqumC7yPtp1XnjHlF1srcwjKw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/eventstream-codec": "^3.1.10", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/fetch-http-handler": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-4.1.2.tgz", + "integrity": "sha512-R7rU7Ae3ItU4rC0c5mB2sP5mJNbCfoDc8I5XlYjIZnquyUwec7fEo78F6DA3SmgJgkU1qTMcZJuGblxZsl10ZA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/protocol-http": "^4.1.8", + "@smithy/querystring-builder": "^3.0.11", + "@smithy/types": "^3.7.2", + "@smithy/util-base64": "^3.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@smithy/hash-node": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-3.0.11.tgz", + "integrity": "sha512-emP23rwYyZhQBvklqTtwetkQlqbNYirDiEEwXl2v0GYWMnCzxst7ZaRAnWuy28njp5kAH54lvkdG37MblZzaHA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.2", + "@smithy/util-buffer-from": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/invalid-dependency": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-3.0.11.tgz", + "integrity": "sha512-NuQmVPEJjUX6c+UELyVz8kUx8Q539EDeNwbRyu4IIF8MeV7hUtq1FB3SHVyki2u++5XLMFqngeMKk7ccspnNyQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + } + }, + "node_modules/@smithy/is-array-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-3.0.0.tgz", + "integrity": "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/middleware-content-length": { + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-3.0.13.tgz", + "integrity": "sha512-zfMhzojhFpIX3P5ug7jxTjfUcIPcGjcQYzB9t+rv0g1TX7B0QdwONW+ATouaLoD7h7LOw/ZlXfkq4xJ/g2TrIw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/protocol-http": "^4.1.8", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/middleware-endpoint": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-3.2.5.tgz", + "integrity": "sha512-VhJNs/s/lyx4weiZdXSloBgoLoS8osV0dKIain8nGmx7of3QFKu5BSdEuk1z/U8x9iwes1i+XCiNusEvuK1ijg==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^2.5.5", + "@smithy/middleware-serde": "^3.0.11", + "@smithy/node-config-provider": "^3.1.12", + "@smithy/shared-ini-file-loader": "^3.1.12", + "@smithy/types": "^3.7.2", + "@smithy/url-parser": "^3.0.11", + "@smithy/util-middleware": "^3.0.11", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/middleware-retry": { + "version": "3.0.29", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.29.tgz", + "integrity": "sha512-/FfI/N2tIVCG9escHYLLABJlNHbO1gWFSdMlvbPOTV+Y+Aa8Q1FuS7Yaghb8NUfFmGYjkbeIu3bnbta6KbarsA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^3.1.12", + "@smithy/protocol-http": "^4.1.8", + "@smithy/service-error-classification": "^3.0.11", + "@smithy/smithy-client": "^3.4.6", + "@smithy/types": "^3.7.2", + "@smithy/util-middleware": "^3.0.11", + "@smithy/util-retry": "^3.0.11", + "tslib": "^2.6.2", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/middleware-retry/node_modules/@smithy/util-retry": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.11.tgz", + "integrity": "sha512-hJUC6W7A3DQgaee3Hp9ZFcOxVDZzmBIRBPlUAk8/fSOEl7pE/aX7Dci0JycNOnm9Mfr0KV2XjIlUOcGWXQUdVQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/service-error-classification": "^3.0.11", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/middleware-serde": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-3.0.11.tgz", + "integrity": "sha512-KzPAeySp/fOoQA82TpnwItvX8BBURecpx6ZMu75EZDkAcnPtO6vf7q4aH5QHs/F1s3/snQaSFbbUMcFFZ086Mw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/middleware-stack": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-3.0.11.tgz", + "integrity": "sha512-1HGo9a6/ikgOMrTrWL/WiN9N8GSVYpuRQO5kjstAq4CvV59bjqnh7TbdXGQ4vxLD3xlSjfBjq5t1SOELePsLnA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/node-config-provider": { + "version": "3.1.12", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-3.1.12.tgz", + "integrity": "sha512-O9LVEu5J/u/FuNlZs+L7Ikn3lz7VB9hb0GtPT9MQeiBmtK8RSY3ULmsZgXhe6VAlgTw0YO+paQx4p8xdbs43vQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/property-provider": "^3.1.11", + "@smithy/shared-ini-file-loader": "^3.1.12", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/node-config-provider/node_modules/@smithy/property-provider": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz", + "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/node-http-handler": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-3.3.2.tgz", + "integrity": "sha512-t4ng1DAd527vlxvOfKFYEe6/QFBcsj7WpNlWTyjorwXXcKw3XlltBGbyHfSJ24QT84nF+agDha9tNYpzmSRZPA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/abort-controller": "^3.1.9", + "@smithy/protocol-http": "^4.1.8", + "@smithy/querystring-builder": "^3.0.11", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/property-provider": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-2.2.0.tgz", + "integrity": "sha512-+xiil2lFhtTRzXkx8F053AV46QnIw6e7MV8od5Mi68E1ICOjCeCHw2XfLnDEUHnT9WGUIkwcqavXjfwuJbGlpg==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/property-provider/node_modules/@smithy/types": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.12.0.tgz", + "integrity": "sha512-QwYgloJ0sVNBeBuBs65cIkTbfzV/Q6ZNPCJ99EICFEdJYG50nGIY/uYXp+TbsdJReIuPr0a0kXmCvren3MbRRw==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/protocol-http": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.8.tgz", + "integrity": "sha512-hmgIAVyxw1LySOwkgMIUN0kjN8TG9Nc85LJeEmEE/cNEe2rkHDUWhnJf2gxcSRFLWsyqWsrZGw40ROjUogg+Iw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/querystring-builder": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.11.tgz", + "integrity": "sha512-u+5HV/9uJaeLj5XTb6+IEF/dokWWkEqJ0XiaRRogyREmKGUgZnNecLucADLdauWFKUNbQfulHFEZEdjwEBjXRg==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.2", + "@smithy/util-uri-escape": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/querystring-parser": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-3.0.11.tgz", + "integrity": "sha512-Je3kFvCsFMnso1ilPwA7GtlbPaTixa3WwC+K21kmMZHsBEOZYQaqxcMqeFFoU7/slFjKDIpiiPydvdJm8Q/MCw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/service-error-classification": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-3.0.11.tgz", + "integrity": "sha512-QnYDPkyewrJzCyaeI2Rmp7pDwbUETe+hU8ADkXmgNusO1bgHBH7ovXJiYmba8t0fNfJx75fE8dlM6SEmZxheog==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/shared-ini-file-loader": { + "version": "3.1.12", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.12.tgz", + "integrity": "sha512-1xKSGI+U9KKdbG2qDvIR9dGrw3CNx+baqJfyr0igKEpjbHL5stsqAesYBzHChYHlelWtb87VnLWlhvfCz13H8Q==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/signature-v4": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-4.2.4.tgz", + "integrity": "sha512-5JWeMQYg81TgU4cG+OexAWdvDTs5JDdbEZx+Qr1iPbvo91QFGzjy0IkXAKaXUHqmKUJgSHK0ZxnCkgZpzkeNTA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^3.0.0", + "@smithy/protocol-http": "^4.1.8", + "@smithy/types": "^3.7.2", + "@smithy/util-hex-encoding": "^3.0.0", + "@smithy/util-middleware": "^3.0.11", + "@smithy/util-uri-escape": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/smithy-client": { + "version": "3.4.6", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.4.6.tgz", + "integrity": "sha512-j/WYdfzdx4asqb0YZch1rb6Y5OQcuTdXY7xnEMtc05diB5jfLQQtys9J/2lzmGKri9m9mUBrcnNTv3jbXvtk7A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^2.5.5", + "@smithy/middleware-endpoint": "^3.2.5", + "@smithy/middleware-stack": "^3.0.11", + "@smithy/protocol-http": "^4.1.8", + "@smithy/types": "^3.7.2", + "@smithy/util-stream": "^3.3.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/types": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.7.2.tgz", + "integrity": "sha512-bNwBYYmN8Eh9RyjS1p2gW6MIhSO2rl7X9QeLM8iTdcGRP+eDiIWDt66c9IysCc22gefKszZv+ubV9qZc7hdESg==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/url-parser": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-3.0.11.tgz", + "integrity": "sha512-TmlqXkSk8ZPhfc+SQutjmFr5FjC0av3GZP4B/10caK1SbRwe/v+Wzu/R6xEKxoNqL+8nY18s1byiy6HqPG37Aw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/querystring-parser": "^3.0.11", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + } + }, + "node_modules/@smithy/util-base64": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-3.0.0.tgz", + "integrity": "sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/util-body-length-browser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-3.0.0.tgz", + "integrity": "sha512-cbjJs2A1mLYmqmyVl80uoLTJhAcfzMOyPgjwAYusWKMdLeNtzmMz9YxNl3/jRLoxSS3wkqkf0jwNdtXWtyEBaQ==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + } + }, + "node_modules/@smithy/util-body-length-node": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-3.0.0.tgz", + "integrity": "sha512-Tj7pZ4bUloNUP6PzwhN7K386tmSmEET9QtQg0TgdNOnxhZvCssHji+oZTUIuzxECRfG8rdm2PMw2WCFs6eIYkA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/util-buffer-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-3.0.0.tgz", + "integrity": "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/util-config-provider": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-3.0.0.tgz", + "integrity": "sha512-pbjk4s0fwq3Di/ANL+rCvJMKM5bzAQdE5S/6RL5NXgMExFAi6UgQMPOm5yPaIWPpr+EOXKXRonJ3FoxKf4mCJQ==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/util-defaults-mode-browser": { + "version": "3.0.29", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.29.tgz", + "integrity": "sha512-7k0kOfDjnSM44GG74UnjEixtHmtF/do6pCNEvp1DQlFjktEz8pv06p9RSjxp2J3Lv6I3+Ba9FLfurpFeBv+Pvw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/property-provider": "^3.1.11", + "@smithy/smithy-client": "^3.4.6", + "@smithy/types": "^3.7.2", + "bowser": "^2.11.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@smithy/util-defaults-mode-browser/node_modules/@smithy/property-provider": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz", + "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/util-defaults-mode-node": { + "version": "3.0.29", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.29.tgz", + "integrity": "sha512-lu8jaXAt1TIVkTAKMuGdZwWQ1L03iV/n8WPbY5hdjcNqLg2ysp5DqiINmtuLL8EgzDv1TXvKDaBAN+9bGH4sEQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/config-resolver": "^3.0.13", + "@smithy/credential-provider-imds": "^3.2.8", + "@smithy/node-config-provider": "^3.1.12", + "@smithy/property-provider": "^3.1.11", + "@smithy/smithy-client": "^3.4.6", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@smithy/util-defaults-mode-node/node_modules/@smithy/property-provider": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz", + "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/util-endpoints": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-2.1.7.tgz", + "integrity": "sha512-tSfcqKcN/Oo2STEYCABVuKgJ76nyyr6skGl9t15hs+YaiU06sgMkN7QYjo0BbVw+KT26zok3IzbdSOksQ4YzVw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^3.1.12", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/util-hex-encoding": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-3.0.0.tgz", + "integrity": "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/util-middleware": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-3.0.11.tgz", + "integrity": "sha512-dWpyc1e1R6VoXrwLoLDd57U1z6CwNSdkM69Ie4+6uYh2GC7Vg51Qtan7ITzczuVpqezdDTKJGJB95fFvvjU/ow==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/util-retry": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-2.2.0.tgz", + "integrity": "sha512-q9+pAFPTfftHXRytmZ7GzLFFrEGavqapFc06XxzZFcSIGERXMerXxCitjOG1prVDR9QdjqotF40SWvbqcCpf8g==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/service-error-classification": "^2.1.5", + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@smithy/util-retry/node_modules/@smithy/service-error-classification": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-2.1.5.tgz", + "integrity": "sha512-uBDTIBBEdAQryvHdc5W8sS5YX7RQzF683XrHePVdFmAgKiMofU15FLSM0/HU03hKTnazdNRFa0YHS7+ArwoUSQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^2.12.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/util-retry/node_modules/@smithy/types": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.12.0.tgz", + "integrity": "sha512-QwYgloJ0sVNBeBuBs65cIkTbfzV/Q6ZNPCJ99EICFEdJYG50nGIY/uYXp+TbsdJReIuPr0a0kXmCvren3MbRRw==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/util-stream": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-3.3.2.tgz", + "integrity": "sha512-sInAqdiVeisUGYAv/FrXpmJ0b4WTFmciTRqzhb7wVuem9BHvhIG7tpiYHLDWrl2stOokNZpTTGqz3mzB2qFwXg==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/fetch-http-handler": "^4.1.2", + "@smithy/node-http-handler": "^3.3.2", + "@smithy/types": "^3.7.2", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-buffer-from": "^3.0.0", + "@smithy/util-hex-encoding": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/util-uri-escape": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz", + "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/util-utf8": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-3.0.0.tgz", + "integrity": "sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/util-waiter": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-3.2.0.tgz", + "integrity": "sha512-PpjSboaDUE6yl+1qlg3Si57++e84oXdWGbuFUSAciXsVfEZJJJupR2Nb0QuXHiunt2vGR+1PTizOMvnUPaG2Qg==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/abort-controller": "^3.1.9", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tootallnate/quickjs-emscripten": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", + "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", + "license": "MIT" + }, + "node_modules/@types/caseless": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.5.tgz", + "integrity": "sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==", + "license": "MIT" + }, + "node_modules/@types/datadog-metrics": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@types/datadog-metrics/-/datadog-metrics-0.6.1.tgz", + "integrity": "sha512-p6zVpfmNcXwtcXjgpz7do/fKyfndGhU5sGJVtb5Gn5PvLDiQUAgD0mI/itf/99sBi9DRxeyhFQ9dQF6OxxQNbA==", + "license": "MIT" + }, + "node_modules/@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.10.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.1.tgz", + "integrity": "sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "node_modules/@types/request": { + "version": "2.48.12", + "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.12.tgz", + "integrity": "sha512-G3sY+NpsA9jnwm0ixhAFQSJ3Q9JkpLZpJbI3GMv0mIAT0y3mRabYeINzal5WOChIiaTEGQYlHOKgkaM9EisWHw==", + "license": "MIT", + "dependencies": { + "@types/caseless": "*", + "@types/node": "*", + "@types/tough-cookie": "*", + "form-data": "^2.5.0" + } + }, + "node_modules/@types/request/node_modules/form-data": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.2.tgz", + "integrity": "sha512-GgwY0PS7DbXqajuGf4OYlsrIu3zgxD6Vvql43IBhm6MahqA5SK/7mwhtNj2AdH2z35YR34ujJ7BN+3fFC3jP5Q==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12", + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/@types/tough-cookie": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", + "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", + "license": "MIT" + }, + "node_modules/@types/uuid": { + "version": "9.0.8", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz", + "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==", + "license": "MIT" + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "license": "MIT", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/agent-base": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", + "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "license": "MIT", + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/ast-types": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/async-retry": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.1.tgz", + "integrity": "sha512-aiieFW/7h3hY0Bq5d+ktDBejxuwR78vRu9hDUdR8rNhSaQ29VzPL4AoIRG7D/c7tdenwOcKvgPM6tIxB3cB6HA==", + "license": "MIT", + "dependencies": { + "retry": "0.12.0" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/axios": { + "version": "1.7.9", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz", + "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/basic-ftp": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", + "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "license": "BSD-3-Clause", + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/bignumber.js": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", + "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bowser": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz", + "integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==", + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", + "license": "BSD-3-Clause" + }, + "node_modules/buildcheck": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/buildcheck/-/buildcheck-0.0.6.tgz", + "integrity": "sha512-8f9ZJCUXyT1M35Jx7MkBgmBMo3oHTTBIPLiY9xyL0pl3T5RwcPEY8cUHr5LBNfu/fk6c2T4DJZuVM/8ZZT2D2A==", + "optional": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "license": "MIT" + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "license": "MIT", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "license": "ISC", + "engines": { + "node": ">= 10" + } + }, + "node_modules/clipanion": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/clipanion/-/clipanion-3.2.1.tgz", + "integrity": "sha512-dYFdjLb7y1ajfxQopN05mylEpK9ZX0sO1/RfMXdfmwjlIsPkbh4p7A682x++zFPLDCo1x3p82dtljHf5cW2LKA==", + "license": "MIT", + "workspaces": [ + "website" + ], + "dependencies": { + "typanion": "^3.8.0" + }, + "peerDependencies": { + "typanion": "*" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "license": "MIT" + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "license": "MIT" + }, + "node_modules/cpu-features": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.10.tgz", + "integrity": "sha512-9IkYqtX3YHPCzoVg1Py+o9057a3i0fp7S530UWokCSaFVTc7CwXPRiOjRjBQQ18ZCNafx78YfnG+HALxtVmOGA==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "buildcheck": "~0.0.6", + "nan": "^2.19.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/data-uri-to-buffer": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/datadog-metrics": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/datadog-metrics/-/datadog-metrics-0.9.3.tgz", + "integrity": "sha512-BVsBX2t+4yA3tHs7DnB5H01cHVNiGJ/bHA8y6JppJDyXG7s2DLm6JaozPGpgsgVGd42Is1CHRG/yMDQpt877Xg==", + "license": "MIT", + "dependencies": { + "debug": "3.1.0", + "dogapi": "2.8.4" + } + }, + "node_modules/debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deep-object-diff": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/deep-object-diff/-/deep-object-diff-1.1.9.tgz", + "integrity": "sha512-Rn+RuwkmkDwCi2/oXOFS9Gsr5lJZu/yTGpK7wAaAIE75CC+LCGEZHpY6VQJa/RoJcrmaA/docWJZvYohlNkWPA==", + "license": "MIT" + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "license": "MIT", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/degenerator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", + "license": "MIT", + "dependencies": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/dogapi": { + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/dogapi/-/dogapi-2.8.4.tgz", + "integrity": "sha512-065fsvu5dB0o4+ENtLjZILvXMClDNH/yA9H6L8nsdcNiz9l0Hzpn7aQaCOPYXxqyzq4CRPOdwkFXUjDOXfRGbg==", + "license": "MIT", + "dependencies": { + "extend": "^3.0.2", + "json-bigint": "^1.0.0", + "lodash": "^4.17.21", + "minimist": "^1.2.5", + "rc": "^1.2.8" + }, + "bin": { + "dogapi": "bin/dogapi" + } + }, + "node_modules/dot-prop": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", + "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", + "license": "MIT", + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/duplexify": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.3.tgz", + "integrity": "sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==", + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.2" + } + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "license": "MIT", + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/ecc-jsbn/node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "license": "MIT" + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "license": "BSD-2-Clause", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/eventid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/eventid/-/eventid-2.0.1.tgz", + "integrity": "sha512-sPNTqiMokAvV048P2c9+foqVJzk49o6d4e0D/sq5jog3pw+4kBgyR0gaM1FM7Mx6Kzd9dztesh9oYz1LWWOpzw==", + "license": "Apache-2.0", + "dependencies": { + "uuid": "^8.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eventid/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "license": "MIT", + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-3.0.0.tgz", + "integrity": "sha512-hKKNajm46uNmTlhHSyZkmToAc56uZJwYq7yrciZjqOxnlfQwERDQJmHPUp7m1m9wx8vgOe8IaCKZ5Kv2k1DdCQ==", + "license": "MIT", + "dependencies": { + "fastest-levenshtein": "^1.0.7" + } + }, + "node_modules/fast-uri": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.3.tgz", + "integrity": "sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==", + "license": "BSD-3-Clause" + }, + "node_modules/fast-xml-parser": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.0.tgz", + "integrity": "sha512-/PlTQCI96+fZMAOLMZK4CWG1ItCbfZ/0jx7UIJFChPNrx7tcEgerUgWbeieCM9MfHInUDyK8DWYZ+YrywDJuTg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + }, + { + "type": "paypal", + "url": "https://paypal.me/naturalintelligence" + } + ], + "license": "MIT", + "dependencies": { + "strnum": "^1.0.5" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "license": "MIT", + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "license": "ISC" + }, + "node_modules/fuzzy": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/fuzzy/-/fuzzy-0.1.3.tgz", + "integrity": "sha512-/gZffu4ykarLrCiP3Ygsa86UAo1E5vEVlvTrpkKywXSbP9Xhln3oSp9QSV57gEq3JFFpGJ4GZ+5zdEp3FcUh4w==", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/gaxios": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.1.tgz", + "integrity": "sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==", + "license": "Apache-2.0", + "dependencies": { + "extend": "^3.0.2", + "https-proxy-agent": "^7.0.1", + "is-stream": "^2.0.0", + "node-fetch": "^2.6.9", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/gcp-metadata": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz", + "integrity": "sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==", + "license": "Apache-2.0", + "dependencies": { + "gaxios": "^6.0.0", + "json-bigint": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-uri": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.4.tgz", + "integrity": "sha512-E1b1lFFLvLgak2whF2xDBcOy6NLVGZBqqjJjsIhvopKfWWEi64pLVTWWehV8KlLerZkfNTA95sTe2OdJKm1OzQ==", + "license": "MIT", + "dependencies": { + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.2", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/get-uri/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/get-uri/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/google-auth-library": { + "version": "9.15.0", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.15.0.tgz", + "integrity": "sha512-7ccSEJFDFO7exFbO6NRyC+xH8/mZ1GZGG2xxx9iHxZWcjUjJpjWxIMw3cofAKcueZ6DATiukmmprD7yavQHOyQ==", + "license": "Apache-2.0", + "dependencies": { + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "gaxios": "^6.1.1", + "gcp-metadata": "^6.1.0", + "gtoken": "^7.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/google-gax": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-4.4.1.tgz", + "integrity": "sha512-Phyp9fMfA00J3sZbJxbbB4jC55b7DBjE3F6poyL3wKMEBVKA79q6BGuHcTiM28yOzVql0NDbRL8MLLh8Iwk9Dg==", + "license": "Apache-2.0", + "dependencies": { + "@grpc/grpc-js": "^1.10.9", + "@grpc/proto-loader": "^0.7.13", + "@types/long": "^4.0.0", + "abort-controller": "^3.0.0", + "duplexify": "^4.0.0", + "google-auth-library": "^9.3.0", + "node-fetch": "^2.7.0", + "object-hash": "^3.0.0", + "proto3-json-serializer": "^2.0.2", + "protobufjs": "^7.3.2", + "retry-request": "^7.0.0", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/gtoken": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz", + "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==", + "license": "MIT", + "dependencies": { + "gaxios": "^6.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/html-entities": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", + "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ], + "license": "MIT" + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/http-proxy-agent/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/http-proxy-agent/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/https-proxy-agent/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", + "license": "MIT" + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC" + }, + "node_modules/inquirer": { + "version": "8.2.6", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.6.tgz", + "integrity": "sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==", + "license": "MIT", + "dependencies": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6", + "wrap-ansi": "^6.0.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/inquirer-checkbox-plus-prompt": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/inquirer-checkbox-plus-prompt/-/inquirer-checkbox-plus-prompt-1.4.2.tgz", + "integrity": "sha512-W8/NL9x5A81Oq9ZfbYW5c1LuwtAhc/oB/u9YZZejna0pqrajj27XhnUHygJV0Vn5TvcDy1VJcD2Ld9kTk40dvg==", + "license": "MIT", + "dependencies": { + "chalk": "4.1.2", + "cli-cursor": "^3.1.0", + "figures": "^3.0.0", + "lodash": "^4.17.5", + "rxjs": "^6.6.7" + }, + "peerDependencies": { + "inquirer": "< 9.x" + } + }, + "node_modules/inquirer-checkbox-plus-prompt/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/inquirer-checkbox-plus-prompt/node_modules/rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/inquirer-checkbox-plus-prompt/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "license": "0BSD" + }, + "node_modules/inquirer/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "license": "MIT", + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/ip-address/node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "license": "BSD-3-Clause" + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", + "license": "MIT" + }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "license": "MIT", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, + "node_modules/jszip": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", + "license": "(MIT OR GPL-3.0-or-later)", + "dependencies": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "setimmediate": "^1.0.5" + } + }, + "node_modules/jszip/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/jszip/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/jszip/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/jwa": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", + "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "license": "MIT", + "dependencies": { + "jwa": "^2.0.0", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "license": "MIT", + "dependencies": { + "immediate": "~3.0.5" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "license": "MIT" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/long": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==", + "license": "Apache-2.0" + }, + "node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "license": "ISC" + }, + "node_modules/nan": { + "version": "2.22.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.22.0.tgz", + "integrity": "sha512-nbajikzWTMwsW+eSsNm3QwlOs7het9gGJU5dDZzRTQGk03vyBOauxgI4VakDzE0PtsGTmXPsXTbbjVhRwR5mpw==", + "license": "MIT", + "optional": true + }, + "node_modules/netmask": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", + "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "license": "MIT", + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pac-proxy-agent": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.1.0.tgz", + "integrity": "sha512-Z5FnLVVZSnX7WjBg0mhDtydeRZ1xMcATZThjySQUHqr+0ksP8kqaw23fNKkaaN/Z8gwLUs/W7xdl0I75eP2Xyw==", + "license": "MIT", + "dependencies": { + "@tootallnate/quickjs-emscripten": "^0.23.0", + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "get-uri": "^6.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.6", + "pac-resolver": "^7.0.1", + "socks-proxy-agent": "^8.0.5" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-proxy-agent/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/pac-proxy-agent/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/pac-resolver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", + "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", + "license": "MIT", + "dependencies": { + "degenerator": "^5.0.0", + "netmask": "^2.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "license": "(MIT AND Zlib)" + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "license": "MIT" + }, + "node_modules/proto3-json-serializer": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-2.0.2.tgz", + "integrity": "sha512-SAzp/O4Yh02jGdRc+uIrGoe87dkN/XtwxfZ4ZyafJHymd79ozp5VG5nyZ7ygqPM5+cpLDjjGnYFUkngonyDPOQ==", + "license": "Apache-2.0", + "dependencies": { + "protobufjs": "^7.2.5" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/protobufjs": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.4.0.tgz", + "integrity": "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/proxy-agent": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz", + "integrity": "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.1", + "https-proxy-agent": "^7.0.6", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.1.0", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.5" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/proxy-agent/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/proxy-agent/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, + "node_modules/pump": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", + "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/pumpify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-2.0.1.tgz", + "integrity": "sha512-m7KOje7jZxrmutanlkS1daj1dS6z6BgslzOXmcSEpIlCxM3VJH7lG5QLeck/6hgF6F4crFf01UtQmNsJfweTAw==", + "license": "MIT", + "dependencies": { + "duplexify": "^4.1.1", + "inherits": "^2.0.3", + "pump": "^3.0.0" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/retry-request": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-7.0.2.tgz", + "integrity": "sha512-dUOvLMJ0/JJYEn8NrpOaGNE7X3vpI5XlZS/u0ANjqtcZVKnIxP7IgCFwrKTxENw29emmwug53awKtaMm4i9g5w==", + "license": "MIT", + "dependencies": { + "@types/request": "^2.48.8", + "extend": "^3.0.2", + "teeny-request": "^9.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/sax": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", + "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", + "license": "ISC" + }, + "node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "license": "MIT" + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "license": "ISC" + }, + "node_modules/simple-git": { + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.16.0.tgz", + "integrity": "sha512-zuWYsOLEhbJRWVxpjdiXl6eyAyGo/KzVW+KFhhw9MqEEJttcq+32jTWSGyxTdf9e/YCohxRE+9xpWFj9FdiJNw==", + "license": "MIT", + "dependencies": { + "@kwsites/file-exists": "^1.1.1", + "@kwsites/promise-deferred": "^1.1.1", + "debug": "^4.3.4" + }, + "funding": { + "type": "github", + "url": "https://github.com/steveukx/git-js?sponsor=1" + } + }, + "node_modules/simple-git/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/simple-git/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", + "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", + "license": "MIT", + "dependencies": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", + "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/socks-proxy-agent/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/socks-proxy-agent/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "license": "BSD-3-Clause" + }, + "node_modules/ssh2": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/ssh2/-/ssh2-1.16.0.tgz", + "integrity": "sha512-r1X4KsBGedJqo7h8F5c4Ybpcr5RjyP+aWIG007uBPRjmdQWfEiVLzSK71Zji1B9sKxwaCvD8y8cwSkYrlLiRRg==", + "hasInstallScript": true, + "dependencies": { + "asn1": "^0.2.6", + "bcrypt-pbkdf": "^1.0.2" + }, + "engines": { + "node": ">=10.16.0" + }, + "optionalDependencies": { + "cpu-features": "~0.0.10", + "nan": "^2.20.0" + } + }, + "node_modules/ssh2-streams": { + "version": "0.4.10", + "resolved": "https://registry.npmjs.org/ssh2-streams/-/ssh2-streams-0.4.10.tgz", + "integrity": "sha512-8pnlMjvnIZJvmTzUIIA5nT4jr2ZWNNVHwyXfMGdRJbug9TpI3kd99ffglgfSWqujVv/0gxwMsDn9j9RVst8yhQ==", + "dependencies": { + "asn1": "~0.2.0", + "bcrypt-pbkdf": "^1.0.2", + "streamsearch": "~0.1.2" + }, + "engines": { + "node": ">=5.2.0" + } + }, + "node_modules/sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "license": "MIT", + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sshpk/node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "license": "MIT" + }, + "node_modules/stream-events": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", + "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", + "license": "MIT", + "dependencies": { + "stubs": "^3.0.0" + } + }, + "node_modules/stream-shift": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", + "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==", + "license": "MIT" + }, + "node_modules/streamsearch": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", + "integrity": "sha512-jos8u++JKm0ARcSUTAZXOVC0mSox7Bhn6sBgty73P1f3JGf7yG2clTbBNHUdde/kdvP2FESam+vM6l8jBrNxHA==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strnum": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", + "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==", + "license": "MIT" + }, + "node_modules/stubs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", + "integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==", + "license": "MIT" + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", + "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/teeny-request": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-9.0.0.tgz", + "integrity": "sha512-resvxdc6Mgb7YEThw6G6bExlXKkv6+YbuzGg9xuXxSgxJF7Ozs+o8Y9+2R3sArdWdW8nOokoQb1yrpFB0pQK2g==", + "license": "Apache-2.0", + "dependencies": { + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "node-fetch": "^2.6.9", + "stream-events": "^1.0.5", + "uuid": "^9.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/teeny-request/node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/teeny-request/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/teeny-request/node_modules/http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "license": "MIT", + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/teeny-request/node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/teeny-request/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "license": "MIT", + "dependencies": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "license": "MIT" + }, + "node_modules/tiny-async-pool": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tiny-async-pool/-/tiny-async-pool-2.1.0.tgz", + "integrity": "sha512-ltAHPh/9k0STRQqaoUX52NH4ZQYAJz24ZAEwf1Zm+HYg3l9OXTWeqWKyYsHu40wF/F0rxd2N2bk5sLvX2qlSvg==", + "license": "MIT" + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "license": "MIT", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "license": "Unlicense" + }, + "node_modules/typanion": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/typanion/-/typanion-3.14.0.tgz", + "integrity": "sha512-ZW/lVMRabETuYCd9O9ZvMhAh8GslSqaUjxmK/JLPCh6l73CvLBiuXswj/+7LdnWOgYsQ130FqLzFz5aGT4I3Ug==", + "license": "MIT", + "workspaces": [ + "website" + ] + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "license": "MIT" + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "license": "MIT", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + }, + "node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "license": "MIT", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml2js": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", + "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", + "license": "MIT", + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "license": "MIT", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yamux-js": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/yamux-js/-/yamux-js-0.1.2.tgz", + "integrity": "sha512-bhsPlPZ9xB4Dawyf6nkS58u4F3IvGCaybkEKGnneUeepcI7MPoG3Tt6SaKCU5x/kP2/2w20Qm/GqbpwAM16vYw==", + "license": "MIT" + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + } + } +} diff --git a/src/ci/package.json b/src/ci/package.json new file mode 100644 index 00000000000..91f21e5531e --- /dev/null +++ b/src/ci/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "@datadog/datadog-ci": "^2.45.1" + } +} diff --git a/src/ci/scripts/upload-build-metrics.py b/src/ci/scripts/upload-build-metrics.py index 23061884a39..49c068c9a40 100644 --- a/src/ci/scripts/upload-build-metrics.py +++ b/src/ci/scripts/upload-build-metrics.py @@ -9,8 +9,8 @@ It expects the following environment variables: - DATADOG_API_KEY: DataDog API token - DD_GITHUB_JOB_NAME: Name of the current GitHub Actions job -And it also expects the presence of a binary called `datadog-ci` to be in PATH. -It can be installed with `npm install -g @datadog/datadog-ci`. +It expects the presence of a binary called `datadog-ci` inside `node_modules`. +It can be installed with `npm ci` at `src/ci`. Usage: ```bash @@ -50,16 +50,14 @@ def upload_datadog_measure(name: str, value: float): """ print(f"Metric {name}: {value:.4f}") - datadog_cmd = "datadog-ci" - if os.getenv("GITHUB_ACTIONS") is not None and sys.platform.lower().startswith( - "win" - ): + cmd = "npx" + if os.getenv("GITHUB_ACTIONS") is not None and sys.platform.lower().startswith("win"): # Due to weird interaction of MSYS2 and Python, we need to use an absolute path, # and also specify the ".cmd" at the end. See https://github.com/rust-lang/rust/pull/125771. - datadog_cmd = "C:\\npm\\prefix\\datadog-ci.cmd" + cmd = "C:\\Program Files\\nodejs\\npx.cmd" subprocess.run( - [datadog_cmd, "measure", "--level", "job", "--measures", f"{name}:{value}"], + [cmd, "datadog-ci", "measure", "--level", "job", "--measures", f"{name}:{value}"], check=False, ) diff --git a/src/doc/book b/src/doc/book -Subproject 9900d976bbfecf4e8124da54351a9ad85ee3c7f +Subproject ad2011d3bcad9f152d034faf7635c22506839d5 diff --git a/src/doc/edition-guide b/src/doc/edition-guide -Subproject 128669297c8a7fdf771042eaec18b8adfaeaf0c +Subproject bc4ce51e1d4dacb9350a92e95f6159a42de2f8c diff --git a/src/doc/nomicon b/src/doc/nomicon -Subproject 0674321898cd454764ab69702819d39a919afd6 +Subproject 97e84a38c94bf9362b11284c20b2cb4adaa1e86 diff --git a/src/doc/reference b/src/doc/reference -Subproject ede56d1bbe132bac476b5029cd6d7508ca9572e +Subproject 9f41bc11342d46544ae0732caf14ec0bcaf2737 diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example -Subproject e1d1f2cdcee4d52b9a01ff7c448be4372a377b7 +Subproject 76406337f4131253443aea0ed7e7f451b464117 diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide -Subproject b21d99b770f9aceb0810c843847c52f86f45d2e +Subproject 7f7ba48f04abc2ad25e52f30b5e2bffa286b019 diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index f3d8a4edd6c..1e9f5a33fc7 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -66,6 +66,7 @@ - [powerpc-unknown-openbsd](platform-support/powerpc-unknown-openbsd.md) - [powerpc-unknown-linux-muslspe](platform-support/powerpc-unknown-linux-muslspe.md) - [powerpc64-ibm-aix](platform-support/aix.md) + - [powerpc64le-unknown-linux-musl](platform-support/powerpc64le-unknown-linux-musl.md) - [riscv32e*-unknown-none-elf](platform-support/riscv32e-unknown-none-elf.md) - [riscv32i*-unknown-none-elf](platform-support/riscv32-unknown-none-elf.md) - [riscv32im-risc0-zkvm-elf](platform-support/riscv32im-risc0-zkvm-elf.md) @@ -75,6 +76,7 @@ - [s390x-unknown-linux-gnu](platform-support/s390x-unknown-linux-gnu.md) - [s390x-unknown-linux-musl](platform-support/s390x-unknown-linux-musl.md) - [sparc-unknown-none-elf](./platform-support/sparc-unknown-none-elf.md) + - [sparcv9-sun-solaris](platform-support/solaris.md) - [*-pc-windows-gnullvm](platform-support/pc-windows-gnullvm.md) - [\*-nto-qnx-\*](platform-support/nto-qnx.md) - [*-unikraft-linux-musl](platform-support/unikraft-linux-musl.md) @@ -93,6 +95,7 @@ - [wasm64-unknown-unknown](platform-support/wasm64-unknown-unknown.md) - [\*-win7-windows-msvc](platform-support/win7-windows-msvc.md) - [x86_64-fortanix-unknown-sgx](platform-support/x86_64-fortanix-unknown-sgx.md) + - [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) - [xtensa-\*-none-elf](platform-support/xtensa.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 3dbcfe97036..db6612f9fff 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -97,6 +97,7 @@ target | notes `powerpc-unknown-linux-gnu` | PowerPC Linux (kernel 3.2, glibc 2.17) `powerpc64-unknown-linux-gnu` | PPC64 Linux (kernel 3.2, glibc 2.17) `powerpc64le-unknown-linux-gnu` | PPC64LE Linux (kernel 3.10, glibc 2.17) +[`powerpc64le-unknown-linux-musl`](platform-support/powerpc64le-unknown-linux-musl.md) | PPC64LE Linux (kernel 4.19, musl 1.2.3) [`riscv64gc-unknown-linux-gnu`](platform-support/riscv64gc-unknown-linux-gnu.md) | RISC-V Linux (kernel 4.20, glibc 2.29) [`riscv64gc-unknown-linux-musl`](platform-support/riscv64gc-unknown-linux-musl.md) | RISC-V Linux (kernel 4.20, musl 1.2.3) [`s390x-unknown-linux-gnu`](platform-support/s390x-unknown-linux-gnu.md) | S390x Linux (kernel 3.2, glibc 2.17) @@ -180,7 +181,7 @@ target | std | notes `riscv64gc-unknown-none-elf` | * | Bare RISC-V (RV64IMAFDC ISA) `riscv64imac-unknown-none-elf` | * | Bare RISC-V (RV64IMAC ISA) `sparc64-unknown-linux-gnu` | ✓ | SPARC Linux (kernel 4.4, glibc 2.23) -`sparcv9-sun-solaris` | ✓ | SPARC Solaris 11, illumos +[`sparcv9-sun-solaris`](platform-support/solaris.md) | ✓ | SPARC V9 Solaris 11.4 [`thumbv6m-none-eabi`](platform-support/thumbv6m-none-eabi.md) | * | Bare Armv6-M [`thumbv7em-none-eabi`](platform-support/thumbv7em-none-eabi.md) | * | Bare Armv7E-M [`thumbv7em-none-eabihf`](platform-support/thumbv7em-none-eabi.md) | * | Bare Armv7E-M, hardfloat @@ -201,7 +202,7 @@ target | std | notes [`x86_64-fortanix-unknown-sgx`](platform-support/x86_64-fortanix-unknown-sgx.md) | ✓ | [Fortanix ABI] for 64-bit Intel SGX [`x86_64-unknown-fuchsia`](platform-support/fuchsia.md) | ✓ | 64-bit x86 Fuchsia [`x86_64-linux-android`](platform-support/android.md) | ✓ | 64-bit x86 Android -`x86_64-pc-solaris` | ✓ | 64-bit Solaris 11, illumos +[`x86_64-pc-solaris`](platform-support/solaris.md) | ✓ | 64-bit x86 Solaris 11.4 [`x86_64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | 64-bit x86 MinGW (Windows 10+), LLVM ABI `x86_64-unknown-linux-gnux32` | ✓ | 64-bit Linux (x32 ABI) (kernel 4.15, glibc 2.27) [`x86_64-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | x86_64 OpenHarmony @@ -348,7 +349,6 @@ target | std | host | notes `powerpc-unknown-freebsd` | ? | | PowerPC FreeBSD `powerpc64-unknown-linux-musl` | ? | | 64-bit PowerPC Linux with musl 1.2.3 [`powerpc64-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | -`powerpc64le-unknown-linux-musl` | ? | | 64-bit PowerPC Linux with musl 1.2.3, Little Endian [`powerpc64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/powerpc64 [`powerpc64-ibm-aix`](platform-support/aix.md) | ? | | 64-bit AIX (7.2 and newer) `riscv32gc-unknown-linux-gnu` | ✓ | | RISC-V Linux (kernel 5.4, glibc 2.33) diff --git a/src/doc/rustc/src/platform-support/pc-windows-gnullvm.md b/src/doc/rustc/src/platform-support/pc-windows-gnullvm.md index ed55bcf4f35..89c4cdb2afc 100644 --- a/src/doc/rustc/src/platform-support/pc-windows-gnullvm.md +++ b/src/doc/rustc/src/platform-support/pc-windows-gnullvm.md @@ -17,9 +17,9 @@ Target triples available so far: ## Requirements The easiest way to obtain these targets is cross-compilation, but native build from `x86_64-pc-windows-gnu` is possible with few hacks which I don't recommend. -Std support is expected to be on pair with `*-pc-windows-gnu`. +Std support is expected to be on par with `*-pc-windows-gnu`. -Binaries for this target should be at least on pair with `*-pc-windows-gnu` in terms of requirements and functionality. +Binaries for this target should be at least on par with `*-pc-windows-gnu` in terms of requirements and functionality. Those targets follow Windows calling convention for `extern "C"`. diff --git a/src/doc/rustc/src/platform-support/powerpc64le-unknown-linux-musl.md b/src/doc/rustc/src/platform-support/powerpc64le-unknown-linux-musl.md new file mode 100644 index 00000000000..3bd3f5d8b7f --- /dev/null +++ b/src/doc/rustc/src/platform-support/powerpc64le-unknown-linux-musl.md @@ -0,0 +1,48 @@ +# powerpc64le-unknown-linux-musl + +**Tier: 2** + +Target for 64-bit little endian PowerPC Linux programs using musl libc. + +## Target maintainers + +- [@Gelbpunkt](https://github.com/Gelbpunkt) +- [@famfo](https://github.com/famfo) +- [@neuschaefer](https://github.com/neuschaefer) + +## Requirements + +Building the target itself requires a 64-bit little endian PowerPC compiler that is supported by `cc-rs`. + +## Building the target + +The target can be built by enabling it for a `rustc` build. + +```toml +[build] +target = ["powerpc64le-unknown-linux-musl"] +``` + +Make sure your C compiler is included in `$PATH`, then add it to the `config.toml`: + +```toml +[target.powerpc64le-unknown-linux-musl] +cc = "powerpc64le-linux-musl-gcc" +cxx = "powerpc64le-linux-musl-g++" +ar = "powerpc64le-linux-musl-ar" +linker = "powerpc64le-linux-musl-gcc" +``` + +## Building Rust programs + +This target are distributed through `rustup`, and otherwise require no +special configuration. + +## Cross-compilation + +This target can be cross-compiled from any host. + +## Testing + +This target can be tested as normal with `x.py` on a 64-bit little endian +PowerPC host or via QEMU emulation. diff --git a/src/doc/rustc/src/platform-support/solaris.md b/src/doc/rustc/src/platform-support/solaris.md new file mode 100644 index 00000000000..1e0a241f840 --- /dev/null +++ b/src/doc/rustc/src/platform-support/solaris.md @@ -0,0 +1,32 @@ +# sparcv9-sun-solaris +# x86_64-pc-solaris + +**Tier: 2** + +Rust for Solaris operating system. + +## Target maintainers + +- Petr Sumbera `sumbera@volny.cz`, https://github.com/psumbera + +## Requirements + +Binary built for this target is expected to run on sparcv9 or x86_64, and Solaris 11.4. + +## Testing + +For testing you can download Oracle Solaris 11.4 CBE release from: + + https://www.oracle.com/uk/solaris/solaris11/downloads/solaris-downloads.html + +Solaris CBE release is also available for GitHub CI: + + https://github.com/vmactions/solaris-vm + +Latest Solaris 11.4 SRU can be tested at Compile farm project: + + https://portal.cfarm.net/machines/list/ (cfarm215, cfarm215) + +There are no official Rust binaries for Solaris available for Rustup yet. But you can eventually download unofficial from: + + https://github.com/psumbera/solaris-rust diff --git a/src/doc/rustdoc/src/read-documentation/search.md b/src/doc/rustdoc/src/read-documentation/search.md index 718d2201c3a..e06dcdb7ed2 100644 --- a/src/doc/rustdoc/src/read-documentation/search.md +++ b/src/doc/rustdoc/src/read-documentation/search.md @@ -149,12 +149,16 @@ will match these queries: * `&mut Read -> Result<Vec<u8>, Error>` * `Read -> Result<Vec<u8>, Error>` * `Read -> Result<Vec<u8>>` -* `Read -> u8` +* `Read -> Vec<u8>` But it *does not* match `Result<Vec, u8>` or `Result<u8<Vec>>`, because those are nested incorrectly, and it does not match `Result<Error, Vec<u8>>` or `Result<Error>`, because those are -in the wrong order. +in the wrong order. It also does not match `Read -> u8`, because +only [certain generic wrapper types] can be left out, and `Vec` isn't +one of them. + +[certain generic wrapper types]: #wrappers-that-can-be-omitted To search for a function that accepts a function as a parameter, like `Iterator::all`, wrap the nested signature in parenthesis, @@ -165,6 +169,18 @@ but you need to know which one you want. [iterator-all]: ../../std/vec/struct.Vec.html?search=Iterator<T>%2C+(T+->+bool)+->+bool&filter-crate=std +### Wrappers that can be omitted + +* References +* Box +* Rc +* Arc +* Option +* Result +* From +* Into +* Future + ### Primitives with Special Syntax | Shorthand | Explicit names | @@ -234,11 +250,6 @@ Most of these limitations should be addressed in future version of Rustdoc. that you don't want a type parameter, you can force it to match something else by giving it a different prefix like `struct:T`. - * It's impossible to search for references or pointers. The - wrapped types can be searched for, so a function that takes `&File` can - be found with `File`, but you'll get a parse error when typing an `&` - into the search field. - * Searching for lifetimes is not supported. * It's impossible to search based on the length of an array. diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index db8426492ee..d1d42e47322 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -207,7 +207,7 @@ To do so, the `#[doc(keyword = "...")]` attribute is used. Example: #![allow(internal_features)] /// Some documentation about the keyword. -#[doc(keyword = "keyword")] +#[doc(keyword = "break")] mod empty_mod {} ``` @@ -315,7 +315,7 @@ Markdown file, the URL given to `--markdown-playground-url` will take precedence `--playground-url` and `#![doc(html_playground_url = "url")]` are present when rendering crate docs, the attribute will take precedence. -### `--sort-modules-by-appearance`: control how items on module pages are sorted +## `--sort-modules-by-appearance`: control how items on module pages are sorted Using this flag looks like this: @@ -328,7 +328,7 @@ some consideration for their stability, and names that end in a number). Giving `rustdoc` will disable this sorting and instead make it print the items in the order they appear in the source. -### `--show-type-layout`: add a section to each type's docs describing its memory layout +## `--show-type-layout`: add a section to each type's docs describing its memory layout * Tracking issue: [#113248](https://github.com/rust-lang/rust/issues/113248) @@ -346,7 +346,7 @@ of that type will take in memory. Note that most layout information is **completely unstable** and may even differ between compilations. -### `--resource-suffix`: modifying the name of CSS/JavaScript in crate docs +## `--resource-suffix`: modifying the name of CSS/JavaScript in crate docs * Tracking issue: [#54765](https://github.com/rust-lang/rust/issues/54765) @@ -361,7 +361,7 @@ all these files are linked from every page, changing where they are can be cumbe specially cache them. This flag will rename all these files in the output to include the suffix in the filename. For example, `light.css` would become `light-suf.css` with the above command. -### `--extern-html-root-url`: control how rustdoc links to non-local crates +## `--extern-html-root-url`: control how rustdoc links to non-local crates Using this flag looks like this: @@ -376,7 +376,7 @@ flags to control that behavior. When the `--extern-html-root-url` flag is given one of your dependencies, rustdoc use that URL for those docs. Keep in mind that if those docs exist in the output directory, those local docs will still override this flag. -### `-Z force-unstable-if-unmarked` +## `-Z force-unstable-if-unmarked` Using this flag looks like this: @@ -389,7 +389,7 @@ This is an internal flag intended for the standard library and compiler that app allows `rustdoc` to be able to generate documentation for the compiler crates and the standard library, as an equivalent command-line argument is provided to `rustc` when building those crates. -### `--index-page`: provide a top-level landing page for docs +## `--index-page`: provide a top-level landing page for docs This feature allows you to generate an index-page with a given markdown file. A good example of it is the [rust documentation index](https://doc.rust-lang.org/nightly/index.html). @@ -398,18 +398,18 @@ With this, you'll have a page which you can customize as much as you want at the Using `index-page` option enables `enable-index-page` option as well. -### `--enable-index-page`: generate a default index page for docs +## `--enable-index-page`: generate a default index page for docs This feature allows the generation of a default index-page which lists the generated crates. -### `--nocapture`: disable output capture for test +## `--nocapture`: disable output capture for test When this flag is used with `--test`, the output (stdout and stderr) of your tests won't be captured by rustdoc. Instead, the output will be directed to your terminal, as if you had run the test executable manually. This is especially useful for debugging your tests! -### `--check`: only checks the documentation +## `--check`: only checks the documentation When this flag is supplied, rustdoc will type check and lint your code, but will not generate any documentation or run your doctests. @@ -420,7 +420,7 @@ Using this flag looks like: rustdoc -Z unstable-options --check src/lib.rs ``` -### `--static-root-path`: control how static files are loaded in HTML output +## `--static-root-path`: control how static files are loaded in HTML output Using this flag looks like this: @@ -435,7 +435,7 @@ JavaScript, and font files in a single location, rather than duplicating it once files like the search index will still load from the documentation root, but anything that gets renamed with `--resource-suffix` will load from the given path. -### `--persist-doctests`: persist doctest executables after running +## `--persist-doctests`: persist doctest executables after running * Tracking issue: [#56925](https://github.com/rust-lang/rust/issues/56925) @@ -449,7 +449,7 @@ This flag allows you to keep doctest executables around after they're compiled o Usually, rustdoc will immediately discard a compiled doctest after it's been tested, but with this option, you can keep those binaries around for farther testing. -### `--show-coverage`: calculate the percentage of items with documentation +## `--show-coverage`: calculate the percentage of items with documentation * Tracking issue: [#58154](https://github.com/rust-lang/rust/issues/58154) @@ -500,7 +500,7 @@ Calculating code examples follows these rules: * typedef 2. If one of the previously listed items has a code example, then it'll be counted. -#### JSON output +### JSON output When using `--output-format json` with this option, it will display the coverage information in JSON format. For example, here is the JSON for a file with one documented item and one @@ -522,7 +522,7 @@ Note that the third item is the crate root, which in this case is undocumented. If you want the JSON output to be displayed on `stdout` instead of having a file generated, you can use `-o -`. -### `-w`/`--output-format`: output format +## `-w`/`--output-format`: output format `--output-format json` emits documentation in the experimental [JSON format](https://doc.rust-lang.org/nightly/nightly-rustc/rustdoc_json_types/). `--output-format html` has no effect, @@ -542,7 +542,7 @@ It can also be used with `--show-coverage`. Take a look at its [documentation](#--show-coverage-calculate-the-percentage-of-items-with-documentation) for more information. -### `--enable-per-target-ignores`: allow `ignore-foo` style filters for doctests +## `--enable-per-target-ignores`: allow `ignore-foo` style filters for doctests * Tracking issue: [#64245](https://github.com/rust-lang/rust/issues/64245) @@ -577,7 +577,7 @@ struct Foo; In older versions, this will be ignored on all targets, but on newer versions `ignore-gnu` will override `ignore`. -### `--runtool`, `--runtool-arg`: program to run tests with; args to pass to it +## `--runtool`, `--runtool-arg`: program to run tests with; args to pass to it * Tracking issue: [#64245](https://github.com/rust-lang/rust/issues/64245) @@ -596,7 +596,7 @@ $ rustdoc src/lib.rs -Z unstable-options --runtool valgrind Another use case would be to run a test inside an emulator, or through a Virtual Machine. -### `--with-examples`: include examples of uses of items as documentation +## `--with-examples`: include examples of uses of items as documentation * Tracking issue: [#88791](https://github.com/rust-lang/rust/issues/88791) @@ -625,7 +625,7 @@ crate being documented (`foobar`) and a path to output the calls To scrape examples from test code, e.g. functions marked `#[test]`, then add the `--scrape-tests` flag. -### `--generate-link-to-definition`: Generate links on types in source code +## `--generate-link-to-definition`: Generate links on types in source code * Tracking issue: [#89095](https://github.com/rust-lang/rust/issues/89095) @@ -664,3 +664,80 @@ Similar to cargo `build.rustc-wrapper` option, this flag takes a `rustc` wrapper The first argument to the program will be the test builder program. This flag can be passed multiple times to nest wrappers. + +## Passing arguments to rustc when compiling doctests + +You can use the `--doctest-compilation-args` flag if you want to add options when compiling the +doctest. For example if you have: + +```rust,no_run +/// ``` +/// #![deny(warnings)] +/// #![feature(async_await)] +/// +/// let x = 12; +/// ``` +pub struct Bar; +``` + +And you run `rustdoc --test` on it, you will get: + +```console +running 1 test +test foo.rs - Bar (line 1) ... FAILED + +failures: + +---- foo.rs - Bar (line 1) stdout ---- +error: the feature `async_await` has been stable since 1.39.0 and no longer requires an attribute to enable + --> foo.rs:2:12 + | +3 | #![feature(async_await)] + | ^^^^^^^^^^^ + | +note: the lint level is defined here + --> foo.rs:1:9 + | +2 | #![deny(warnings)] + | ^^^^^^^^ + = note: `#[deny(stable_features)]` implied by `#[deny(warnings)]` + +error: aborting due to 1 previous error + +Couldn't compile the test. + +failures: + foo.rs - Bar (line 1) + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.03s +``` + +But if you can limit the lint level to warning by using `--doctest_compilation_args=--cap-lints=warn`: + +```console +$ rustdoc --test --doctest_compilation_args=--cap-lints=warn file.rs + +running 1 test +test tests/rustdoc-ui/doctest/rustflags.rs - Bar (line 5) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.06s +``` + +The parsing of arguments works as follows: if it encounters a `"` or a `'`, it will continue +until it finds the character unescaped (without a prepending `\`). If not inside a string, a +whitespace character will also split arguments. Example: + +```text +"hello 'a'\" ok" how are 'you today?' +``` + +will be split as follows: + +```text +[ + "hello 'a'\" ok", + "how", + "are", + "you today?", +] +``` diff --git a/src/doc/unstable-book/src/language-features/coverage-attribute.md b/src/doc/unstable-book/src/language-features/coverage-attribute.md deleted file mode 100644 index 0a9bd07de07..00000000000 --- a/src/doc/unstable-book/src/language-features/coverage-attribute.md +++ /dev/null @@ -1,30 +0,0 @@ -# `coverage_attribute` - -The tracking issue for this feature is: [#84605] - -[#84605]: https://github.com/rust-lang/rust/issues/84605 - ---- - -The `coverage` attribute can be used to selectively disable coverage -instrumentation in an annotated function. This might be useful to: - -- Avoid instrumentation overhead in a performance critical function -- Avoid generating coverage for a function that is not meant to be executed, - but still target 100% coverage for the rest of the program. - -## Example - -```rust -#![feature(coverage_attribute)] - -// `foo()` will get coverage instrumentation (by default) -fn foo() { - // ... -} - -#[coverage(off)] -fn bar() { - // ... -} -``` diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index d81c47886d2..019a888bd2f 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -4,6 +4,7 @@ use std::iter::once; use std::sync::Arc; use rustc_data_structures::fx::FxHashSet; +use rustc_hir as hir; use rustc_hir::Mutability; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, DefIdSet, LocalDefId, LocalModDefId}; @@ -15,7 +16,6 @@ use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{Symbol, sym}; use thin_vec::{ThinVec, thin_vec}; use tracing::{debug, trace}; -use {rustc_ast as ast, rustc_hir as hir}; use super::Item; use crate::clean::{ @@ -43,7 +43,7 @@ pub(crate) fn try_inline( cx: &mut DocContext<'_>, res: Res, name: Symbol, - attrs: Option<(&[ast::Attribute], Option<LocalDefId>)>, + attrs: Option<(&[hir::Attribute], Option<LocalDefId>)>, visited: &mut DefIdSet, ) -> Option<Vec<clean::Item>> { let did = res.opt_def_id()?; @@ -206,7 +206,7 @@ pub(crate) fn try_inline_glob( } } -pub(crate) fn load_attrs<'hir>(cx: &DocContext<'hir>, did: DefId) -> &'hir [ast::Attribute] { +pub(crate) fn load_attrs<'hir>(cx: &DocContext<'hir>, did: DefId) -> &'hir [hir::Attribute] { cx.tcx.get_attrs_unchecked(did) } @@ -360,7 +360,7 @@ fn build_type_alias( pub(crate) fn build_impls( cx: &mut DocContext<'_>, did: DefId, - attrs: Option<(&[ast::Attribute], Option<LocalDefId>)>, + attrs: Option<(&[hir::Attribute], Option<LocalDefId>)>, ret: &mut Vec<clean::Item>, ) { let _prof_timer = cx.tcx.sess.prof.generic_activity("build_inherent_impls"); @@ -392,8 +392,8 @@ pub(crate) fn build_impls( pub(crate) fn merge_attrs( cx: &mut DocContext<'_>, - old_attrs: &[ast::Attribute], - new_attrs: Option<(&[ast::Attribute], Option<LocalDefId>)>, + old_attrs: &[hir::Attribute], + new_attrs: Option<(&[hir::Attribute], Option<LocalDefId>)>, ) -> (clean::Attributes, Option<Arc<clean::cfg::Cfg>>) { // NOTE: If we have additional attributes (from a re-export), // always insert them first. This ensure that re-export @@ -404,14 +404,14 @@ pub(crate) fn merge_attrs( both.extend_from_slice(old_attrs); ( if let Some(item_id) = item_id { - Attributes::from_ast_with_additional(old_attrs, (inner, item_id.to_def_id())) + Attributes::from_hir_with_additional(old_attrs, (inner, item_id.to_def_id())) } else { - Attributes::from_ast(&both) + Attributes::from_hir(&both) }, both.cfg(cx.tcx, &cx.cache.hidden_cfg), ) } else { - (Attributes::from_ast(old_attrs), old_attrs.cfg(cx.tcx, &cx.cache.hidden_cfg)) + (Attributes::from_hir(old_attrs), old_attrs.cfg(cx.tcx, &cx.cache.hidden_cfg)) } } @@ -419,7 +419,7 @@ pub(crate) fn merge_attrs( pub(crate) fn build_impl( cx: &mut DocContext<'_>, did: DefId, - attrs: Option<(&[ast::Attribute], Option<LocalDefId>)>, + attrs: Option<(&[hir::Attribute], Option<LocalDefId>)>, ret: &mut Vec<clean::Item>, ) { if !cx.inlined.insert(did.into()) { @@ -629,7 +629,7 @@ fn build_module_items( visited: &mut DefIdSet, inlined_names: &mut FxHashSet<(ItemType, Symbol)>, allowed_def_ids: Option<&DefIdSet>, - attrs: Option<(&[ast::Attribute], Option<LocalDefId>)>, + attrs: Option<(&[hir::Attribute], Option<LocalDefId>)>, ) -> Vec<clean::Item> { let mut items = Vec::new(); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 25f88c8797f..9d0c0f687c7 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -55,7 +55,7 @@ use rustc_trait_selection::traits::wf::object_region_bounds; use thin_vec::ThinVec; use tracing::{debug, instrument}; use utils::*; -use {rustc_ast as ast, rustc_attr as attr, rustc_hir as hir}; +use {rustc_ast as ast, rustc_hir as hir}; pub(crate) use self::types::*; pub(crate) use self::utils::{krate, register_res, synthesize_auto_trait_and_blanket_impls}; @@ -201,7 +201,7 @@ fn generate_item_with_correct_attrs( }; let cfg = attrs.cfg(cx.tcx, &cx.cache.hidden_cfg); - let attrs = Attributes::from_ast_iter(attrs.iter().map(|(attr, did)| (&**attr, *did)), false); + let attrs = Attributes::from_hir_iter(attrs.iter().map(|(attr, did)| (&**attr, *did)), false); let name = renamed.or(Some(name)); let mut item = Item::from_def_id_and_attrs_and_parts(def_id, name, kind, attrs, cfg); @@ -1036,7 +1036,7 @@ fn clean_fn_or_proc_macro<'tcx>( /// This is needed to make it more "readable" when documenting functions using /// `rustc_legacy_const_generics`. More information in /// <https://github.com/rust-lang/rust/issues/83167>. -fn clean_fn_decl_legacy_const_generics(func: &mut Function, attrs: &[ast::Attribute]) { +fn clean_fn_decl_legacy_const_generics(func: &mut Function, attrs: &[hir::Attribute]) { for meta_item_list in attrs .iter() .filter(|a| a.has_name(sym::rustc_legacy_const_generics)) @@ -1222,14 +1222,16 @@ fn clean_trait_item<'tcx>(trait_item: &hir::TraitItem<'tcx>, cx: &mut DocContext let local_did = trait_item.owner_id.to_def_id(); cx.with_param_env(local_did, |cx| { let inner = match trait_item.kind { - hir::TraitItemKind::Const(ty, Some(default)) => AssocConstItem(Box::new(Constant { - generics: enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx)), - kind: ConstantKind::Local { def_id: local_did, body: default }, - type_: clean_ty(ty, cx), - })), + hir::TraitItemKind::Const(ty, Some(default)) => { + ProvidedAssocConstItem(Box::new(Constant { + generics: enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx)), + kind: ConstantKind::Local { def_id: local_did, body: default }, + type_: clean_ty(ty, cx), + })) + } hir::TraitItemKind::Const(ty, None) => { let generics = enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx)); - TyAssocConstItem(generics, Box::new(clean_ty(ty, cx))) + RequiredAssocConstItem(generics, Box::new(clean_ty(ty, cx))) } hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => { let m = clean_function(cx, sig, trait_item.generics, FunctionArgs::Body(body)); @@ -1237,7 +1239,7 @@ fn clean_trait_item<'tcx>(trait_item: &hir::TraitItem<'tcx>, cx: &mut DocContext } hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Required(names)) => { let m = clean_function(cx, sig, trait_item.generics, FunctionArgs::Names(names)); - TyMethodItem(m) + RequiredMethodItem(m) } hir::TraitItemKind::Type(bounds, Some(default)) => { let generics = enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx)); @@ -1257,7 +1259,7 @@ fn clean_trait_item<'tcx>(trait_item: &hir::TraitItem<'tcx>, cx: &mut DocContext hir::TraitItemKind::Type(bounds, None) => { let generics = enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx)); let bounds = bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect(); - TyAssocTypeItem(generics, bounds) + RequiredAssocTypeItem(generics, bounds) } }; Item::from_def_id_and_parts(local_did, Some(trait_item.ident.name), inner, cx) @@ -1271,7 +1273,7 @@ pub(crate) fn clean_impl_item<'tcx>( let local_did = impl_.owner_id.to_def_id(); cx.with_param_env(local_did, |cx| { let inner = match impl_.kind { - hir::ImplItemKind::Const(ty, expr) => AssocConstItem(Box::new(Constant { + hir::ImplItemKind::Const(ty, expr) => ImplAssocConstItem(Box::new(Constant { generics: clean_generics(impl_.generics, cx), kind: ConstantKind::Local { def_id: local_did, body: expr }, type_: clean_ty(ty, cx), @@ -1320,18 +1322,23 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo ); simplify::move_bounds_to_generic_parameters(&mut generics); - let provided = match assoc_item.container { - ty::AssocItemContainer::Impl => true, - ty::AssocItemContainer::Trait => tcx.defaultness(assoc_item.def_id).has_value(), - }; - if provided { - AssocConstItem(Box::new(Constant { + match assoc_item.container { + ty::AssocItemContainer::Impl => ImplAssocConstItem(Box::new(Constant { generics, kind: ConstantKind::Extern { def_id: assoc_item.def_id }, type_: ty, - })) - } else { - TyAssocConstItem(generics, Box::new(ty)) + })), + ty::AssocItemContainer::Trait => { + if tcx.defaultness(assoc_item.def_id).has_value() { + ProvidedAssocConstItem(Box::new(Constant { + generics, + kind: ConstantKind::Extern { def_id: assoc_item.def_id }, + type_: ty, + })) + } else { + RequiredAssocConstItem(generics, Box::new(ty)) + } + } } } ty::AssocKind::Fn => { @@ -1369,7 +1376,7 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo }; MethodItem(item, defaultness) } else { - TyMethodItem(item) + RequiredMethodItem(item) } } ty::AssocKind::Type => { @@ -1486,7 +1493,7 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo bounds, ) } else { - TyAssocTypeItem(generics, bounds) + RequiredAssocTypeItem(generics, bounds) } } else { AssocTypeItem( @@ -2578,7 +2585,7 @@ fn get_all_import_attributes<'hir>( import_def_id: LocalDefId, target_def_id: DefId, is_inline: bool, -) -> Vec<(Cow<'hir, ast::Attribute>, Option<DefId>)> { +) -> Vec<(Cow<'hir, hir::Attribute>, Option<DefId>)> { let mut attrs = Vec::new(); let mut first = true; for def_id in reexport_chain(cx.tcx, import_def_id, target_def_id) @@ -2604,7 +2611,7 @@ fn filter_tokens_from_list( ) -> Vec<TokenTree> { let mut tokens = Vec::with_capacity(args_tokens.len()); let mut skip_next_comma = false; - for token in args_tokens.trees() { + for token in args_tokens.iter() { match token { TokenTree::Token(Token { kind: TokenKind::Comma, .. }, _) if skip_next_comma => { skip_next_comma = false; @@ -2631,9 +2638,9 @@ fn filter_doc_attr_ident(ident: Symbol, is_inline: bool) -> bool { /// Remove attributes from `normal` that should not be inherited by `use` re-export. /// Before calling this function, make sure `normal` is a `#[doc]` attribute. -fn filter_doc_attr(normal: &mut ast::NormalAttr, is_inline: bool) { - match normal.item.args { - ast::AttrArgs::Delimited(ref mut args) => { +fn filter_doc_attr(args: &mut hir::AttrArgs, is_inline: bool) { + match args { + hir::AttrArgs::Delimited(ref mut args) => { let tokens = filter_tokens_from_list(&args.tokens, |token| { !matches!( token, @@ -2651,7 +2658,7 @@ fn filter_doc_attr(normal: &mut ast::NormalAttr, is_inline: bool) { }); args.tokens = TokenStream::new(tokens); } - ast::AttrArgs::Empty | ast::AttrArgs::Eq { .. } => {} + hir::AttrArgs::Empty | hir::AttrArgs::Eq { .. } => {} } } @@ -2676,23 +2683,23 @@ fn filter_doc_attr(normal: &mut ast::NormalAttr, is_inline: bool) { /// * `doc(no_inline)` /// * `doc(hidden)` fn add_without_unwanted_attributes<'hir>( - attrs: &mut Vec<(Cow<'hir, ast::Attribute>, Option<DefId>)>, - new_attrs: &'hir [ast::Attribute], + attrs: &mut Vec<(Cow<'hir, hir::Attribute>, Option<DefId>)>, + new_attrs: &'hir [hir::Attribute], is_inline: bool, import_parent: Option<DefId>, ) { for attr in new_attrs { - if matches!(attr.kind, ast::AttrKind::DocComment(..)) { + if matches!(attr.kind, hir::AttrKind::DocComment(..)) { attrs.push((Cow::Borrowed(attr), import_parent)); continue; } let mut attr = attr.clone(); match attr.kind { - ast::AttrKind::Normal(ref mut normal) => { - if let [ident] = &*normal.item.path.segments { - let ident = ident.ident.name; + hir::AttrKind::Normal(ref mut normal) => { + if let [ident] = &*normal.path.segments { + let ident = ident.name; if ident == sym::doc { - filter_doc_attr(normal, is_inline); + filter_doc_attr(&mut normal.args, is_inline); attrs.push((Cow::Owned(attr), import_parent)); } else if is_inline || ident != sym::cfg { // If it's not a `cfg()` attribute, we keep it. @@ -2895,7 +2902,7 @@ fn clean_extern_crate<'tcx>( && attrs.iter().any(|a| { a.has_name(sym::doc) && match a.meta_item_list() { - Some(l) => attr::list_contains_name(&l, sym::inline), + Some(l) => ast::attr::list_contains_name(&l, sym::inline), None => false, } }) @@ -3000,8 +3007,8 @@ fn clean_use_statement_inner<'tcx>( a.has_name(sym::doc) && match a.meta_item_list() { Some(l) => { - attr::list_contains_name(&l, sym::no_inline) - || attr::list_contains_name(&l, sym::hidden) + ast::attr::list_contains_name(&l, sym::no_inline) + || ast::attr::list_contains_name(&l, sym::hidden) } None => false, } diff --git a/src/librustdoc/clean/render_macro_matchers.rs b/src/librustdoc/clean/render_macro_matchers.rs index d39ecf83ac0..3cc5f8d615a 100644 --- a/src/librustdoc/clean/render_macro_matchers.rs +++ b/src/librustdoc/clean/render_macro_matchers.rs @@ -131,7 +131,7 @@ fn print_tts(printer: &mut Printer<'_>, tts: &TokenStream) { use State::*; let mut state = Start; - for tt in tts.trees() { + for tt in tts.iter() { let (needs_space, next_state) = match &tt { TokenTree::Token(tt, _) => match (state, &tt.kind) { (Dollar, token::Ident(..)) => (false, DollarIdent), diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index cba947eb833..8c7ab925577 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -6,9 +6,7 @@ use std::{fmt, iter}; use arrayvec::ArrayVec; use rustc_abi::{ExternAbi, VariantIdx}; -use rustc_ast::MetaItemInner; -use rustc_ast_pretty::pprust; -use rustc_attr::{ConstStability, Deprecation, Stability, StableSince}; +use rustc_attr_parsing::{ConstStability, Deprecation, Stability, StableSince}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId}; @@ -454,14 +452,14 @@ impl Item { kind: ItemKind, cx: &mut DocContext<'_>, ) -> Item { - let ast_attrs = cx.tcx.get_attrs_unchecked(def_id); + let hir_attrs = cx.tcx.get_attrs_unchecked(def_id); Self::from_def_id_and_attrs_and_parts( def_id, name, kind, - Attributes::from_ast(ast_attrs), - ast_attrs.cfg(cx.tcx, &cx.cache.hidden_cfg), + Attributes::from_hir(hir_attrs), + hir_attrs.cfg(cx.tcx, &cx.cache.hidden_cfg), ) } @@ -547,14 +545,14 @@ impl Item { pub(crate) fn is_associated_type(&self) -> bool { matches!(self.kind, AssocTypeItem(..) | StrippedItem(box AssocTypeItem(..))) } - pub(crate) fn is_ty_associated_type(&self) -> bool { - matches!(self.kind, TyAssocTypeItem(..) | StrippedItem(box TyAssocTypeItem(..))) + pub(crate) fn is_required_associated_type(&self) -> bool { + matches!(self.kind, RequiredAssocTypeItem(..) | StrippedItem(box RequiredAssocTypeItem(..))) } pub(crate) fn is_associated_const(&self) -> bool { - matches!(self.kind, AssocConstItem(..) | StrippedItem(box AssocConstItem(..))) + matches!(self.kind, ProvidedAssocConstItem(..) | ImplAssocConstItem(..) | StrippedItem(box (ProvidedAssocConstItem(..) | ImplAssocConstItem(..)))) } - pub(crate) fn is_ty_associated_const(&self) -> bool { - matches!(self.kind, TyAssocConstItem(..) | StrippedItem(box TyAssocConstItem(..))) + pub(crate) fn is_required_associated_const(&self) -> bool { + matches!(self.kind, RequiredAssocConstItem(..) | StrippedItem(box RequiredAssocConstItem(..))) } pub(crate) fn is_method(&self) -> bool { self.type_() == ItemType::Method @@ -671,7 +669,9 @@ impl Item { asyncness: hir::IsAsync::NotAsync, } } - ItemKind::FunctionItem(_) | ItemKind::MethodItem(_, _) | ItemKind::TyMethodItem(_) => { + ItemKind::FunctionItem(_) + | ItemKind::MethodItem(_, _) + | ItemKind::RequiredMethodItem(_) => { let def_id = self.def_id().unwrap(); build_fn_header(def_id, tcx, tcx.asyncness(def_id)) } @@ -701,8 +701,13 @@ impl Item { // Variants always inherit visibility VariantItem(..) | ImplItem(..) => return None, // Trait items inherit the trait's visibility - AssocConstItem(..) | TyAssocConstItem(..) | AssocTypeItem(..) | TyAssocTypeItem(..) - | TyMethodItem(..) | MethodItem(..) => { + RequiredAssocConstItem(..) + | ProvidedAssocConstItem(..) + | ImplAssocConstItem(..) + | AssocTypeItem(..) + | RequiredAssocTypeItem(..) + | RequiredMethodItem(..) + | MethodItem(..) => { let assoc_item = tcx.associated_item(def_id); let is_trait_item = match assoc_item.container { ty::AssocItemContainer::Trait => true, @@ -742,10 +747,10 @@ impl Item { .iter() .filter_map(|attr| { if keep_as_is { - Some(pprust::attribute_to_string(attr)) + Some(rustc_hir_pretty::attribute_to_string(&tcx, attr)) } else if ALLOWED_ATTRIBUTES.contains(&attr.name_or_empty()) { Some( - pprust::attribute_to_string(attr) + rustc_hir_pretty::attribute_to_string(&tcx, attr) .replace("\\\n", "") .replace('\n', "") .replace(" ", " "), @@ -847,10 +852,10 @@ pub(crate) enum ItemKind { TraitAliasItem(TraitAlias), ImplItem(Box<Impl>), /// A required method in a trait declaration meaning it's only a function signature. - TyMethodItem(Box<Function>), + RequiredMethodItem(Box<Function>), /// A method in a trait impl or a provided method in a trait declaration. /// - /// Compared to [TyMethodItem], it also contains a method body. + /// Compared to [RequiredMethodItem], it also contains a method body. MethodItem(Box<Function>, Option<hir::Defaultness>), StructFieldItem(Type), VariantItem(Variant), @@ -864,14 +869,16 @@ pub(crate) enum ItemKind { ProcMacroItem(ProcMacro), PrimitiveItem(PrimitiveType), /// A required associated constant in a trait declaration. - TyAssocConstItem(Generics, Box<Type>), + RequiredAssocConstItem(Generics, Box<Type>), ConstantItem(Box<Constant>), - /// An associated constant in a trait impl or a provided one in a trait declaration. - AssocConstItem(Box<Constant>), + /// An associated constant in a trait declaration with provided default value. + ProvidedAssocConstItem(Box<Constant>), + /// An associated constant in an inherent impl or trait impl. + ImplAssocConstItem(Box<Constant>), /// A required associated type in a trait declaration. /// /// The bounds may be non-empty if there is a `where` clause. - TyAssocTypeItem(Generics, Vec<GenericBound>), + RequiredAssocTypeItem(Generics, Vec<GenericBound>), /// An associated type in a trait impl or a provided one in a trait declaration. AssocTypeItem(Box<TypeAlias>, Vec<GenericBound>), /// An item that has been stripped by a rustdoc pass @@ -902,7 +909,7 @@ impl ItemKind { | StaticItem(_) | ConstantItem(_) | TraitAliasItem(_) - | TyMethodItem(_) + | RequiredMethodItem(_) | MethodItem(_, _) | StructFieldItem(_) | ForeignFunctionItem(_, _) @@ -911,9 +918,10 @@ impl ItemKind { | MacroItem(_) | ProcMacroItem(_) | PrimitiveItem(_) - | TyAssocConstItem(..) - | AssocConstItem(..) - | TyAssocTypeItem(..) + | RequiredAssocConstItem(..) + | ProvidedAssocConstItem(..) + | ImplAssocConstItem(..) + | RequiredAssocTypeItem(..) | AssocTypeItem(..) | StrippedItem(_) | KeywordItem => [].iter(), @@ -955,7 +963,7 @@ pub(crate) trait AttributesExt { type AttributeIterator<'a>: Iterator<Item = ast::MetaItemInner> where Self: 'a; - type Attributes<'a>: Iterator<Item = &'a ast::Attribute> + type Attributes<'a>: Iterator<Item = &'a hir::Attribute> where Self: 'a; @@ -1009,7 +1017,7 @@ pub(crate) trait AttributesExt { // #[doc] if attr.doc_str().is_none() && attr.has_name(sym::doc) { // #[doc(...)] - if let Some(list) = attr.meta().as_ref().and_then(|mi| mi.meta_item_list()) { + if let Some(list) = attr.meta_item_list() { for item in list { // #[doc(hidden)] if !item.has_name(sym::cfg) { @@ -1042,7 +1050,7 @@ pub(crate) trait AttributesExt { let mut meta = attr.meta_item().unwrap().clone(); meta.path = ast::Path::from_ident(Ident::with_dummy_span(sym::target_feature)); - if let Ok(feat_cfg) = Cfg::parse(&MetaItemInner::MetaItem(meta)) { + if let Ok(feat_cfg) = Cfg::parse(&ast::MetaItemInner::MetaItem(meta)) { cfg &= feat_cfg; } } @@ -1053,14 +1061,14 @@ pub(crate) trait AttributesExt { } } -impl AttributesExt for [ast::Attribute] { +impl AttributesExt for [hir::Attribute] { type AttributeIterator<'a> = impl Iterator<Item = ast::MetaItemInner> + 'a; - type Attributes<'a> = impl Iterator<Item = &'a ast::Attribute> + 'a; + type Attributes<'a> = impl Iterator<Item = &'a hir::Attribute> + 'a; fn lists(&self, name: Symbol) -> Self::AttributeIterator<'_> { self.iter() .filter(move |attr| attr.has_name(name)) - .filter_map(ast::Attribute::meta_item_list) + .filter_map(ast::attr::AttributeExt::meta_item_list) .flatten() } @@ -1069,20 +1077,20 @@ impl AttributesExt for [ast::Attribute] { } } -impl AttributesExt for [(Cow<'_, ast::Attribute>, Option<DefId>)] { +impl AttributesExt for [(Cow<'_, hir::Attribute>, Option<DefId>)] { type AttributeIterator<'a> = impl Iterator<Item = ast::MetaItemInner> + 'a where Self: 'a; type Attributes<'a> - = impl Iterator<Item = &'a ast::Attribute> + 'a + = impl Iterator<Item = &'a hir::Attribute> + 'a where Self: 'a; fn lists(&self, name: Symbol) -> Self::AttributeIterator<'_> { AttributesExt::iter(self) .filter(move |attr| attr.has_name(name)) - .filter_map(ast::Attribute::meta_item_list) + .filter_map(hir::Attribute::meta_item_list) .flatten() } @@ -1152,7 +1160,7 @@ pub struct RenderedLink { #[derive(Clone, Debug, Default)] pub(crate) struct Attributes { pub(crate) doc_strings: Vec<DocFragment>, - pub(crate) other_attrs: ast::AttrVec, + pub(crate) other_attrs: ThinVec<hir::Attribute>, } impl Attributes { @@ -1180,22 +1188,22 @@ impl Attributes { self.has_doc_flag(sym::hidden) } - pub(crate) fn from_ast(attrs: &[ast::Attribute]) -> Attributes { - Attributes::from_ast_iter(attrs.iter().map(|attr| (attr, None)), false) + pub(crate) fn from_hir(attrs: &[hir::Attribute]) -> Attributes { + Attributes::from_hir_iter(attrs.iter().map(|attr| (attr, None)), false) } - pub(crate) fn from_ast_with_additional( - attrs: &[ast::Attribute], - (additional_attrs, def_id): (&[ast::Attribute], DefId), + pub(crate) fn from_hir_with_additional( + attrs: &[hir::Attribute], + (additional_attrs, def_id): (&[hir::Attribute], DefId), ) -> Attributes { // Additional documentation should be shown before the original documentation. let attrs1 = additional_attrs.iter().map(|attr| (attr, Some(def_id))); let attrs2 = attrs.iter().map(|attr| (attr, None)); - Attributes::from_ast_iter(attrs1.chain(attrs2), false) + Attributes::from_hir_iter(attrs1.chain(attrs2), false) } - pub(crate) fn from_ast_iter<'a>( - attrs: impl Iterator<Item = (&'a ast::Attribute, Option<DefId>)>, + pub(crate) fn from_hir_iter<'a>( + attrs: impl Iterator<Item = (&'a hir::Attribute, Option<DefId>)>, doc_only: bool, ) -> Attributes { let (doc_strings, other_attrs) = attrs_to_doc_fragments(attrs, doc_only); diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index d59b4e4081c..8aeebdde7bb 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -578,11 +578,10 @@ pub(crate) fn has_doc_flag(tcx: TyCtxt<'_>, did: DefId, flag: Symbol) -> bool { } pub(crate) fn attrs_have_doc_flag<'a>( - mut attrs: impl Iterator<Item = &'a ast::Attribute>, + mut attrs: impl Iterator<Item = &'a hir::Attribute>, flag: Symbol, ) -> bool { - attrs - .any(|attr| attr.meta_item_list().is_some_and(|l| rustc_attr::list_contains_name(&l, flag))) + attrs.any(|attr| attr.meta_item_list().is_some_and(|l| ast::attr::list_contains_name(&l, flag))) } /// A link to `doc.rust-lang.org` that includes the channel name. Use this instead of manual links diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 34c91e33db7..af3c7cc7be3 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -172,6 +172,9 @@ pub(crate) struct Options { /// This is mainly useful for other tools that reads that debuginfo to figure out /// how to call the compiler with the same arguments. pub(crate) expanded_args: Vec<String>, + + /// Arguments to be used when compiling doctests. + pub(crate) doctest_compilation_args: Vec<String>, } impl fmt::Debug for Options { @@ -774,6 +777,7 @@ impl Options { let scrape_examples_options = ScrapeExamplesOptions::new(matches, dcx); let with_examples = matches.opt_strs("with-examples"); let call_locations = crate::scrape_examples::load_call_locations(with_examples, dcx); + let doctest_compilation_args = matches.opt_strs("doctest-compilation-args"); let unstable_features = rustc_feature::UnstableFeatures::from_environment(crate_name.as_deref()); @@ -819,6 +823,7 @@ impl Options { scrape_examples_options, unstable_features, expanded_args: args, + doctest_compilation_args, }; let render_options = RenderOptions { output, diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 70d9269ae5c..e6e5123d0bb 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -13,10 +13,10 @@ use std::{panic, str}; pub(crate) use make::DocTestBuilder; pub(crate) use markdown::test as test_markdown; -use rustc_ast as ast; use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet}; use rustc_errors::emitter::HumanReadableErrorType; use rustc_errors::{ColorConfig, DiagCtxtHandle}; +use rustc_hir as hir; use rustc_hir::CRATE_HIR_ID; use rustc_hir::def_id::LOCAL_CRATE; use rustc_interface::interface; @@ -50,6 +50,46 @@ pub(crate) struct GlobalTestOptions { pub(crate) args_file: PathBuf, } +/// Function used to split command line arguments just like a shell would. +fn split_args(args: &str) -> Vec<String> { + let mut out = Vec::new(); + let mut iter = args.chars(); + let mut current = String::new(); + + while let Some(c) = iter.next() { + if c == '\\' { + if let Some(c) = iter.next() { + // If it's escaped, even a quote or a whitespace will be ignored. + current.push(c); + } + } else if c == '"' || c == '\'' { + while let Some(new_c) = iter.next() { + if new_c == c { + break; + } else if new_c == '\\' { + if let Some(c) = iter.next() { + // If it's escaped, even a quote will be ignored. + current.push(c); + } + } else { + current.push(new_c); + } + } + } else if " \n\t\r".contains(c) { + if !current.is_empty() { + out.push(current.clone()); + current.clear(); + } + } else { + current.push(c); + } + } + if !current.is_empty() { + out.push(current); + } + out +} + pub(crate) fn generate_args_file(file_path: &Path, options: &RustdocOptions) -> Result<(), String> { let mut file = File::create(file_path) .map_err(|error| format!("failed to create args file: {error:?}"))?; @@ -78,6 +118,10 @@ pub(crate) fn generate_args_file(file_path: &Path, options: &RustdocOptions) -> content.push(format!("-Z{unstable_option_str}")); } + for compilation_args in &options.doctest_compilation_args { + content.extend(split_args(compilation_args)); + } + let content = content.join("\n"); file.write_all(content.as_bytes()) @@ -174,28 +218,28 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions compiling_test_count, .. } = interface::run_compiler(config, |compiler| { - compiler.enter(|queries| { - let collector = queries.global_ctxt().enter(|tcx| { - let crate_name = tcx.crate_name(LOCAL_CRATE).to_string(); - let crate_attrs = tcx.hir().attrs(CRATE_HIR_ID); - let opts = scrape_test_config(crate_name, crate_attrs, args_path); - let enable_per_target_ignores = options.enable_per_target_ignores; - - let mut collector = CreateRunnableDocTests::new(options, opts); - let hir_collector = HirCollector::new( - ErrorCodes::from(compiler.sess.opts.unstable_features.is_nightly_build()), - enable_per_target_ignores, - tcx, - ); - let tests = hir_collector.collect_crate(); - tests.into_iter().for_each(|t| collector.add_test(t)); - - collector - }); - compiler.sess.dcx().abort_if_errors(); + let krate = rustc_interface::passes::parse(&compiler.sess); + + let collector = rustc_interface::create_and_enter_global_ctxt(&compiler, krate, |tcx| { + let crate_name = tcx.crate_name(LOCAL_CRATE).to_string(); + let crate_attrs = tcx.hir().attrs(CRATE_HIR_ID); + let opts = scrape_test_config(crate_name, crate_attrs, args_path); + let enable_per_target_ignores = options.enable_per_target_ignores; + + let mut collector = CreateRunnableDocTests::new(options, opts); + let hir_collector = HirCollector::new( + ErrorCodes::from(compiler.sess.opts.unstable_features.is_nightly_build()), + enable_per_target_ignores, + tcx, + ); + let tests = hir_collector.collect_crate(); + tests.into_iter().for_each(|t| collector.add_test(t)); collector - }) + }); + compiler.sess.dcx().abort_if_errors(); + + collector }); run_tests(opts, &rustdoc_options, &unused_extern_reports, standalone_tests, mergeable_tests); @@ -325,7 +369,7 @@ pub(crate) fn run_tests( // Look for `#![doc(test(no_crate_inject))]`, used by crates in the std facade. fn scrape_test_config( crate_name: String, - attrs: &[ast::Attribute], + attrs: &[hir::Attribute], args_file: PathBuf, ) -> GlobalTestOptions { use rustc_ast_pretty::pprust; diff --git a/src/librustdoc/doctest/make.rs b/src/librustdoc/doctest/make.rs index 3ae60938749..a188bc8ebd9 100644 --- a/src/librustdoc/doctest/make.rs +++ b/src/librustdoc/doctest/make.rs @@ -51,8 +51,17 @@ impl DocTestBuilder { !lang_str.compile_fail && !lang_str.test_harness && !lang_str.standalone_crate }); - let SourceInfo { crate_attrs, maybe_crate_attrs, crates, everything_else } = - partition_source(source, edition); + let Some(SourceInfo { crate_attrs, maybe_crate_attrs, crates, everything_else }) = + partition_source(source, edition) + else { + return Self::invalid( + String::new(), + String::new(), + String::new(), + source.to_string(), + test_id, + ); + }; // Uses librustc_ast to parse the doctest and find if there's a main fn and the extern // crate already is included. @@ -77,18 +86,7 @@ impl DocTestBuilder { else { // If the parser panicked due to a fatal error, pass the test code through unchanged. // The error will be reported during compilation. - return Self { - supports_color: false, - has_main_fn: false, - crate_attrs, - maybe_crate_attrs, - crates, - everything_else, - already_has_extern_crate: false, - test_id, - failed_ast: true, - can_be_merged: false, - }; + return Self::invalid(crate_attrs, maybe_crate_attrs, crates, everything_else, test_id); }; // If the AST returned an error, we don't want this doctest to be merged with the // others. Same if it contains `#[feature]` or `#[no_std]`. @@ -113,6 +111,27 @@ impl DocTestBuilder { } } + fn invalid( + crate_attrs: String, + maybe_crate_attrs: String, + crates: String, + everything_else: String, + test_id: Option<String>, + ) -> Self { + Self { + supports_color: false, + has_main_fn: false, + crate_attrs, + maybe_crate_attrs, + crates, + everything_else, + already_has_extern_crate: false, + test_id, + failed_ast: true, + can_be_merged: false, + } + } + /// Transforms a test into code that can be compiled into a Rust binary, and returns the number of /// lines before the test code begins. pub(crate) fn generate_unique_doctest( @@ -518,8 +537,8 @@ fn handle_attr(mod_attr_pending: &mut String, source_info: &mut SourceInfo, edit push_to.push('\n'); // If it's complete, then we can clear the pending content. mod_attr_pending.clear(); - } else if mod_attr_pending.ends_with('\\') { - mod_attr_pending.push('n'); + } else { + mod_attr_pending.push_str("\n"); } } @@ -531,7 +550,7 @@ struct SourceInfo { everything_else: String, } -fn partition_source(s: &str, edition: Edition) -> SourceInfo { +fn partition_source(s: &str, edition: Edition) -> Option<SourceInfo> { #[derive(Copy, Clone, PartialEq)] enum PartitionState { Attrs, @@ -606,11 +625,16 @@ fn partition_source(s: &str, edition: Edition) -> SourceInfo { } } + if !mod_attr_pending.is_empty() { + debug!("invalid doctest code: {s:?}"); + return None; + } + source_info.everything_else = source_info.everything_else.trim().to_string(); debug!("crate_attrs:\n{}{}", source_info.crate_attrs, source_info.maybe_crate_attrs); debug!("crates:\n{}", source_info.crates); debug!("after:\n{}", source_info.everything_else); - source_info + Some(source_info) } diff --git a/src/librustdoc/doctest/rust.rs b/src/librustdoc/doctest/rust.rs index dc68f48f635..0903baddabe 100644 --- a/src/librustdoc/doctest/rust.rs +++ b/src/librustdoc/doctest/rust.rs @@ -110,7 +110,7 @@ impl HirCollector<'_> { // The collapse-docs pass won't combine sugared/raw doc attributes, or included files with // anything else, this will combine them for us. - let attrs = Attributes::from_ast(ast_attrs); + let attrs = Attributes::from_hir(ast_attrs); if let Some(doc) = attrs.opt_doc_value() { let span = span_of_fragments(&attrs.doc_strings).unwrap_or(sp); self.collector.position = if span.edition().at_least_rust_2024() { diff --git a/src/librustdoc/doctest/tests.rs b/src/librustdoc/doctest/tests.rs index 160d0f222b4..fa6cca3681b 100644 --- a/src/librustdoc/doctest/tests.rs +++ b/src/librustdoc/doctest/tests.rs @@ -379,3 +379,25 @@ fn main() { let (output, len) = make_test(input, None, false, &opts, None); assert_eq!((output, len), (expected, 1)); } + +#[test] +fn check_split_args() { + fn compare(input: &str, expected: &[&str]) { + let output = super::split_args(input); + let expected = expected.iter().map(|s| s.to_string()).collect::<Vec<_>>(); + assert_eq!(expected, output, "test failed for {input:?}"); + } + + compare("'a' \"b\"c", &["a", "bc"]); + compare("'a' \"b \"c d", &["a", "b c", "d"]); + compare("'a' \"b\\\"c\"", &["a", "b\"c"]); + compare("'a\"'", &["a\""]); + compare("\"a'\"", &["a'"]); + compare("\\ a", &[" a"]); + compare("\\\\", &["\\"]); + compare("a'", &["a"]); + compare("a ", &["a"]); + compare("a b", &["a", "b"]); + compare("a\n\t \rb", &["a", "b"]); + compare("a\n\t1 \rb", &["a", "1", "b"]); +} diff --git a/src/librustdoc/fold.rs b/src/librustdoc/fold.rs index 95e495205ae..c03d16ad081 100644 --- a/src/librustdoc/fold.rs +++ b/src/librustdoc/fold.rs @@ -82,7 +82,7 @@ pub(crate) trait DocFolder: Sized { | StaticItem(_) | ConstantItem(..) | TraitAliasItem(_) - | TyMethodItem(_) + | RequiredMethodItem(_) | MethodItem(_, _) | StructFieldItem(_) | ForeignFunctionItem(..) @@ -91,9 +91,10 @@ pub(crate) trait DocFolder: Sized { | MacroItem(_) | ProcMacroItem(_) | PrimitiveItem(_) - | TyAssocConstItem(..) - | AssocConstItem(..) - | TyAssocTypeItem(..) + | RequiredAssocConstItem(..) + | ProvidedAssocConstItem(..) + | ImplAssocConstItem(..) + | RequiredAssocTypeItem(..) | AssocTypeItem(..) | KeywordItem => kind, } diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index e387eb010be..b63122565c4 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -334,12 +334,13 @@ impl DocFolder for CacheBuilder<'_, '_> { clean::ExternCrateItem { .. } | clean::ImportItem(..) | clean::ImplItem(..) - | clean::TyMethodItem(..) + | clean::RequiredMethodItem(..) | clean::MethodItem(..) | clean::StructFieldItem(..) - | clean::TyAssocConstItem(..) - | clean::AssocConstItem(..) - | clean::TyAssocTypeItem(..) + | clean::RequiredAssocConstItem(..) + | clean::ProvidedAssocConstItem(..) + | clean::ImplAssocConstItem(..) + | clean::RequiredAssocTypeItem(..) | clean::AssocTypeItem(..) | clean::StrippedItem(..) | clean::KeywordItem => { @@ -443,15 +444,17 @@ fn add_item_to_search_index(tcx: TyCtxt<'_>, cache: &mut Cache, item: &clean::It let item_def_id = item.item_id.as_def_id().unwrap(); let (parent_did, parent_path) = match item.kind { clean::StrippedItem(..) => return, - clean::AssocConstItem(..) | clean::AssocTypeItem(..) + clean::ProvidedAssocConstItem(..) + | clean::ImplAssocConstItem(..) + | clean::AssocTypeItem(..) if cache.parent_stack.last().is_some_and(|parent| parent.is_trait_impl()) => { // skip associated items in trait impls return; } - clean::TyMethodItem(..) - | clean::TyAssocConstItem(..) - | clean::TyAssocTypeItem(..) + clean::RequiredMethodItem(..) + | clean::RequiredAssocConstItem(..) + | clean::RequiredAssocTypeItem(..) | clean::StructFieldItem(..) | clean::VariantItem(..) => { // Don't index if containing module is stripped (i.e., private), @@ -467,7 +470,10 @@ fn add_item_to_search_index(tcx: TyCtxt<'_>, cache: &mut Cache, item: &clean::It let parent_path = &cache.stack[..cache.stack.len() - 1]; (Some(parent_did), parent_path) } - clean::MethodItem(..) | clean::AssocConstItem(..) | clean::AssocTypeItem(..) => { + clean::MethodItem(..) + | clean::ProvidedAssocConstItem(..) + | clean::ImplAssocConstItem(..) + | clean::AssocTypeItem(..) => { let last = cache.parent_stack.last().expect("parent_stack is empty 2"); let parent_did = match last { // impl Trait for &T { fn method(self); } diff --git a/src/librustdoc/formats/item_type.rs b/src/librustdoc/formats/item_type.rs index 383e3135faa..de6537e992f 100644 --- a/src/librustdoc/formats/item_type.rs +++ b/src/librustdoc/formats/item_type.rs @@ -88,7 +88,7 @@ impl<'a> From<&'a clean::Item> for ItemType { clean::ConstantItem(..) => ItemType::Constant, clean::TraitItem(..) => ItemType::Trait, clean::ImplItem(..) => ItemType::Impl, - clean::TyMethodItem(..) => ItemType::TyMethod, + clean::RequiredMethodItem(..) => ItemType::TyMethod, clean::MethodItem(..) => ItemType::Method, clean::StructFieldItem(..) => ItemType::StructField, clean::VariantItem(..) => ItemType::Variant, @@ -96,8 +96,10 @@ impl<'a> From<&'a clean::Item> for ItemType { clean::ForeignStaticItem(..) => ItemType::Static, // no ForeignStatic clean::MacroItem(..) => ItemType::Macro, clean::PrimitiveItem(..) => ItemType::Primitive, - clean::TyAssocConstItem(..) | clean::AssocConstItem(..) => ItemType::AssocConst, - clean::TyAssocTypeItem(..) | clean::AssocTypeItem(..) => ItemType::AssocType, + clean::RequiredAssocConstItem(..) + | clean::ProvidedAssocConstItem(..) + | clean::ImplAssocConstItem(..) => ItemType::AssocConst, + clean::RequiredAssocTypeItem(..) | clean::AssocTypeItem(..) => ItemType::AssocType, clean::ForeignTypeItem => ItemType::ForeignType, clean::KeywordItem => ItemType::Keyword, clean::TraitAliasItem(..) => ItemType::TraitAlias, diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 0a563b1df26..136002b8e15 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -15,7 +15,7 @@ use std::iter::{self, once}; use itertools::Itertools; use rustc_abi::ExternAbi; -use rustc_attr::{ConstStability, StabilityLevel, StableSince}; +use rustc_attr_parsing::{ConstStability, StabilityLevel, StableSince}; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; @@ -1626,10 +1626,7 @@ pub(crate) trait PrintWithSpace { impl PrintWithSpace for hir::Safety { fn print_with_space(&self) -> &str { - match self { - hir::Safety::Unsafe => "unsafe ", - hir::Safety::Safe => "", - } + self.prefix_str() } } diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 90c49270566..aa8fdaaee4c 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -344,35 +344,48 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> { } /// Make headings links with anchor IDs and build up TOC. -struct LinkReplacer<'a, I: Iterator<Item = Event<'a>>> { - inner: I, +struct LinkReplacerInner<'a> { links: &'a [RenderedLink], shortcut_link: Option<&'a RenderedLink>, } +struct LinkReplacer<'a, I: Iterator<Item = Event<'a>>> { + iter: I, + inner: LinkReplacerInner<'a>, +} + impl<'a, I: Iterator<Item = Event<'a>>> LinkReplacer<'a, I> { fn new(iter: I, links: &'a [RenderedLink]) -> Self { - LinkReplacer { inner: iter, links, shortcut_link: None } + LinkReplacer { iter, inner: { LinkReplacerInner { links, shortcut_link: None } } } } } -impl<'a, I: Iterator<Item = Event<'a>>> Iterator for LinkReplacer<'a, I> { - type Item = Event<'a>; +// FIXME: Once we have specialized trait impl (for `Iterator` impl on `LinkReplacer`), +// we can remove this type and move back `LinkReplacerInner` fields into `LinkReplacer`. +struct SpannedLinkReplacer<'a, I: Iterator<Item = SpannedEvent<'a>>> { + iter: I, + inner: LinkReplacerInner<'a>, +} - fn next(&mut self) -> Option<Self::Item> { - let mut event = self.inner.next(); +impl<'a, I: Iterator<Item = SpannedEvent<'a>>> SpannedLinkReplacer<'a, I> { + fn new(iter: I, links: &'a [RenderedLink]) -> Self { + SpannedLinkReplacer { iter, inner: { LinkReplacerInner { links, shortcut_link: None } } } + } +} +impl<'a> LinkReplacerInner<'a> { + fn handle_event(&mut self, event: &mut Event<'a>) { // Replace intra-doc links and remove disambiguators from shortcut links (`[fn@f]`). - match &mut event { + match event { // This is a shortcut link that was resolved by the broken_link_callback: `[fn@f]` // Remove any disambiguator. - Some(Event::Start(Tag::Link { + Event::Start(Tag::Link { // [fn@f] or [fn@f][] link_type: LinkType::ShortcutUnknown | LinkType::CollapsedUnknown, dest_url, title, .. - })) => { + }) => { debug!("saw start of shortcut link to {dest_url} with title {title}"); // If this is a shortcut link, it was resolved by the broken_link_callback. // So the URL will already be updated properly. @@ -389,13 +402,13 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for LinkReplacer<'a, I> { } } // Now that we're done with the shortcut link, don't replace any more text. - Some(Event::End(TagEnd::Link)) if self.shortcut_link.is_some() => { + Event::End(TagEnd::Link) if self.shortcut_link.is_some() => { debug!("saw end of shortcut link"); self.shortcut_link = None; } // Handle backticks in inline code blocks, but only if we're in the middle of a shortcut link. // [`fn@f`] - Some(Event::Code(text)) => { + Event::Code(text) => { trace!("saw code {text}"); if let Some(link) = self.shortcut_link { // NOTE: this only replaces if the code block is the *entire* text. @@ -418,7 +431,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for LinkReplacer<'a, I> { } // Replace plain text in links, but only in the middle of a shortcut link. // [fn@f] - Some(Event::Text(text)) => { + Event::Text(text) => { trace!("saw text {text}"); if let Some(link) = self.shortcut_link { // NOTE: same limitations as `Event::Code` @@ -434,7 +447,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for LinkReplacer<'a, I> { } // If this is a link, but not a shortcut link, // replace the URL, since the broken_link_callback was not called. - Some(Event::Start(Tag::Link { dest_url, title, .. })) => { + Event::Start(Tag::Link { dest_url, title, .. }) => { if let Some(link) = self.links.iter().find(|&link| *link.original_text == **dest_url) { @@ -447,12 +460,33 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for LinkReplacer<'a, I> { // Anything else couldn't have been a valid Rust path, so no need to replace the text. _ => {} } + } +} + +impl<'a, I: Iterator<Item = Event<'a>>> Iterator for LinkReplacer<'a, I> { + type Item = Event<'a>; + fn next(&mut self) -> Option<Self::Item> { + let mut event = self.iter.next(); + if let Some(ref mut event) = event { + self.inner.handle_event(event); + } // Yield the modified event event } } +impl<'a, I: Iterator<Item = SpannedEvent<'a>>> Iterator for SpannedLinkReplacer<'a, I> { + type Item = SpannedEvent<'a>; + + fn next(&mut self) -> Option<Self::Item> { + let Some((mut event, range)) = self.iter.next() else { return None }; + self.inner.handle_event(&mut event); + // Yield the modified event + Some((event, range)) + } +} + /// Wrap HTML tables into `<div>` to prevent having the doc blocks width being too big. struct TableWrapper<'a, I: Iterator<Item = Event<'a>>> { inner: I, @@ -1339,9 +1373,9 @@ impl<'a> Markdown<'a> { ids.handle_footnotes(|ids, existing_footnotes| { let p = HeadingLinks::new(p, None, ids, heading_offset); + let p = SpannedLinkReplacer::new(p, links); let p = footnotes::Footnotes::new(p, existing_footnotes); - let p = LinkReplacer::new(p.map(|(ev, _)| ev), links); - let p = TableWrapper::new(p); + let p = TableWrapper::new(p.map(|(ev, _)| ev)); CodeBlocks::new(p, codes, edition, playground) }) } diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index e013829e5e0..dfdf2cd6ec3 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -44,14 +44,15 @@ use std::path::PathBuf; use std::{fs, str}; use rinja::Template; -use rustc_attr::{ConstStability, DeprecatedSince, Deprecation, StabilityLevel, StableSince}; +use rustc_attr_parsing::{ + ConstStability, DeprecatedSince, Deprecation, RustcVersion, StabilityLevel, StableSince, +}; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_hir::Mutability; use rustc_hir::def_id::{DefId, DefIdSet}; use rustc_middle::ty::print::PrintTraitRefExt; use rustc_middle::ty::{self, TyCtxt}; -use rustc_session::RustcVersion; use rustc_span::symbol::{Symbol, sym}; use rustc_span::{BytePos, DUMMY_SP, FileName, RealFileName}; use serde::ser::SerializeMap; @@ -835,12 +836,23 @@ fn assoc_href_attr(it: &clean::Item, link: AssocItemLink<'_>, cx: &Context<'_>) href.map(|href| format!(" href=\"{href}\"")).unwrap_or_default() } +#[derive(Debug)] +enum AssocConstValue<'a> { + // In trait definitions, it is relevant for the public API whether an + // associated constant comes with a default value, so even if we cannot + // render its value, the presence of a value must be shown using `= _`. + TraitDefault(&'a clean::ConstantKind), + // In impls, there is no need to show `= _`. + Impl(&'a clean::ConstantKind), + None, +} + fn assoc_const( w: &mut Buffer, it: &clean::Item, generics: &clean::Generics, ty: &clean::Type, - default: Option<&clean::ConstantKind>, + value: AssocConstValue<'_>, link: AssocItemLink<'_>, indent: usize, cx: &Context<'_>, @@ -856,15 +868,20 @@ fn assoc_const( generics = generics.print(cx), ty = ty.print(cx), ); - if let Some(default) = default { - w.write_str(" = "); - + if let AssocConstValue::TraitDefault(konst) | AssocConstValue::Impl(konst) = value { // FIXME: `.value()` uses `clean::utils::format_integer_with_underscore_sep` under the // hood which adds noisy underscores and a type suffix to number literals. // This hurts readability in this context especially when more complex expressions // are involved and it doesn't add much of value. // Find a way to print constants here without all that jazz. - write!(w, "{}", Escape(&default.value(tcx).unwrap_or_else(|| default.expr(tcx)))); + let repr = konst.value(tcx).unwrap_or_else(|| konst.expr(tcx)); + if match value { + AssocConstValue::TraitDefault(_) => true, // always show + AssocConstValue::Impl(_) => repr != "_", // show if there is a meaningful value to show + AssocConstValue::None => unreachable!(), + } { + write!(w, " = {}", Escape(&repr)); + } } write!(w, "{}", print_where_clause(generics, cx, indent, Ending::NoNewline)); } @@ -1075,33 +1092,43 @@ fn render_assoc_item( ) { match &item.kind { clean::StrippedItem(..) => {} - clean::TyMethodItem(m) => { + clean::RequiredMethodItem(m) => { assoc_method(w, item, &m.generics, &m.decl, link, parent, cx, render_mode) } clean::MethodItem(m, _) => { assoc_method(w, item, &m.generics, &m.decl, link, parent, cx, render_mode) } - clean::TyAssocConstItem(generics, ty) => assoc_const( + clean::RequiredAssocConstItem(generics, ty) => assoc_const( w, item, generics, ty, - None, + AssocConstValue::None, link, if parent == ItemType::Trait { 4 } else { 0 }, cx, ), - clean::AssocConstItem(ci) => assoc_const( + clean::ProvidedAssocConstItem(ci) => assoc_const( w, item, &ci.generics, &ci.type_, - Some(&ci.kind), + AssocConstValue::TraitDefault(&ci.kind), link, if parent == ItemType::Trait { 4 } else { 0 }, cx, ), - clean::TyAssocTypeItem(ref generics, ref bounds) => assoc_type( + clean::ImplAssocConstItem(ci) => assoc_const( + w, + item, + &ci.generics, + &ci.type_, + AssocConstValue::Impl(&ci.kind), + link, + if parent == ItemType::Trait { 4 } else { 0 }, + cx, + ), + clean::RequiredAssocTypeItem(ref generics, ref bounds) => assoc_type( w, item, generics, @@ -1383,7 +1410,7 @@ fn render_deref_methods( fn should_render_item(item: &clean::Item, deref_mut_: bool, tcx: TyCtxt<'_>) -> bool { let self_type_opt = match item.kind { clean::MethodItem(ref method, _) => method.decl.receiver_type(), - clean::TyMethodItem(ref method) => method.decl.receiver_type(), + clean::RequiredMethodItem(ref method) => method.decl.receiver_type(), _ => None, }; @@ -1659,7 +1686,7 @@ fn render_impl( write!(w, "<details class=\"toggle{method_toggle_class}\" open><summary>"); } match &item.kind { - clean::MethodItem(..) | clean::TyMethodItem(_) => { + clean::MethodItem(..) | clean::RequiredMethodItem(_) => { // Only render when the method is not static or we allow static methods if render_method_item { let id = cx.derive_id(format!("{item_type}.{name}")); @@ -1689,7 +1716,7 @@ fn render_impl( w.write_str("</h4></section>"); } } - clean::TyAssocConstItem(ref generics, ref ty) => { + 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}\">"); @@ -1704,14 +1731,14 @@ fn render_impl( item, generics, ty, - None, + AssocConstValue::None, link.anchor(if trait_.is_some() { &source_id } else { &id }), 0, cx, ); w.write_str("</h4></section>"); } - clean::AssocConstItem(ci) => { + 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}\">"); @@ -1726,14 +1753,18 @@ fn render_impl( item, &ci.generics, &ci.type_, - Some(&ci.kind), + match item.kind { + clean::ProvidedAssocConstItem(_) => AssocConstValue::TraitDefault(&ci.kind), + clean::ImplAssocConstItem(_) => AssocConstValue::Impl(&ci.kind), + _ => unreachable!(), + }, link.anchor(if trait_.is_some() { &source_id } else { &id }), 0, cx, ); w.write_str("</h4></section>"); } - clean::TyAssocTypeItem(ref generics, ref bounds) => { + 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}\">"); @@ -1808,11 +1839,13 @@ fn render_impl( if !impl_.is_negative_trait_impl() { for trait_item in &impl_.items { match trait_item.kind { - clean::MethodItem(..) | clean::TyMethodItem(_) => methods.push(trait_item), - clean::TyAssocTypeItem(..) | clean::AssocTypeItem(..) => { + clean::MethodItem(..) | clean::RequiredMethodItem(_) => methods.push(trait_item), + clean::RequiredAssocTypeItem(..) | clean::AssocTypeItem(..) => { assoc_types.push(trait_item) } - clean::TyAssocConstItem(..) | clean::AssocConstItem(_) => { + clean::RequiredAssocConstItem(..) + | clean::ProvidedAssocConstItem(_) + | clean::ImplAssocConstItem(_) => { // We render it directly since they're supposed to come first. doc_impl_item( &mut default_impl_items, diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 4c8d704e65b..0fb77d38f16 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -469,7 +469,7 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl let unsafety_flag = match myitem.kind { clean::FunctionItem(_) | clean::ForeignFunctionItem(..) - if myitem.fn_header(tcx).unwrap().safety == hir::Safety::Unsafe => + if myitem.fn_header(tcx).unwrap().safety.is_unsafe() => { "<sup title=\"unsafe function\">âš </sup>" } @@ -651,9 +651,11 @@ fn item_function(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, f: &clean:: fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Trait) { let tcx = cx.tcx(); let bounds = bounds(&t.bounds, false, cx); - let required_types = t.items.iter().filter(|m| m.is_ty_associated_type()).collect::<Vec<_>>(); + let required_types = + t.items.iter().filter(|m| m.is_required_associated_type()).collect::<Vec<_>>(); let provided_types = t.items.iter().filter(|m| m.is_associated_type()).collect::<Vec<_>>(); - let required_consts = t.items.iter().filter(|m| m.is_ty_associated_const()).collect::<Vec<_>>(); + let required_consts = + t.items.iter().filter(|m| m.is_required_associated_const()).collect::<Vec<_>>(); let provided_consts = t.items.iter().filter(|m| m.is_associated_const()).collect::<Vec<_>>(); let required_methods = t.items.iter().filter(|m| m.is_ty_method()).collect::<Vec<_>>(); let provided_methods = t.items.iter().filter(|m| m.is_method()).collect::<Vec<_>>(); @@ -1926,9 +1928,7 @@ fn item_static( buffer, "{vis}{safe}static {mutability}{name}: {typ}", vis = visibility_print_with_space(it, cx), - safe = safety - .map(|safe| if safe == hir::Safety::Unsafe { "unsafe " } else { "" }) - .unwrap_or(""), + safe = safety.map(|safe| safe.prefix_str()).unwrap_or(""), mutability = s.mutability.print_with_space(), name = it.name.unwrap(), typ = s.type_.print(cx) diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs index 2c26ffa76f6..fe2e155c9ba 100644 --- a/src/librustdoc/html/render/search_index.rs +++ b/src/librustdoc/html/render/search_index.rs @@ -837,7 +837,7 @@ pub(crate) fn get_function_type_for_search( clean::ForeignFunctionItem(ref f, _) | clean::FunctionItem(ref f) | clean::MethodItem(ref f, _) - | clean::TyMethodItem(ref f) => { + | clean::RequiredMethodItem(ref f) => { get_fn_inputs_and_outputs(f, tcx, impl_or_trait_generics, cache) } _ => return None, @@ -1207,10 +1207,11 @@ fn simplify_fn_type<'a, 'tcx>( && let Type::Path { path } = arg && let def_id = path.def_id() && let Some(trait_) = cache.traits.get(&def_id) - && trait_.items.iter().any(|at| at.is_ty_associated_type()) + && trait_.items.iter().any(|at| at.is_required_associated_type()) { for assoc_ty in &trait_.items { - if let clean::ItemKind::TyAssocTypeItem(_generics, bounds) = &assoc_ty.kind + if let clean::ItemKind::RequiredAssocTypeItem(_generics, bounds) = + &assoc_ty.kind && let Some(name) = assoc_ty.name { let idx = -isize::try_from(rgen.len() + 1).unwrap(); diff --git a/src/librustdoc/html/render/sidebar.rs b/src/librustdoc/html/render/sidebar.rs index e99e2f04b2c..af39d15f671 100644 --- a/src/librustdoc/html/render/sidebar.rs +++ b/src/librustdoc/html/render/sidebar.rs @@ -282,10 +282,10 @@ fn sidebar_trait<'a>( res } - let req_assoc = filter_items(&t.items, |m| m.is_ty_associated_type(), "associatedtype"); + let req_assoc = filter_items(&t.items, |m| m.is_required_associated_type(), "associatedtype"); let prov_assoc = filter_items(&t.items, |m| m.is_associated_type(), "associatedtype"); let req_assoc_const = - filter_items(&t.items, |m| m.is_ty_associated_const(), "associatedconstant"); + filter_items(&t.items, |m| m.is_required_associated_const(), "associatedconstant"); let prov_assoc_const = filter_items(&t.items, |m| m.is_associated_const(), "associatedconstant"); let req_method = filter_items(&t.items, |m| m.is_ty_method(), "tymethod"); diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 9e5cf497211..04eeee37fe8 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -2592,7 +2592,12 @@ class DocSearch { const writeFn = (fnType, result) => { if (fnType.id < 0) { if (fnParamNames[-1 - fnType.id] === "") { - for (const nested of fnType.generics) { + // Normally, there's no need to shown an unhighlighted + // where clause, but if it's impl Trait, then we do. + const generics = fnType.generics.length > 0 ? + fnType.generics : + obj.type.where_clause[-1 - fnType.id]; + for (const nested of generics) { writeFn(nested, result); } return; diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index bb967b7f163..583d0214a46 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -6,7 +6,7 @@ use rustc_abi::ExternAbi; use rustc_ast::ast; -use rustc_attr::DeprecatedSince; +use rustc_attr_parsing::DeprecatedSince; use rustc_hir::def::{CtorKind, DefKind}; use rustc_hir::def_id::DefId; use rustc_metadata::rendered_const; @@ -215,8 +215,8 @@ where } } -pub(crate) fn from_deprecation(deprecation: rustc_attr::Deprecation) -> Deprecation { - let rustc_attr::Deprecation { since, note, suggestion: _ } = deprecation; +pub(crate) fn from_deprecation(deprecation: rustc_attr_parsing::Deprecation) -> Deprecation { + let rustc_attr_parsing::Deprecation { since, note, suggestion: _ } = deprecation; let since = match since { DeprecatedSince::RustcVersion(version) => Some(version.to_string()), DeprecatedSince::Future => Some("TBD".to_owned()), @@ -319,7 +319,9 @@ fn from_clean_item(item: clean::Item, renderer: &JsonRenderer<'_>) -> ItemEnum { TraitItem(t) => ItemEnum::Trait((*t).into_json(renderer)), TraitAliasItem(t) => ItemEnum::TraitAlias(t.into_json(renderer)), MethodItem(m, _) => ItemEnum::Function(from_function(m, true, header.unwrap(), renderer)), - TyMethodItem(m) => ItemEnum::Function(from_function(m, false, header.unwrap(), renderer)), + RequiredMethodItem(m) => { + ItemEnum::Function(from_function(m, false, header.unwrap(), renderer)) + } ImplItem(i) => ItemEnum::Impl((*i).into_json(renderer)), StaticItem(s) => ItemEnum::Static(convert_static(s, rustc_hir::Safety::Safe, renderer)), ForeignStaticItem(s, safety) => ItemEnum::Static(convert_static(s, safety, renderer)), @@ -339,15 +341,15 @@ fn from_clean_item(item: clean::Item, renderer: &JsonRenderer<'_>) -> ItemEnum { }) } // FIXME(generic_const_items): Add support for generic associated consts. - TyAssocConstItem(_generics, ty) => { + RequiredAssocConstItem(_generics, ty) => { ItemEnum::AssocConst { type_: (*ty).into_json(renderer), value: None } } // FIXME(generic_const_items): Add support for generic associated consts. - AssocConstItem(ci) => ItemEnum::AssocConst { + ProvidedAssocConstItem(ci) | ImplAssocConstItem(ci) => ItemEnum::AssocConst { type_: ci.type_.into_json(renderer), value: Some(ci.kind.expr(renderer.tcx)), }, - TyAssocTypeItem(g, b) => ItemEnum::AssocType { + RequiredAssocTypeItem(g, b) => ItemEnum::AssocType { generics: g.into_json(renderer), bounds: b.into_json(renderer), type_: None, @@ -639,7 +641,7 @@ impl FromClean<clean::BareFunctionDecl> for FunctionPointer { let clean::BareFunctionDecl { safety, generic_params, decl, abi } = bare_decl; FunctionPointer { header: FunctionHeader { - is_unsafe: matches!(safety, rustc_hir::Safety::Unsafe), + is_unsafe: safety.is_unsafe(), is_const: false, is_async: false, abi: convert_abi(abi), @@ -669,7 +671,7 @@ impl FromClean<clean::Trait> for Trait { fn from_clean(trait_: clean::Trait, renderer: &JsonRenderer<'_>) -> Self { let tcx = renderer.tcx; let is_auto = trait_.is_auto(tcx); - let is_unsafe = trait_.safety(tcx) == rustc_hir::Safety::Unsafe; + let is_unsafe = trait_.safety(tcx).is_unsafe(); let is_dyn_compatible = trait_.is_dyn_compatible(tcx); let clean::Trait { items, generics, bounds, .. } = trait_; Trait { @@ -711,7 +713,7 @@ impl FromClean<clean::Impl> for Impl { ty::ImplPolarity::Negative => true, }; Impl { - is_unsafe: safety == rustc_hir::Safety::Unsafe, + is_unsafe: safety.is_unsafe(), generics: generics.into_json(renderer), provided_trait_methods: provided_trait_methods .into_iter() @@ -840,7 +842,7 @@ fn convert_static( Static { type_: (*stat.type_).into_json(renderer), is_mutable: stat.mutability == ast::Mutability::Mut, - is_unsafe: safety == rustc_hir::Safety::Unsafe, + is_unsafe: safety.is_unsafe(), expr: stat .expr .map(|e| rendered_const(tcx, tcx.hir().body(e), tcx.hir().body_owner_def_id(e))) diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 5d82b8e309a..ff1c9c61720 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -36,7 +36,7 @@ extern crate pulldown_cmark; extern crate rustc_abi; extern crate rustc_ast; extern crate rustc_ast_pretty; -extern crate rustc_attr; +extern crate rustc_attr_parsing; extern crate rustc_data_structures; extern crate rustc_driver; extern crate rustc_errors; @@ -642,6 +642,15 @@ fn opts() -> Vec<RustcOptGroup> { "Includes trait implementations and other crate info from provided path. Only use with --merge=finalize", "path/to/doc.parts/<crate-name>", ), + opt(Unstable, Flag, "", "html-no-source", "Disable HTML source code pages generation", ""), + opt( + Unstable, + Multi, + "", + "doctest-compilation-args", + "", + "add arguments to be used when compiling doctests", + ), // deprecated / removed options opt(Unstable, FlagMulti, "", "disable-minification", "removed", ""), opt( @@ -684,7 +693,6 @@ fn opts() -> Vec<RustcOptGroup> { "removed, see issue #44136 <https://github.com/rust-lang/rust/issues/44136> for more information", "[rust]", ), - opt(Unstable, Flag, "", "html-no-source", "Disable HTML source code pages generation", ""), ] } @@ -856,50 +864,41 @@ fn main_args( return; } - compiler.enter(|queries| { - let mut gcx = queries.global_ctxt(); - if sess.dcx().has_errors().is_some() { - sess.dcx().fatal("Compilation failed, aborting rustdoc"); + let krate = rustc_interface::passes::parse(sess); + if sess.dcx().has_errors().is_some() { + sess.dcx().fatal("Compilation failed, aborting rustdoc"); + } + + rustc_interface::create_and_enter_global_ctxt(&compiler, krate, |tcx| { + let (krate, render_opts, mut cache) = sess.time("run_global_ctxt", || { + core::run_global_ctxt(tcx, show_coverage, render_options, output_format) + }); + info!("finished with rustc"); + + if let Some(options) = scrape_examples_options { + return scrape_examples::run(krate, render_opts, cache, tcx, options, bin_crate); + } + + cache.crate_version = crate_version; + + if show_coverage { + // if we ran coverage, bail early, we don't need to also generate docs at this point + // (also we didn't load in any of the useful passes) + return; + } else if run_check { + // Since we're in "check" mode, no need to generate anything beyond this point. + return; } - gcx.enter(|tcx| { - let (krate, render_opts, mut cache) = sess.time("run_global_ctxt", || { - core::run_global_ctxt(tcx, show_coverage, render_options, output_format) - }); - info!("finished with rustc"); - - if let Some(options) = scrape_examples_options { - return scrape_examples::run( - krate, - render_opts, - cache, - tcx, - options, - bin_crate, - ); - } - - cache.crate_version = crate_version; - - if show_coverage { - // if we ran coverage, bail early, we don't need to also generate docs at this point - // (also we didn't load in any of the useful passes) - return; - } else if run_check { - // Since we're in "check" mode, no need to generate anything beyond this point. - return; - } - - info!("going to format"); - match output_format { - config::OutputFormat::Html => sess.time("render_html", || { - run_renderer::<html::render::Context<'_>>(krate, render_opts, cache, tcx) - }), - config::OutputFormat::Json => sess.time("render_json", || { - run_renderer::<json::JsonRenderer<'_>>(krate, render_opts, cache, tcx) - }), - } - }) + info!("going to format"); + match output_format { + config::OutputFormat::Html => sess.time("render_html", || { + run_renderer::<html::render::Context<'_>>(krate, render_opts, cache, tcx) + }), + config::OutputFormat::Json => sess.time("render_json", || { + run_renderer::<json::JsonRenderer<'_>>(krate, render_opts, cache, tcx) + }), + } }) }) } diff --git a/src/librustdoc/passes/check_doc_test_visibility.rs b/src/librustdoc/passes/check_doc_test_visibility.rs index c288a3cf2a4..0fefd13f763 100644 --- a/src/librustdoc/passes/check_doc_test_visibility.rs +++ b/src/librustdoc/passes/check_doc_test_visibility.rs @@ -72,10 +72,11 @@ pub(crate) fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) - | clean::ForeignFunctionItem(..) | clean::ForeignStaticItem(..) | clean::ForeignTypeItem - | clean::AssocConstItem(..) | clean::AssocTypeItem(..) - | clean::TyAssocConstItem(..) - | clean::TyAssocTypeItem(..) + | clean::RequiredAssocConstItem(..) + | clean::ProvidedAssocConstItem(..) + | clean::ImplAssocConstItem(..) + | clean::RequiredAssocTypeItem(..) // check for trait impl | clean::ImplItem(box clean::Impl { trait_: Some(_), .. }) ) diff --git a/src/librustdoc/passes/propagate_stability.rs b/src/librustdoc/passes/propagate_stability.rs index a81b130a218..4c682c3d4ca 100644 --- a/src/librustdoc/passes/propagate_stability.rs +++ b/src/librustdoc/passes/propagate_stability.rs @@ -6,7 +6,7 @@ //! [`core::error`] module is marked as stable since 1.81.0, so we want to show //! [`core::error::Error`] as stable since 1.81.0 as well. -use rustc_attr::{Stability, StabilityLevel}; +use rustc_attr_parsing::{Stability, StabilityLevel}; use rustc_hir::def_id::CRATE_DEF_ID; use crate::clean::{Crate, Item, ItemId, ItemKind}; @@ -67,11 +67,12 @@ impl DocFolder for StabilityPropagator<'_, '_> { // Don't inherit the parent's stability for these items, because they // are potentially accessible even if the parent is more unstable. ItemKind::ImplItem(..) - | ItemKind::TyMethodItem(..) + | ItemKind::RequiredMethodItem(..) | ItemKind::MethodItem(..) - | ItemKind::TyAssocConstItem(..) - | ItemKind::AssocConstItem(..) - | ItemKind::TyAssocTypeItem(..) + | ItemKind::RequiredAssocConstItem(..) + | ItemKind::ProvidedAssocConstItem(..) + | ItemKind::ImplAssocConstItem(..) + | ItemKind::RequiredAssocTypeItem(..) | ItemKind::AssocTypeItem(..) | ItemKind::PrimitiveItem(..) | ItemKind::KeywordItem => own_stability, diff --git a/src/librustdoc/passes/stripper.rs b/src/librustdoc/passes/stripper.rs index 60909754b33..eedbbca0f8d 100644 --- a/src/librustdoc/passes/stripper.rs +++ b/src/librustdoc/passes/stripper.rs @@ -79,7 +79,10 @@ impl DocFolder for Stripper<'_, '_> { } } - clean::MethodItem(..) | clean::AssocConstItem(..) | clean::AssocTypeItem(..) => { + clean::MethodItem(..) + | clean::ProvidedAssocConstItem(..) + | clean::ImplAssocConstItem(..) + | clean::AssocTypeItem(..) => { let item_id = i.item_id; if item_id.is_local() && !self.effective_visibilities.is_reachable(self.tcx, item_id.expect_def_id()) @@ -118,7 +121,9 @@ impl DocFolder for Stripper<'_, '_> { clean::ImplItem(..) => {} // tymethods etc. have no control over privacy - clean::TyMethodItem(..) | clean::TyAssocConstItem(..) | clean::TyAssocTypeItem(..) => {} + clean::RequiredMethodItem(..) + | clean::RequiredAssocConstItem(..) + | clean::RequiredAssocTypeItem(..) => {} // Proc-macros are always public clean::ProcMacroItem(..) => {} diff --git a/src/librustdoc/visit.rs b/src/librustdoc/visit.rs index c2e8ffd7665..b8b619514aa 100644 --- a/src/librustdoc/visit.rs +++ b/src/librustdoc/visit.rs @@ -35,7 +35,7 @@ pub(crate) trait DocVisitor<'a>: Sized { | StaticItem(_) | ConstantItem(..) | TraitAliasItem(_) - | TyMethodItem(_) + | RequiredMethodItem(_) | MethodItem(_, _) | StructFieldItem(_) | ForeignFunctionItem(..) @@ -44,9 +44,10 @@ pub(crate) trait DocVisitor<'a>: Sized { | MacroItem(_) | ProcMacroItem(_) | PrimitiveItem(_) - | TyAssocConstItem(..) - | AssocConstItem(..) - | TyAssocTypeItem(..) + | RequiredAssocConstItem(..) + | ProvidedAssocConstItem(..) + | ImplAssocConstItem(..) + | RequiredAssocTypeItem(..) | AssocTypeItem(..) | KeywordItem => {} } diff --git a/src/llvm-project b/src/llvm-project -Subproject 1268e87bdbaed0693a9d782ccd5a21e2cab2de3 +Subproject 59512b00273829823da74050d373b8d46dbca55 diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 39d9158a1ff..561b611148a 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -37,6 +37,7 @@ static HOSTS: &[&str] = &[ "powerpc-unknown-linux-gnu", "powerpc64-unknown-linux-gnu", "powerpc64le-unknown-linux-gnu", + "powerpc64le-unknown-linux-musl", "riscv64gc-unknown-linux-gnu", "s390x-unknown-linux-gnu", "x86_64-apple-darwin", @@ -131,6 +132,7 @@ static TARGETS: &[&str] = &[ "powerpc-unknown-linux-gnu", "powerpc64-unknown-linux-gnu", "powerpc64le-unknown-linux-gnu", + "powerpc64le-unknown-linux-musl", "riscv32i-unknown-none-elf", "riscv32im-risc0-zkvm-elf", "riscv32im-unknown-none-elf", diff --git a/src/tools/cargo b/src/tools/cargo -Subproject 769f622e12db0001431d8ae36d1093fb8727c5d +Subproject 652623b779c88fe44afede28bf7f1c9c0781251 diff --git a/src/tools/clippy/clippy_lints/src/approx_const.rs b/src/tools/clippy/clippy_lints/src/approx_const.rs index ebd35fd2b27..95c85f250e9 100644 --- a/src/tools/clippy/clippy_lints/src/approx_const.rs +++ b/src/tools/clippy/clippy_lints/src/approx_const.rs @@ -2,9 +2,10 @@ use clippy_config::Conf; use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::msrvs::{self, Msrv}; use rustc_ast::ast::{FloatTy, LitFloatType, LitKind}; +use rustc_attr_parsing::RustcVersion; use rustc_hir::{Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; -use rustc_session::{RustcVersion, impl_lint_pass}; +use rustc_session::impl_lint_pass; use rustc_span::symbol; use std::f64::consts as f64; diff --git a/src/tools/clippy/clippy_lints/src/attrs/inline_always.rs b/src/tools/clippy/clippy_lints/src/attrs/inline_always.rs index d41bb580c6c..2325f914b0b 100644 --- a/src/tools/clippy/clippy_lints/src/attrs/inline_always.rs +++ b/src/tools/clippy/clippy_lints/src/attrs/inline_always.rs @@ -1,7 +1,7 @@ use super::INLINE_ALWAYS; use super::utils::is_word; use clippy_utils::diagnostics::span_lint; -use rustc_ast::Attribute; +use rustc_hir::Attribute; use rustc_lint::LateContext; use rustc_span::symbol::Symbol; use rustc_span::{Span, sym}; diff --git a/src/tools/clippy/clippy_lints/src/attrs/should_panic_without_expect.rs b/src/tools/clippy/clippy_lints/src/attrs/should_panic_without_expect.rs index 97cffeb098e..fd27e30a67f 100644 --- a/src/tools/clippy/clippy_lints/src/attrs/should_panic_without_expect.rs +++ b/src/tools/clippy/clippy_lints/src/attrs/should_panic_without_expect.rs @@ -2,20 +2,20 @@ use super::{Attribute, SHOULD_PANIC_WITHOUT_EXPECT}; use clippy_utils::diagnostics::span_lint_and_sugg; use rustc_ast::token::{Token, TokenKind}; use rustc_ast::tokenstream::TokenTree; -use rustc_ast::{AttrArgs, AttrArgsEq, AttrKind}; +use rustc_ast::{AttrArgs, AttrKind}; use rustc_errors::Applicability; use rustc_lint::EarlyContext; use rustc_span::sym; pub(super) fn check(cx: &EarlyContext<'_>, attr: &Attribute) { if let AttrKind::Normal(normal_attr) = &attr.kind { - if let AttrArgs::Eq { value: AttrArgsEq::Ast(_), .. } = &normal_attr.item.args { + if let AttrArgs::Eq { .. } = &normal_attr.item.args { // `#[should_panic = ".."]` found, good return; } if let AttrArgs::Delimited(args) = &normal_attr.item.args - && let mut tt_iter = args.tokens.trees() + && let mut tt_iter = args.tokens.iter() && let Some(TokenTree::Token( Token { kind: TokenKind::Ident(sym::expected, _), diff --git a/src/tools/clippy/clippy_lints/src/booleans.rs b/src/tools/clippy/clippy_lints/src/booleans.rs index 6eef0d42a55..f68a7a89b39 100644 --- a/src/tools/clippy/clippy_lints/src/booleans.rs +++ b/src/tools/clippy/clippy_lints/src/booleans.rs @@ -9,7 +9,8 @@ use rustc_errors::Applicability; use rustc_hir::intravisit::{FnKind, Visitor, walk_expr}; use rustc_hir::{BinOpKind, Body, Expr, ExprKind, FnDecl, UnOp}; use rustc_lint::{LateContext, LateLintPass, Level}; -use rustc_session::{RustcVersion, impl_lint_pass}; +use rustc_attr_parsing::RustcVersion; +use rustc_session::impl_lint_pass; use rustc_span::def_id::LocalDefId; use rustc_span::{Span, sym}; diff --git a/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs b/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs index 383fae7992b..a1ff20dee72 100644 --- a/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs +++ b/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs @@ -5,9 +5,8 @@ use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::visitors::for_each_expr_without_closures; use clippy_utils::{LimitStack, get_async_fn_body, is_async_fn}; use core::ops::ControlFlow; -use rustc_ast::ast::Attribute; use rustc_hir::intravisit::FnKind; -use rustc_hir::{Body, Expr, ExprKind, FnDecl}; +use rustc_hir::{Attribute, Body, Expr, ExprKind, FnDecl}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_session::impl_lint_pass; use rustc_span::def_id::LocalDefId; diff --git a/src/tools/clippy/clippy_lints/src/crate_in_macro_def.rs b/src/tools/clippy/clippy_lints/src/crate_in_macro_def.rs index c8f81413728..7d86bd3e540 100644 --- a/src/tools/clippy/clippy_lints/src/crate_in_macro_def.rs +++ b/src/tools/clippy/clippy_lints/src/crate_in_macro_def.rs @@ -82,11 +82,11 @@ fn is_macro_export(attr: &Attribute) -> bool { fn contains_unhygienic_crate_reference(tts: &TokenStream) -> Option<Span> { let mut prev_is_dollar = false; - let mut cursor = tts.trees(); - while let Some(curr) = cursor.next() { + let mut iter = tts.iter(); + while let Some(curr) = iter.next() { if !prev_is_dollar && let Some(span) = is_crate_keyword(curr) - && let Some(next) = cursor.look_ahead(0) + && let Some(next) = iter.peek() && is_token(next, &TokenKind::PathSep) { return Some(span); diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs index 8125dab8adf..f65edd36253 100644 --- a/src/tools/clippy/clippy_lints/src/derive.rs +++ b/src/tools/clippy/clippy_lints/src/derive.rs @@ -7,7 +7,7 @@ use rustc_errors::Applicability; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{FnKind, Visitor, walk_expr, walk_fn, walk_item}; use rustc_hir::{ - self as hir, BlockCheckMode, BodyId, Expr, ExprKind, FnDecl, Impl, Item, ItemKind, Safety, UnsafeSource, + self as hir, BlockCheckMode, BodyId, Expr, ExprKind, FnDecl, Impl, Item, ItemKind, UnsafeSource, }; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::hir::nested_filter; @@ -421,7 +421,7 @@ impl<'tcx> Visitor<'tcx> for UnsafeVisitor<'_, 'tcx> { id: LocalDefId, ) -> Self::Result { if let Some(header) = kind.header() - && header.safety == Safety::Unsafe + && header.safety.is_unsafe() { ControlFlow::Break(()) } else { diff --git a/src/tools/clippy/clippy_lints/src/doc/empty_line_after.rs b/src/tools/clippy/clippy_lints/src/doc/empty_line_after.rs index de7a2c2433f..099194d4e74 100644 --- a/src/tools/clippy/clippy_lints/src/doc/empty_line_after.rs +++ b/src/tools/clippy/clippy_lints/src/doc/empty_line_after.rs @@ -2,10 +2,10 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::source::{SpanRangeExt, snippet_indent}; use clippy_utils::tokenize_with_text; use itertools::Itertools; +use rustc_ast::AttrStyle; use rustc_ast::token::CommentKind; -use rustc_ast::{AttrKind, AttrStyle, Attribute}; use rustc_errors::{Applicability, Diag, SuggestionStyle}; -use rustc_hir::{ItemKind, Node}; +use rustc_hir::{AttrKind, Attribute, ItemKind, Node}; use rustc_lexer::TokenKind; use rustc_lint::LateContext; use rustc_span::{BytePos, ExpnKind, InnerSpan, Span, SpanData}; diff --git a/src/tools/clippy/clippy_lints/src/doc/include_in_doc_without_cfg.rs b/src/tools/clippy/clippy_lints/src/doc/include_in_doc_without_cfg.rs index 2182689f985..0bb16a0c77d 100644 --- a/src/tools/clippy/clippy_lints/src/doc/include_in_doc_without_cfg.rs +++ b/src/tools/clippy/clippy_lints/src/doc/include_in_doc_without_cfg.rs @@ -1,18 +1,18 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet_opt; -use rustc_ast::{AttrArgs, AttrArgsEq, AttrKind, AttrStyle, Attribute}; +use rustc_ast::{AttrStyle}; use rustc_errors::Applicability; use rustc_lint::LateContext; -use rustc_span::sym; +use rustc_hir::{Attribute, AttrKind, AttrArgs}; use super::DOC_INCLUDE_WITHOUT_CFG; pub fn check(cx: &LateContext<'_>, attrs: &[Attribute]) { for attr in attrs { if !attr.span.from_expansion() - && let AttrKind::Normal(ref normal) = attr.kind - && normal.item.path == sym::doc - && let AttrArgs::Eq { value: AttrArgsEq::Hir(ref meta), .. } = normal.item.args + && let AttrKind::Normal(ref item) = attr.kind + && attr.doc_str().is_some() + && let AttrArgs::Eq { expr: meta, .. } = &item.args && !attr.span.contains(meta.span) // Since the `include_str` is already expanded at this point, we can only take the // whole attribute snippet and then modify for our suggestion. diff --git a/src/tools/clippy/clippy_lints/src/doc/mod.rs b/src/tools/clippy/clippy_lints/src/doc/mod.rs index 88ac871acf6..f65acd7978a 100644 --- a/src/tools/clippy/clippy_lints/src/doc/mod.rs +++ b/src/tools/clippy/clippy_lints/src/doc/mod.rs @@ -16,10 +16,9 @@ use pulldown_cmark::Event::{ }; use pulldown_cmark::Tag::{BlockQuote, CodeBlock, FootnoteDefinition, Heading, Item, Link, Paragraph}; use pulldown_cmark::{BrokenLink, CodeBlockKind, CowStr, Options, TagEnd}; -use rustc_ast::ast::Attribute; use rustc_data_structures::fx::FxHashSet; use rustc_hir::intravisit::{self, Visitor}; -use rustc_hir::{AnonConst, Expr, ImplItemKind, ItemKind, Node, Safety, TraitItemKind}; +use rustc_hir::{AnonConst, Attribute, Expr, ImplItemKind, ItemKind, Node, Safety, TraitItemKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::hir::nested_filter; use rustc_middle::lint::in_external_macro; diff --git a/src/tools/clippy/clippy_lints/src/doc/suspicious_doc_comments.rs b/src/tools/clippy/clippy_lints/src/doc/suspicious_doc_comments.rs index f6f942b10ca..84393213e6f 100644 --- a/src/tools/clippy/clippy_lints/src/doc/suspicious_doc_comments.rs +++ b/src/tools/clippy/clippy_lints/src/doc/suspicious_doc_comments.rs @@ -1,7 +1,8 @@ use clippy_utils::diagnostics::span_lint_and_then; +use rustc_ast::AttrStyle; use rustc_ast::token::CommentKind; -use rustc_ast::{AttrKind, AttrStyle, Attribute}; use rustc_errors::Applicability; +use rustc_hir::Attribute; use rustc_lint::LateContext; use rustc_span::Span; @@ -35,7 +36,7 @@ fn collect_doc_replacements(attrs: &[Attribute]) -> Vec<(Span, String)> { attrs .iter() .filter_map(|attr| { - if let AttrKind::DocComment(com_kind, sym) = attr.kind + if let Some((sym, com_kind)) = attr.doc_str_and_comment_kind() && let AttrStyle::Outer = attr.style && let Some(com) = sym.as_str().strip_prefix('!') { diff --git a/src/tools/clippy/clippy_lints/src/doc/too_long_first_doc_paragraph.rs b/src/tools/clippy/clippy_lints/src/doc/too_long_first_doc_paragraph.rs index 0165d24c7df..0f9ff550853 100644 --- a/src/tools/clippy/clippy_lints/src/doc/too_long_first_doc_paragraph.rs +++ b/src/tools/clippy/clippy_lints/src/doc/too_long_first_doc_paragraph.rs @@ -1,6 +1,5 @@ -use rustc_ast::ast::Attribute; use rustc_errors::Applicability; -use rustc_hir::{Item, ItemKind}; +use rustc_hir::{Attribute, Item, ItemKind}; use rustc_lint::LateContext; use clippy_utils::diagnostics::span_lint_and_then; diff --git a/src/tools/clippy/clippy_lints/src/eta_reduction.rs b/src/tools/clippy/clippy_lints/src/eta_reduction.rs index 8c22e43349f..2cd48ef98e5 100644 --- a/src/tools/clippy/clippy_lints/src/eta_reduction.rs +++ b/src/tools/clippy/clippy_lints/src/eta_reduction.rs @@ -281,7 +281,7 @@ fn check_inputs( } fn check_sig<'tcx>(closure_sig: FnSig<'tcx>, call_sig: FnSig<'tcx>) -> bool { - call_sig.safety == Safety::Safe && !has_late_bound_to_non_late_bound_regions(closure_sig, call_sig) + call_sig.safety.is_safe() && !has_late_bound_to_non_late_bound_regions(closure_sig, call_sig) } /// This walks through both signatures and checks for any time a late-bound region is expected by an diff --git a/src/tools/clippy/clippy_lints/src/functions/misnamed_getters.rs b/src/tools/clippy/clippy_lints/src/functions/misnamed_getters.rs index 2cbc4b07234..017571c38db 100644 --- a/src/tools/clippy/clippy_lints/src/functions/misnamed_getters.rs +++ b/src/tools/clippy/clippy_lints/src/functions/misnamed_getters.rs @@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::source::snippet; use rustc_errors::Applicability; use rustc_hir::intravisit::FnKind; -use rustc_hir::{Body, ExprKind, FnDecl, ImplicitSelfKind, Safety}; +use rustc_hir::{Body, ExprKind, FnDecl, ImplicitSelfKind}; use rustc_lint::LateContext; use rustc_middle::ty; use rustc_span::Span; @@ -34,7 +34,7 @@ pub fn check_fn(cx: &LateContext<'_>, kind: FnKind<'_>, decl: &FnDecl<'_>, body: ImplicitSelfKind::None => return, }; - let name = if sig.header.safety == Safety::Unsafe { + let name = if sig.header.safety.is_unsafe() { name.strip_suffix("_unchecked").unwrap_or(name) } else { name 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 175d92d2d79..2b26285429a 100644 --- a/src/tools/clippy/clippy_lints/src/functions/must_use.rs +++ b/src/tools/clippy/clippy_lints/src/functions/must_use.rs @@ -1,9 +1,8 @@ use hir::FnSig; -use rustc_ast::ast::Attribute; use rustc_errors::Applicability; use rustc_hir::def::Res; use rustc_hir::def_id::DefIdSet; -use rustc_hir::{self as hir, QPath}; +use rustc_hir::{self as hir, Attribute, QPath}; use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::{LateContext, LintContext}; use rustc_middle::lint::in_external_macro; 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 4986a311eba..3ded8dc3012 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 @@ -42,7 +42,7 @@ fn check_raw_ptr<'tcx>( body: &'tcx hir::Body<'tcx>, def_id: LocalDefId, ) { - if safety == hir::Safety::Safe && cx.effective_visibilities.is_exported(def_id) { + if safety.is_safe() && cx.effective_visibilities.is_exported(def_id) { let raw_ptrs = iter_input_pats(decl, body) .filter_map(|arg| raw_ptr_arg(cx, arg)) .collect::<HirIdSet>(); @@ -58,7 +58,7 @@ fn check_raw_ptr<'tcx>( }, hir::ExprKind::MethodCall(_, recv, args, _) => { let def_id = typeck.type_dependent_def_id(e.hir_id).unwrap(); - if cx.tcx.fn_sig(def_id).skip_binder().skip_binder().safety == hir::Safety::Unsafe { + if cx.tcx.fn_sig(def_id).skip_binder().skip_binder().safety.is_unsafe() { check_arg(cx, &raw_ptrs, recv); for arg in args { check_arg(cx, &raw_ptrs, arg); diff --git a/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs b/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs index f3467adacc5..6cee7cfaca2 100644 --- a/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs +++ b/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs @@ -2,12 +2,12 @@ use clippy_config::Conf; use clippy_utils::diagnostics::span_lint; use clippy_utils::is_in_test; use clippy_utils::msrvs::Msrv; -use rustc_attr::{StabilityLevel, StableSince}; +use rustc_attr_parsing::{StabilityLevel, StableSince, RustcVersion}; use rustc_data_structures::fx::FxHashMap; use rustc_hir::{Expr, ExprKind, HirId}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::TyCtxt; -use rustc_session::{RustcVersion, impl_lint_pass}; +use rustc_session::impl_lint_pass; use rustc_span::def_id::DefId; use rustc_span::{ExpnKind, Span}; diff --git a/src/tools/clippy/clippy_lints/src/inherent_to_string.rs b/src/tools/clippy/clippy_lints/src/inherent_to_string.rs index ec6174bc030..e096dd25175 100644 --- a/src/tools/clippy/clippy_lints/src/inherent_to_string.rs +++ b/src/tools/clippy/clippy_lints/src/inherent_to_string.rs @@ -1,7 +1,7 @@ use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::ty::{implements_trait, is_type_lang_item}; use clippy_utils::{return_ty, trait_ref_of_method}; -use rustc_hir::{GenericParamKind, ImplItem, ImplItemKind, LangItem, Safety}; +use rustc_hir::{GenericParamKind, ImplItem, ImplItemKind, LangItem}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::declare_lint_pass; use rustc_span::sym; @@ -95,7 +95,7 @@ impl<'tcx> LateLintPass<'tcx> for InherentToString { if let ImplItemKind::Fn(ref signature, _) = impl_item.kind // #11201 && let header = signature.header - && header.safety == Safety::Safe + && header.safety.is_safe() && header.abi == Abi::Rust && impl_item.ident.name == sym::to_string && let decl = signature.decl diff --git a/src/tools/clippy/clippy_lints/src/large_include_file.rs b/src/tools/clippy/clippy_lints/src/large_include_file.rs index b38e362410e..66d4c40ab5e 100644 --- a/src/tools/clippy/clippy_lints/src/large_include_file.rs +++ b/src/tools/clippy/clippy_lints/src/large_include_file.rs @@ -2,8 +2,8 @@ use clippy_config::Conf; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::macros::root_macro_call_first_node; use clippy_utils::source::snippet_opt; -use rustc_ast::{AttrArgs, AttrArgsEq, AttrKind, Attribute, LitKind}; -use rustc_hir::{Expr, ExprKind}; +use rustc_ast::{LitKind}; +use rustc_hir::{Expr, ExprKind, Attribute, AttrArgs, AttrKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::impl_lint_pass; use rustc_span::{Span, sym}; @@ -93,10 +93,10 @@ impl LateLintPass<'_> for LargeIncludeFile { if !attr.span.from_expansion() // Currently, rustc limits the usage of macro at the top-level of attributes, // so we don't need to recurse into each level. - && let AttrKind::Normal(ref normal) = attr.kind + && let AttrKind::Normal(ref item) = attr.kind && let Some(doc) = attr.doc_str() && doc.as_str().len() as u64 > self.max_file_size - && let AttrArgs::Eq { value: AttrArgsEq::Hir(ref meta), .. } = normal.item.args + && let AttrArgs::Eq { expr: meta, .. } = &item.args && !attr.span.contains(meta.span) // Since the `include_str` is already expanded at this point, we can only take the // whole attribute snippet and then modify for our suggestion. diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs index e80cca6e7db..3e8315588cc 100644 --- a/src/tools/clippy/clippy_lints/src/lib.rs +++ b/src/tools/clippy/clippy_lints/src/lib.rs @@ -35,7 +35,7 @@ extern crate rustc_abi; extern crate rustc_arena; extern crate rustc_ast; extern crate rustc_ast_pretty; -extern crate rustc_attr; +extern crate rustc_attr_parsing; extern crate rustc_data_structures; extern crate rustc_driver; extern crate rustc_errors; diff --git a/src/tools/clippy/clippy_lints/src/macro_use.rs b/src/tools/clippy/clippy_lints/src/macro_use.rs index 22aa681b681..3c669d94d69 100644 --- a/src/tools/clippy/clippy_lints/src/macro_use.rs +++ b/src/tools/clippy/clippy_lints/src/macro_use.rs @@ -1,7 +1,6 @@ use clippy_utils::diagnostics::span_lint_hir_and_then; use clippy_utils::source::snippet; use hir::def::{DefKind, Res}; -use rustc_ast::ast; use rustc_data_structures::fx::FxHashSet; use rustc_errors::Applicability; use rustc_hir as hir; @@ -104,7 +103,7 @@ impl LateLintPass<'_> for MacroUseImports { self.push_unique_macro_pat_ty(cx, item.span); } } - fn check_attribute(&mut self, cx: &LateContext<'_>, attr: &ast::Attribute) { + fn check_attribute(&mut self, cx: &LateContext<'_>, attr: &hir::Attribute) { if attr.span.from_expansion() { self.push_unique_macro(cx, attr.span); } diff --git a/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs b/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs index 47472ab831f..223d0dc7656 100644 --- a/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs +++ b/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs @@ -2,9 +2,9 @@ use super::REDUNDANT_PATTERN_MATCHING; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet_with_applicability; use clippy_utils::{is_lint_allowed, is_wild, span_contains_comment}; -use rustc_ast::{Attribute, LitKind}; +use rustc_ast::LitKind; use rustc_errors::Applicability; -use rustc_hir::{Arm, BorrowKind, Expr, ExprKind, Pat, PatKind, QPath}; +use rustc_hir::{Arm, Attribute, BorrowKind, Expr, ExprKind, Pat, PatKind, QPath}; use rustc_lint::{LateContext, LintContext}; use rustc_middle::ty; use rustc_span::source_map::Spanned; diff --git a/src/tools/clippy/clippy_lints/src/missing_doc.rs b/src/tools/clippy/clippy_lints/src/missing_doc.rs index 1300c7d1062..b6f49dcc163 100644 --- a/src/tools/clippy/clippy_lints/src/missing_doc.rs +++ b/src/tools/clippy/clippy_lints/src/missing_doc.rs @@ -10,8 +10,9 @@ use clippy_utils::attrs::is_doc_hidden; use clippy_utils::diagnostics::span_lint; use clippy_utils::is_from_proc_macro; use clippy_utils::source::SpanRangeExt; -use rustc_ast::ast::{self, MetaItem, MetaItemKind}; +use rustc_ast::ast::MetaItemInner; use rustc_hir as hir; +use rustc_hir::Attribute; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; use rustc_lint::{LateContext, LateLintPass, LintContext}; @@ -67,9 +68,8 @@ impl MissingDoc { *self.doc_hidden_stack.last().expect("empty doc_hidden_stack") } - fn has_include(meta: Option<MetaItem>) -> bool { - if let Some(meta) = meta - && let MetaItemKind::List(list) = meta.kind + fn has_include(meta: Option<&[MetaItemInner]>) -> bool { + if let Some(list) = meta && let Some(meta) = list.first() && let Some(name) = meta.ident() { @@ -83,7 +83,7 @@ impl MissingDoc { &self, cx: &LateContext<'_>, def_id: LocalDefId, - attrs: &[ast::Attribute], + attrs: &[Attribute], sp: Span, article: &'static str, desc: &'static str, @@ -129,7 +129,7 @@ impl MissingDoc { let has_doc = attrs .iter() - .any(|a| a.doc_str().is_some() || Self::has_include(a.meta())) + .any(|a| a.doc_str().is_some() || Self::has_include(a.meta_item_list().as_deref())) || matches!(self.search_span(sp), Some(span) if span_to_snippet_contains_docs(cx, span)); if !has_doc { @@ -172,12 +172,12 @@ impl MissingDoc { impl_lint_pass!(MissingDoc => [MISSING_DOCS_IN_PRIVATE_ITEMS]); impl<'tcx> LateLintPass<'tcx> for MissingDoc { - fn check_attributes(&mut self, _: &LateContext<'tcx>, attrs: &'tcx [ast::Attribute]) { + fn check_attributes(&mut self, _: &LateContext<'tcx>, attrs: &'tcx [Attribute]) { let doc_hidden = self.doc_hidden() || is_doc_hidden(attrs); self.doc_hidden_stack.push(doc_hidden); } - fn check_attributes_post(&mut self, _: &LateContext<'tcx>, _: &'tcx [ast::Attribute]) { + fn check_attributes_post(&mut self, _: &LateContext<'tcx>, _: &'tcx [Attribute]) { self.doc_hidden_stack.pop().expect("empty doc_hidden_stack"); } diff --git a/src/tools/clippy/clippy_lints/src/missing_inline.rs b/src/tools/clippy/clippy_lints/src/missing_inline.rs index e587d695c84..11ff779d531 100644 --- a/src/tools/clippy/clippy_lints/src/missing_inline.rs +++ b/src/tools/clippy/clippy_lints/src/missing_inline.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::span_lint; -use rustc_ast::ast; use rustc_hir as hir; +use rustc_hir::Attribute; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::ty::AssocItemContainer; use rustc_session::declare_lint_pass; @@ -63,7 +63,7 @@ declare_clippy_lint! { "detects missing `#[inline]` attribute for public callables (functions, trait methods, methods...)" } -fn check_missing_inline_attrs(cx: &LateContext<'_>, attrs: &[ast::Attribute], sp: Span, desc: &'static str) { +fn check_missing_inline_attrs(cx: &LateContext<'_>, attrs: &[Attribute], sp: Span, desc: &'static str) { let has_inline = attrs.iter().any(|a| a.has_name(sym::inline)); if !has_inline { span_lint( 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 12bcc608174..79252bba74d 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 @@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::visitors::{Descend, Visitable, for_each_expr}; use core::ops::ControlFlow::Continue; use hir::def::{DefKind, Res}; -use hir::{BlockCheckMode, ExprKind, QPath, Safety, UnOp}; +use hir::{BlockCheckMode, ExprKind, QPath, UnOp}; use rustc_ast::Mutability; use rustc_hir as hir; use rustc_lint::{LateContext, LateLintPass}; @@ -133,7 +133,7 @@ fn collect_unsafe_exprs<'tcx>( ty::FnPtr(sig_tys, hdr) => sig_tys.with(hdr), _ => return Continue(Descend::Yes), }; - if sig.safety() == Safety::Unsafe { + if sig.safety().is_unsafe() { unsafe_ops.push(("unsafe function call occurs here", expr.span)); } }, @@ -144,7 +144,7 @@ fn collect_unsafe_exprs<'tcx>( .type_dependent_def_id(expr.hir_id) .map(|def_id| cx.tcx.fn_sig(def_id)) { - if sig.skip_binder().safety() == Safety::Unsafe { + if sig.skip_binder().safety().is_unsafe() { unsafe_ops.push(("unsafe method call occurs here", expr.span)); } } diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs index 6f3f371a68d..30846fb46ac 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs @@ -5,12 +5,11 @@ use clippy_utils::source::{SpanRangeExt, snippet}; use clippy_utils::ty::{ implements_trait, implements_trait_with_env_from_iter, is_copy, is_type_diagnostic_item, is_type_lang_item, }; -use rustc_ast::ast::Attribute; use rustc_errors::{Applicability, Diag}; use rustc_hir::intravisit::FnKind; use rustc_hir::{ - BindingMode, Body, FnDecl, GenericArg, HirId, HirIdSet, Impl, ItemKind, LangItem, Mutability, Node, PatKind, QPath, - TyKind, + Attribute, BindingMode, Body, FnDecl, GenericArg, HirId, HirIdSet, Impl, ItemKind, LangItem, Mutability, Node, + PatKind, QPath, TyKind, }; use rustc_hir_typeck::expr_use_visitor as euv; use rustc_lint::{LateContext, LateLintPass}; 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 b60fea3f03e..abdce69e764 100644 --- a/src/tools/clippy/clippy_lints/src/new_without_default.rs +++ b/src/tools/clippy/clippy_lints/src/new_without_default.rs @@ -75,7 +75,7 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault { if let hir::ImplItemKind::Fn(ref sig, _) = impl_item.kind { let name = impl_item.ident.name; let id = impl_item.owner_id; - if sig.header.safety == hir::Safety::Unsafe { + if sig.header.safety.is_unsafe() { // can't be implemented for unsafe new return; } diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs index dec4c18a309..b674b01406d 100644 --- a/src/tools/clippy/clippy_lints/src/ptr.rs +++ b/src/tools/clippy/clippy_lints/src/ptr.rs @@ -8,7 +8,7 @@ use rustc_hir::hir_id::{HirId, HirIdMap}; use rustc_hir::intravisit::{Visitor, walk_expr}; use rustc_hir::{ self as hir, AnonConst, BinOpKind, BindingMode, Body, Expr, ExprKind, FnRetTy, FnSig, GenericArg, ImplItemKind, - ItemKind, Lifetime, Mutability, Node, Param, PatKind, QPath, Safety, TraitFn, TraitItem, TraitItemKind, TyKind, + ItemKind, Lifetime, Mutability, Node, Param, PatKind, QPath, TraitFn, TraitItem, TraitItemKind, TyKind, }; use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::{Obligation, ObligationCause}; @@ -475,7 +475,7 @@ fn check_fn_args<'cx, 'tcx: 'cx>( .def_id, ), ty::ReBound(_, r) => r.kind.get_id(), - ty::ReLateParam(r) => r.bound_region.get_id(), + ty::ReLateParam(r) => r.kind.get_id(), ty::ReStatic | ty::ReVar(_) | ty::RePlaceholder(_) @@ -541,7 +541,7 @@ fn check_mut_from_ref<'tcx>(cx: &LateContext<'tcx>, sig: &FnSig<'_>, body: Optio .collect(); if let Some(args) = args && !args.is_empty() - && body.is_none_or(|body| sig.header.safety == Safety::Unsafe || contains_unsafe_block(cx, body.value)) + && body.is_none_or(|body| sig.header.safety.is_unsafe() || contains_unsafe_block(cx, body.value)) { span_lint_and_then( cx, diff --git a/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs b/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs index 2941b9c3960..82ff13a5aff 100644 --- a/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs +++ b/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs @@ -2,7 +2,7 @@ use clippy_config::Conf; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::is_from_proc_macro; use clippy_utils::msrvs::Msrv; -use rustc_attr::{StabilityLevel, StableSince}; +use rustc_attr_parsing::{StabilityLevel, StableSince}; use rustc_errors::Applicability; use rustc_hir::def::Res; use rustc_hir::def_id::DefId; diff --git a/src/tools/clippy/clippy_lints/src/to_string_trait_impl.rs b/src/tools/clippy/clippy_lints/src/to_string_trait_impl.rs index 0361836cdec..9596b85664b 100644 --- a/src/tools/clippy/clippy_lints/src/to_string_trait_impl.rs +++ b/src/tools/clippy/clippy_lints/src/to_string_trait_impl.rs @@ -1,5 +1,4 @@ use clippy_utils::diagnostics::span_lint_and_help; -use clippy_utils::ty::implements_trait; use rustc_hir::{Impl, Item, ItemKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::declare_lint_pass; @@ -54,8 +53,6 @@ impl<'tcx> LateLintPass<'tcx> for ToStringTraitImpl { }) = it.kind && let Some(trait_did) = trait_ref.trait_def_id() && cx.tcx.is_diagnostic_item(sym::ToString, trait_did) - && let Some(display_did) = cx.tcx.get_diagnostic_item(sym::Display) - && !implements_trait(cx, cx.tcx.type_of(it.owner_id).instantiate_identity(), display_did, &[]) { span_lint_and_help( cx, 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 b79e59f857b..45d730985bb 100644 --- a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs +++ b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs @@ -203,7 +203,7 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks { let item_has_safety_comment = item_has_safety_comment(cx, item); match (&item.kind, item_has_safety_comment) { // lint unsafe impl without safety comment - (ItemKind::Impl(impl_), HasSafetyComment::No) if impl_.safety == hir::Safety::Unsafe => { + (ItemKind::Impl(impl_), HasSafetyComment::No) if impl_.safety.is_unsafe() => { if !is_lint_allowed(cx, UNDOCUMENTED_UNSAFE_BLOCKS, item.hir_id()) && !is_unsafe_from_proc_macro(cx, item.span) { @@ -227,7 +227,7 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks { } }, // lint safe impl with unnecessary safety comment - (ItemKind::Impl(impl_), HasSafetyComment::Yes(pos)) if impl_.safety == hir::Safety::Safe => { + (ItemKind::Impl(impl_), HasSafetyComment::Yes(pos)) if impl_.safety.is_safe() => { if !is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, item.hir_id()) { let (span, help_span) = mk_spans(pos); 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 af38e066559..496343d82c8 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 @@ -222,7 +222,7 @@ fn check_invalid_clippy_version_attribute(cx: &LateContext<'_>, item: &'_ Item<' return; } - if rustc_attr::parse_version(value).is_none() { + if rustc_attr_parsing::parse_version(value).is_none() { span_lint_and_help( cx, INVALID_CLIPPY_VERSION_ATTRIBUTE, diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs index 12074dd16e6..623d9c76086 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs @@ -872,8 +872,7 @@ pub fn eq_attr_args(l: &AttrArgs, r: &AttrArgs) -> bool { match (l, r) { (Empty, Empty) => true, (Delimited(la), Delimited(ra)) => eq_delim_args(la, ra), - (Eq { value: AttrArgsEq::Ast(le), .. }, Eq{ value: AttrArgsEq::Ast(re), .. }) => eq_expr(le, re), - (Eq { value: AttrArgsEq::Hir(ll), .. }, Eq{ value: AttrArgsEq::Hir(rl), .. }) => ll.kind == rl.kind, + (Eq { eq_span: _, expr: le }, Eq { eq_span: _, expr: re }) => eq_expr(le, re), _ => false, } } diff --git a/src/tools/clippy/clippy_utils/src/attrs.rs b/src/tools/clippy/clippy_utils/src/attrs.rs index b2a6657baad..922afffb876 100644 --- a/src/tools/clippy/clippy_utils/src/attrs.rs +++ b/src/tools/clippy/clippy_utils/src/attrs.rs @@ -1,4 +1,5 @@ -use rustc_ast::{ast, attr}; +use rustc_ast::attr; +use rustc_ast::attr::AttributeExt; use rustc_errors::Applicability; use rustc_lexer::TokenKind; use rustc_lint::LateContext; @@ -51,33 +52,31 @@ impl LimitStack { pub fn limit(&self) -> u64 { *self.stack.last().expect("there should always be a value in the stack") } - pub fn push_attrs(&mut self, sess: &Session, attrs: &[ast::Attribute], name: &'static str) { + pub fn push_attrs(&mut self, sess: &Session, attrs: &[impl AttributeExt], name: &'static str) { let stack = &mut self.stack; parse_attrs(sess, attrs, name, |val| stack.push(val)); } - pub fn pop_attrs(&mut self, sess: &Session, attrs: &[ast::Attribute], name: &'static str) { + pub fn pop_attrs(&mut self, sess: &Session, attrs: &[impl AttributeExt], name: &'static str) { let stack = &mut self.stack; parse_attrs(sess, attrs, name, |val| assert_eq!(stack.pop(), Some(val))); } } -pub fn get_attr<'a>( +pub fn get_attr<'a, A: AttributeExt + 'a>( sess: &'a Session, - attrs: &'a [ast::Attribute], + attrs: &'a [A], name: &'static str, -) -> impl Iterator<Item = &'a ast::Attribute> { +) -> impl Iterator<Item = &'a A> { attrs.iter().filter(move |attr| { - let attr = if let ast::AttrKind::Normal(ref normal) = attr.kind { - &normal.item - } else { + let Some(attr_segments) = attr.ident_path() else { return false; }; - let attr_segments = &attr.path.segments; - if attr_segments.len() == 2 && attr_segments[0].ident.name == sym::clippy { + + if attr_segments.len() == 2 && attr_segments[0].name == sym::clippy { BUILTIN_ATTRIBUTES .iter() .find_map(|&(builtin_name, ref deprecation_status)| { - if attr_segments[1].ident.name.as_str() == builtin_name { + if attr_segments[1].name.as_str() == builtin_name { Some(deprecation_status) } else { None @@ -85,14 +84,13 @@ pub fn get_attr<'a>( }) .map_or_else( || { - sess.dcx() - .span_err(attr_segments[1].ident.span, "usage of unknown attribute"); + sess.dcx().span_err(attr_segments[1].span, "usage of unknown attribute"); false }, |deprecation_status| { let mut diag = sess .dcx() - .struct_span_err(attr_segments[1].ident.span, "usage of deprecated attribute"); + .struct_span_err(attr_segments[1].span, "usage of deprecated attribute"); match *deprecation_status { DeprecationStatus::Deprecated => { diag.emit(); @@ -100,7 +98,7 @@ pub fn get_attr<'a>( }, DeprecationStatus::Replaced(new_name) => { diag.span_suggestion( - attr_segments[1].ident.span, + attr_segments[1].span, "consider using", new_name, Applicability::MachineApplicable, @@ -110,7 +108,7 @@ pub fn get_attr<'a>( }, DeprecationStatus::None => { diag.cancel(); - attr_segments[1].ident.name.as_str() == name + attr_segments[1].as_str() == name }, } }, @@ -121,31 +119,31 @@ pub fn get_attr<'a>( }) } -fn parse_attrs<F: FnMut(u64)>(sess: &Session, attrs: &[ast::Attribute], name: &'static str, mut f: F) { +fn parse_attrs<F: FnMut(u64)>(sess: &Session, attrs: &[impl AttributeExt], name: &'static str, mut f: F) { for attr in get_attr(sess, attrs, name) { if let Some(ref value) = attr.value_str() { if let Ok(value) = FromStr::from_str(value.as_str()) { f(value); } else { - sess.dcx().span_err(attr.span, "not a number"); + sess.dcx().span_err(attr.span(), "not a number"); } } else { - sess.dcx().span_err(attr.span, "bad clippy attribute"); + sess.dcx().span_err(attr.span(), "bad clippy attribute"); } } } -pub fn get_unique_attr<'a>( +pub fn get_unique_attr<'a, A: AttributeExt>( sess: &'a Session, - attrs: &'a [ast::Attribute], + attrs: &'a [A], name: &'static str, -) -> Option<&'a ast::Attribute> { - let mut unique_attr: Option<&ast::Attribute> = None; +) -> Option<&'a A> { + let mut unique_attr: Option<&A> = None; for attr in get_attr(sess, attrs, name) { if let Some(duplicate) = unique_attr { sess.dcx() - .struct_span_err(attr.span, format!("`{name}` is defined multiple times")) - .with_span_note(duplicate.span, "first definition found here") + .struct_span_err(attr.span(), format!("`{name}` is defined multiple times")) + .with_span_note(duplicate.span(), "first definition found here") .emit(); } else { unique_attr = Some(attr); @@ -156,16 +154,16 @@ pub fn get_unique_attr<'a>( /// Returns true if the attributes contain any of `proc_macro`, /// `proc_macro_derive` or `proc_macro_attribute`, false otherwise -pub fn is_proc_macro(attrs: &[ast::Attribute]) -> bool { - attrs.iter().any(rustc_ast::Attribute::is_proc_macro_attr) +pub fn is_proc_macro(attrs: &[impl AttributeExt]) -> bool { + attrs.iter().any(AttributeExt::is_proc_macro_attr) } /// Returns true if the attributes contain `#[doc(hidden)]` -pub fn is_doc_hidden(attrs: &[ast::Attribute]) -> bool { +pub fn is_doc_hidden(attrs: &[impl AttributeExt]) -> bool { attrs .iter() .filter(|attr| attr.has_name(sym::doc)) - .filter_map(ast::Attribute::meta_item_list) + .filter_map(AttributeExt::meta_item_list) .any(|l| attr::list_contains_name(&l, sym::hidden)) } 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 3269bf758ac..b71b53ea3bb 100644 --- a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs +++ b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs @@ -373,7 +373,7 @@ fn ty_search_pat(ty: &Ty<'_>) -> (Pat, Pat) { TyKind::Ptr(MutTy { ty, .. }) => (Pat::Str("*"), ty_search_pat(ty).1), TyKind::Ref(_, MutTy { ty, .. }) => (Pat::Str("&"), ty_search_pat(ty).1), TyKind::BareFn(bare_fn) => ( - if bare_fn.safety == Safety::Unsafe { + if bare_fn.safety.is_unsafe() { Pat::Str("unsafe") } else if bare_fn.abi != Abi::Rust { Pat::Str("extern") diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 8d48cdd3cbb..02bbddb413a 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -31,7 +31,7 @@ // (Currently there is no way to opt into sysroot crates without `extern crate`.) extern crate rustc_ast; extern crate rustc_ast_pretty; -extern crate rustc_attr; +extern crate rustc_attr_parsing; extern crate rustc_const_eval; extern crate rustc_data_structures; // The `rustc_driver` crate seems to be required in order to use the `rust_ast` crate. @@ -135,13 +135,24 @@ use rustc_middle::hir::nested_filter; #[macro_export] macro_rules! extract_msrv_attr { - ($context:ident) => { - fn check_attributes(&mut self, cx: &rustc_lint::$context<'_>, attrs: &[rustc_ast::ast::Attribute]) { + (LateContext) => { + fn check_attributes(&mut self, cx: &rustc_lint::LateContext<'_>, attrs: &[rustc_hir::Attribute]) { let sess = rustc_lint::LintContext::sess(cx); self.msrv.check_attributes(sess, attrs); } - fn check_attributes_post(&mut self, cx: &rustc_lint::$context<'_>, attrs: &[rustc_ast::ast::Attribute]) { + fn check_attributes_post(&mut self, cx: &rustc_lint::LateContext<'_>, attrs: &[rustc_hir::Attribute]) { + let sess = rustc_lint::LintContext::sess(cx); + self.msrv.check_attributes_post(sess, attrs); + } + }; + (EarlyContext) => { + fn check_attributes(&mut self, cx: &rustc_lint::EarlyContext<'_>, attrs: &[rustc_ast::Attribute]) { + let sess = rustc_lint::LintContext::sess(cx); + self.msrv.check_attributes(sess, attrs); + } + + fn check_attributes_post(&mut self, cx: &rustc_lint::EarlyContext<'_>, attrs: &[rustc_ast::Attribute]) { let sess = rustc_lint::LintContext::sess(cx); self.msrv.check_attributes_post(sess, attrs); } @@ -1912,7 +1923,7 @@ pub fn clip(tcx: TyCtxt<'_>, u: u128, ity: UintTy) -> u128 { (u << amt) >> amt } -pub fn has_attr(attrs: &[ast::Attribute], symbol: Symbol) -> bool { +pub fn has_attr(attrs: &[hir::Attribute], symbol: Symbol) -> bool { attrs.iter().any(|attr| attr.has_name(symbol)) } @@ -2263,21 +2274,13 @@ pub fn std_or_core(cx: &LateContext<'_>) -> Option<&'static str> { pub fn is_no_std_crate(cx: &LateContext<'_>) -> bool { cx.tcx.hir().attrs(hir::CRATE_HIR_ID).iter().any(|attr| { - if let ast::AttrKind::Normal(ref normal) = attr.kind { - normal.item.path == sym::no_std - } else { - false - } + attr.name_or_empty() == sym::no_std }) } pub fn is_no_core_crate(cx: &LateContext<'_>) -> bool { cx.tcx.hir().attrs(hir::CRATE_HIR_ID).iter().any(|attr| { - if let ast::AttrKind::Normal(ref normal) = attr.kind { - normal.item.path == sym::no_core - } else { - false - } + attr.name_or_empty() == sym::no_core }) } diff --git a/src/tools/clippy/clippy_utils/src/msrvs.rs b/src/tools/clippy/clippy_utils/src/msrvs.rs index 1eb7d54e133..1e6368fab36 100644 --- a/src/tools/clippy/clippy_utils/src/msrvs.rs +++ b/src/tools/clippy/clippy_utils/src/msrvs.rs @@ -1,6 +1,6 @@ -use rustc_ast::Attribute; -use rustc_attr::parse_version; -use rustc_session::{RustcVersion, Session}; +use rustc_ast::attr::AttributeExt; +use rustc_attr_parsing::{parse_version, RustcVersion}; +use rustc_session::Session; use rustc_span::{Symbol, sym}; use serde::Deserialize; use smallvec::{SmallVec, smallvec}; @@ -124,15 +124,15 @@ impl Msrv { self.current().is_none_or(|msrv| msrv >= required) } - fn parse_attr(sess: &Session, attrs: &[Attribute]) -> Option<RustcVersion> { + fn parse_attr(sess: &Session, attrs: &[impl AttributeExt]) -> Option<RustcVersion> { let sym_msrv = Symbol::intern("msrv"); let mut msrv_attrs = attrs.iter().filter(|attr| attr.path_matches(&[sym::clippy, sym_msrv])); if let Some(msrv_attr) = msrv_attrs.next() { if let Some(duplicate) = msrv_attrs.last() { sess.dcx() - .struct_span_err(duplicate.span, "`clippy::msrv` is defined multiple times") - .with_span_note(msrv_attr.span, "first definition found here") + .struct_span_err(duplicate.span(), "`clippy::msrv` is defined multiple times") + .with_span_note(msrv_attr.span(), "first definition found here") .emit(); } @@ -142,22 +142,22 @@ impl Msrv { } sess.dcx() - .span_err(msrv_attr.span, format!("`{msrv}` is not a valid Rust version")); + .span_err(msrv_attr.span(), format!("`{msrv}` is not a valid Rust version")); } else { - sess.dcx().span_err(msrv_attr.span, "bad clippy attribute"); + sess.dcx().span_err(msrv_attr.span(), "bad clippy attribute"); } } None } - pub fn check_attributes(&mut self, sess: &Session, attrs: &[Attribute]) { + pub fn check_attributes(&mut self, sess: &Session, attrs: &[impl AttributeExt]) { if let Some(version) = Self::parse_attr(sess, attrs) { self.stack.push(version); } } - pub fn check_attributes_post(&mut self, sess: &Session, attrs: &[Attribute]) { + pub fn check_attributes_post(&mut self, sess: &Session, attrs: &[impl AttributeExt]) { if Self::parse_attr(sess, attrs).is_some() { self.stack.pop(); } diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index df3f10d6179..104ae154e36 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -5,7 +5,7 @@ use crate::msrvs::{self, Msrv}; use hir::LangItem; -use rustc_attr::StableSince; +use rustc_attr_parsing::{RustcVersion, StableSince}; use rustc_const_eval::check_consts::ConstCx; use rustc_hir as hir; use rustc_hir::def_id::DefId; @@ -381,14 +381,14 @@ fn check_terminator<'tcx>( fn is_stable_const_fn(tcx: TyCtxt<'_>, def_id: DefId, msrv: &Msrv) -> bool { tcx.is_const_fn(def_id) && tcx.lookup_const_stability(def_id).is_none_or(|const_stab| { - if let rustc_attr::StabilityLevel::Stable { since, .. } = const_stab.level { + if let rustc_attr_parsing::StabilityLevel::Stable { since, .. } = const_stab.level { // Checking MSRV is manually necessary because `rustc` has no such concept. This entire // function could be removed if `rustc` provided a MSRV-aware version of `is_stable_const_fn`. // as a part of an unimplemented MSRV check https://github.com/rust-lang/rust/issues/65262. let const_stab_rust_version = match since { StableSince::Version(version) => version, - StableSince::Current => rustc_session::RustcVersion::CURRENT, + StableSince::Current => RustcVersion::CURRENT, StableSince::Err => return false, }; diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index 260d1b801e3..bc3c3ca5c21 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -9,7 +9,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir as hir; use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; use rustc_hir::def_id::DefId; -use rustc_hir::{Expr, FnDecl, LangItem, Safety, TyKind}; +use rustc_hir::{Expr, FnDecl, LangItem, TyKind}; use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::LateContext; use rustc_middle::mir::ConstValue; @@ -531,7 +531,7 @@ pub fn peel_mid_ty_refs_is_mutable(ty: Ty<'_>) -> (Ty<'_>, usize, Mutability) { /// Returns `true` if the given type is an `unsafe` function. pub fn type_is_unsafe_function<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { match ty.kind() { - ty::FnDef(..) | ty::FnPtr(..) => ty.fn_sig(cx.tcx).safety() == Safety::Unsafe, + ty::FnDef(..) | ty::FnPtr(..) => ty.fn_sig(cx.tcx).safety().is_unsafe(), _ => false, } } diff --git a/src/tools/clippy/clippy_utils/src/visitors.rs b/src/tools/clippy/clippy_utils/src/visitors.rs index ff58c6358ba..71499b1293a 100644 --- a/src/tools/clippy/clippy_utils/src/visitors.rs +++ b/src/tools/clippy/clippy_utils/src/visitors.rs @@ -7,7 +7,7 @@ use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::intravisit::{self, Visitor, walk_block, walk_expr}; use rustc_hir::{ AnonConst, Arm, Block, BlockCheckMode, Body, BodyId, Expr, ExprKind, HirId, ItemId, ItemKind, LetExpr, Pat, QPath, - Safety, Stmt, UnOp, UnsafeSource, StructTailExpr, + Stmt, UnOp, UnsafeSource, StructTailExpr, }; use rustc_lint::LateContext; use rustc_middle::hir::nested_filter; @@ -426,15 +426,15 @@ pub fn is_expr_unsafe<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> bool { .cx .typeck_results() .type_dependent_def_id(e.hir_id) - .is_some_and(|id| self.cx.tcx.fn_sig(id).skip_binder().safety() == Safety::Unsafe) => + .is_some_and(|id| self.cx.tcx.fn_sig(id).skip_binder().safety().is_unsafe()) => { ControlFlow::Break(()) }, ExprKind::Call(func, _) => match *self.cx.typeck_results().expr_ty(func).peel_refs().kind() { - ty::FnDef(id, _) if self.cx.tcx.fn_sig(id).skip_binder().safety() == Safety::Unsafe => { + ty::FnDef(id, _) if self.cx.tcx.fn_sig(id).skip_binder().safety().is_unsafe() => { ControlFlow::Break(()) }, - ty::FnPtr(_, hdr) if hdr.safety == Safety::Unsafe => ControlFlow::Break(()), + ty::FnPtr(_, hdr) if hdr.safety.is_unsafe() => ControlFlow::Break(()), _ => walk_expr(self, e), }, ExprKind::Path(ref p) @@ -458,7 +458,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 - && i.safety == Safety::Unsafe + && i.safety.is_unsafe() { ControlFlow::Break(()) } else { diff --git a/src/tools/clippy/tests/ui/to_string_trait_impl.rs b/src/tools/clippy/tests/ui/to_string_trait_impl.rs index 4c1202d4203..7be9f7994f0 100644 --- a/src/tools/clippy/tests/ui/to_string_trait_impl.rs +++ b/src/tools/clippy/tests/ui/to_string_trait_impl.rs @@ -30,46 +30,3 @@ impl Bar { String::from("Bar") } } - -mod issue12263 { - pub struct MyStringWrapper<'a>(&'a str); - - impl std::fmt::Display for MyStringWrapper<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.0.fmt(f) - } - } - - impl ToString for MyStringWrapper<'_> { - fn to_string(&self) -> String { - self.0.to_string() - } - } - - pub struct S<T>(T); - impl std::fmt::Display for S<String> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - todo!() - } - } - // no specialization if the generics differ, so lint - impl ToString for S<i32> { - fn to_string(&self) -> String { - todo!() - } - } - - pub struct S2<T>(T); - impl std::fmt::Display for S2<String> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - todo!() - } - } - - // also specialization if the generics don't differ - impl ToString for S2<String> { - fn to_string(&self) -> String { - todo!() - } - } -} diff --git a/src/tools/clippy/tests/ui/to_string_trait_impl.stderr b/src/tools/clippy/tests/ui/to_string_trait_impl.stderr index 304c9a5e1fb..fe8afc215f0 100644 --- a/src/tools/clippy/tests/ui/to_string_trait_impl.stderr +++ b/src/tools/clippy/tests/ui/to_string_trait_impl.stderr @@ -12,17 +12,5 @@ LL | | } = note: `-D clippy::to-string-trait-impl` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::to_string_trait_impl)]` -error: direct implementation of `ToString` - --> tests/ui/to_string_trait_impl.rs:56:5 - | -LL | / impl ToString for S<i32> { -LL | | fn to_string(&self) -> String { -LL | | todo!() -LL | | } -LL | | } - | |_____^ - | - = help: prefer implementing `Display` instead - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error diff --git a/src/tools/compiletest/src/debuggers.rs b/src/tools/compiletest/src/debuggers.rs index b605bc813f1..20e3c8dfb9e 100644 --- a/src/tools/compiletest/src/debuggers.rs +++ b/src/tools/compiletest/src/debuggers.rs @@ -1,6 +1,6 @@ use std::env; use std::ffi::OsString; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use std::process::Command; use std::sync::Arc; @@ -141,7 +141,7 @@ pub(crate) fn extract_cdb_version(full_version_line: &str) -> Option<[u16; 4]> { pub(crate) fn analyze_gdb( gdb: Option<String>, target: &str, - android_cross_path: &PathBuf, + android_cross_path: &Path, ) -> (Option<String>, Option<u32>) { #[cfg(not(windows))] const GDB_FALLBACK: &str = "gdb"; diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index a5a166af33b..d3b4631a212 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -598,10 +598,9 @@ pub fn collect_and_make_tests(config: Arc<Config>) -> Vec<test::TestDescAndFn> { let mut collector = TestCollector { tests: vec![], found_path_stems: HashSet::new(), poisoned: false }; - collect_tests_from_dir(&cx, &mut collector, &cx.config.src_base, &PathBuf::new()) - .unwrap_or_else(|reason| { - panic!("Could not read tests from {}: {reason}", cx.config.src_base.display()) - }); + collect_tests_from_dir(&cx, &mut collector, &cx.config.src_base, Path::new("")).unwrap_or_else( + |reason| panic!("Could not read tests from {}: {reason}", cx.config.src_base.display()), + ); let TestCollector { tests, found_path_stems, poisoned } = collector; diff --git a/src/tools/compiletest/src/read2.rs b/src/tools/compiletest/src/read2.rs index 2375f391d03..62e675c77ae 100644 --- a/src/tools/compiletest/src/read2.rs +++ b/src/tools/compiletest/src/read2.rs @@ -286,7 +286,7 @@ mod imp { impl<'a> Pipe<'a> { unsafe fn new<P: IntoRawHandle>(p: P, dst: &'a mut Vec<u8>) -> Pipe<'a> { Pipe { - dst: dst, + dst, pipe: NamedPipe::from_raw_handle(p.into_raw_handle()), overlapped: Overlapped::zero(), done: false, diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 7b11bf3b121..6a4f0b96bb4 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1,6 +1,6 @@ use std::borrow::Cow; use std::collections::{HashMap, HashSet}; -use std::ffi::OsString; +use std::ffi::{OsStr, OsString}; use std::fs::{self, File, create_dir_all}; use std::hash::{DefaultHasher, Hash, Hasher}; use std::io::prelude::*; @@ -410,7 +410,12 @@ impl<'test> TestCx<'test> { truncated: Truncated::No, cmdline: format!("{cmd:?}"), }; - self.dump_output(&proc_res.stdout, &proc_res.stderr); + self.dump_output( + self.config.verbose, + &cmd.get_program().to_string_lossy(), + &proc_res.stdout, + &proc_res.stderr, + ); proc_res } @@ -1401,7 +1406,12 @@ impl<'test> TestCx<'test> { cmdline, }; - self.dump_output(&result.stdout, &result.stderr); + self.dump_output( + self.config.verbose, + &command.get_program().to_string_lossy(), + &result.stdout, + &result.stderr, + ); result } @@ -1816,12 +1826,35 @@ impl<'test> TestCx<'test> { } } - fn dump_output(&self, out: &str, err: &str) { + fn dump_output(&self, print_output: bool, proc_name: &str, out: &str, err: &str) { let revision = if let Some(r) = self.revision { format!("{}.", r) } else { String::new() }; self.dump_output_file(out, &format!("{}out", revision)); self.dump_output_file(err, &format!("{}err", revision)); - self.maybe_dump_to_stdout(out, err); + + if !print_output { + return; + } + + let path = Path::new(proc_name); + let proc_name = if path.file_stem().is_some_and(|p| p == "rmake") { + OsString::from_iter( + path.parent() + .unwrap() + .file_name() + .into_iter() + .chain(Some(OsStr::new("/"))) + .chain(path.file_name()), + ) + } else { + path.file_name().unwrap().into() + }; + let proc_name = proc_name.to_string_lossy(); + println!("------{proc_name} stdout------------------------------"); + println!("{}", out); + println!("------{proc_name} stderr------------------------------"); + println!("{}", err); + println!("------------------------------------------"); } fn dump_output_file(&self, out: &str, extension: &str) { @@ -1874,16 +1907,6 @@ impl<'test> TestCx<'test> { output_base_name(self.config, self.testpaths, self.safe_revision()) } - fn maybe_dump_to_stdout(&self, out: &str, err: &str) { - if self.config.verbose { - println!("------stdout------------------------------"); - println!("{}", out); - println!("------stderr------------------------------"); - println!("{}", err); - println!("------------------------------------------"); - } - } - fn error(&self, err: &str) { match self.revision { Some(rev) => println!("\nerror in revision `{}`: {}", rev, err), @@ -1935,23 +1958,23 @@ impl<'test> TestCx<'test> { let mut filecheck = Command::new(self.config.llvm_filecheck.as_ref().unwrap()); filecheck.arg("--input-file").arg(output).arg(&self.testpaths.file); - // FIXME: Consider making some of these prefix flags opt-in per test, - // via `filecheck-flags` or by adding new header directives. - // Because we use custom prefixes, we also have to register the default prefix. filecheck.arg("--check-prefix=CHECK"); - // Some tests use the current revision name as a check prefix. + // FIXME(#134510): auto-registering revision names as check prefix is a bit sketchy, and + // that having to pass `--allow-unused-prefix` is an unfortunate side-effect of not knowing + // whether the test author actually wanted revision-specific check prefixes or not. + // + // TL;DR We may not want to conflate `compiletest` revisions and `FileCheck` prefixes. + + // HACK: tests are allowed to use a revision name as a check prefix. if let Some(rev) = self.revision { filecheck.arg("--check-prefix").arg(rev); } - // Some tests also expect either the MSVC or NONMSVC prefix to be defined. - let msvc_or_not = if self.config.target.contains("msvc") { "MSVC" } else { "NONMSVC" }; - filecheck.arg("--check-prefix").arg(msvc_or_not); - - // The filecheck tool normally fails if a prefix is defined but not used. - // However, we define several prefixes globally for all tests. + // HACK: the filecheck tool normally fails if a prefix is defined but not used. However, + // sometimes revisions are used to specify *compiletest* directives which are not FileCheck + // concerns. filecheck.arg("--allow-unused-prefixes"); // Provide more context on failures. @@ -2537,7 +2560,7 @@ impl<'test> TestCx<'test> { }) } - fn delete_file(&self, file: &PathBuf) { + fn delete_file(&self, file: &Path) { if !file.exists() { // Deleting a nonexistent file would error. return; diff --git a/src/tools/compiletest/src/runtest/run_make.rs b/src/tools/compiletest/src/runtest/run_make.rs index 04bc2d7787d..85ade5b727a 100644 --- a/src/tools/compiletest/src/runtest/run_make.rs +++ b/src/tools/compiletest/src/runtest/run_make.rs @@ -517,14 +517,13 @@ impl TestCx<'_> { let proc = disable_error_reporting(|| cmd.spawn().expect("failed to spawn `rmake`")); let (Output { stdout, stderr, status }, truncated) = self.read2_abbreviated(proc); + let stdout = String::from_utf8_lossy(&stdout).into_owned(); + let stderr = String::from_utf8_lossy(&stderr).into_owned(); + // This conditions on `status.success()` so we don't print output twice on error. + // NOTE: this code is called from a libtest thread, so it's hidden by default unless --nocapture is passed. + self.dump_output(status.success(), &cmd.get_program().to_string_lossy(), &stdout, &stderr); if !status.success() { - let res = ProcRes { - status, - stdout: String::from_utf8_lossy(&stdout).into_owned(), - stderr: String::from_utf8_lossy(&stderr).into_owned(), - truncated, - cmdline: format!("{:?}", cmd), - }; + let res = ProcRes { status, stdout, stderr, truncated, cmdline: format!("{:?}", cmd) }; self.fatal_proc_rec("rmake recipe failed to complete", &res); } } diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md index 4e30dea18ff..8f577295d17 100644 --- a/src/tools/miri/README.md +++ b/src/tools/miri/README.md @@ -375,16 +375,19 @@ to Miri failing to detect cases of undefined behavior in a program. * `-Zmiri-disable-weak-memory-emulation` disables the emulation of some C++11 weak memory effects. * `-Zmiri-native-lib=<path to a shared object file>` is an experimental flag for providing support - for calling native functions from inside the interpreter via FFI. Functions not provided by that - file are still executed via the usual Miri shims. - **WARNING**: If an invalid/incorrect `.so` file is specified, this can cause Undefined Behavior in Miri itself! - And of course, Miri cannot do any checks on the actions taken by the native code. - Note that Miri has its own handling of file descriptors, so if you want to replace *some* functions - working on file descriptors, you will have to replace *all* of them, or the two kinds of - file descriptors will be mixed up. - This is **work in progress**; currently, only integer arguments and return values are - supported (and no, pointer/integer casts to work around this limitation will not work; - they will fail horribly). It also only works on Unix hosts for now. + for calling native functions from inside the interpreter via FFI. The flag is supported only on + Unix systems. Functions not provided by that file are still executed via the usual Miri shims. + **WARNING**: If an invalid/incorrect `.so` file is specified, this can cause Undefined Behavior in + Miri itself! And of course, Miri cannot do any checks on the actions taken by the native code. + Note that Miri has its own handling of file descriptors, so if you want to replace *some* + functions working on file descriptors, you will have to replace *all* of them, or the two kinds of + file descriptors will be mixed up. This is **work in progress**; currently, only integer and + pointers arguments and return values are supported and memory allocated by the native code cannot + be accessed from Rust (only the other way around). Native code must not spawn threads that keep + running in the background after the call has returned to Rust and that access Rust-allocated + memory. Finally, the flag is **unsound** in the sense that Miri stops tracking details such as + initialization and provenance on memory shared with native code, so it is easily possible to write + code that has UB which is missed by Miri. * `-Zmiri-measureme=<name>` enables `measureme` profiling for the interpreted program. This can be used to find which parts of your program are executing slowly under Miri. The profile is written out to a file inside a directory called `<name>`, and can be processed diff --git a/src/tools/miri/bench-cargo-miri/backtraces/Cargo.lock b/src/tools/miri/bench-cargo-miri/backtraces/Cargo.lock index 848864ea1f3..86b5e9872e9 100644 --- a/src/tools/miri/bench-cargo-miri/backtraces/Cargo.lock +++ b/src/tools/miri/bench-cargo-miri/backtraces/Cargo.lock @@ -1,35 +1,35 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "addr2line" -version = "0.17.0" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ "gimli", ] [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "backtrace" -version = "0.3.65" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11a17d453482a265fd5f8479f2a3f405566e6ca627837aaddb85af8b1ab8ef61" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", - "cc", "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", + "windows-targets", ] [[package]] @@ -40,15 +40,6 @@ dependencies = [ ] [[package]] -name = "cc" -version = "1.1.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9540e661f81799159abee814118cc139a2004b3a3aa3ea37724a1b66530b90e0" -dependencies = [ - "shlex", -] - -[[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -56,48 +47,106 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "gimli" -version = "0.26.1" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "libc" -version = "0.2.126" +version = "0.2.168" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" +checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d" [[package]] name = "memchr" -version = "2.5.0" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "miniz_oxide" -version = "0.5.3" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" dependencies = [ - "adler", + "adler2", ] [[package]] name = "object" -version = "0.28.4" +version = "0.36.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" dependencies = [ "memchr", ] [[package]] name = "rustc-demangle" -version = "0.1.21" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] -name = "shlex" -version = "1.3.0" +name = "windows_x86_64_msvc" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/src/tools/miri/bench-cargo-miri/serde1/Cargo.lock b/src/tools/miri/bench-cargo-miri/serde1/Cargo.lock index 48750576135..db64ee9a16d 100644 --- a/src/tools/miri/bench-cargo-miri/serde1/Cargo.lock +++ b/src/tools/miri/bench-cargo-miri/serde1/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "cargo-miri-test" @@ -12,48 +12,54 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.2" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "proc-macro2" -version = "1.0.39" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.18" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] [[package]] name = "ryu" -version = "1.0.10" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "serde" -version = "1.0.137" +version = "1.0.216" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" +checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.137" +version = "1.0.216" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" +checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" dependencies = [ "proc-macro2", "quote", @@ -62,20 +68,21 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.81" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] [[package]] name = "syn" -version = "1.0.96" +version = "2.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0748dd251e24453cb8717f0354206b91557e4ec8703673a4b30208f2abaf1ebf" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" dependencies = [ "proc-macro2", "quote", @@ -84,6 +91,6 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.0" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" diff --git a/src/tools/miri/bench-cargo-miri/serde2/Cargo.lock b/src/tools/miri/bench-cargo-miri/serde2/Cargo.lock index 48750576135..db64ee9a16d 100644 --- a/src/tools/miri/bench-cargo-miri/serde2/Cargo.lock +++ b/src/tools/miri/bench-cargo-miri/serde2/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "cargo-miri-test" @@ -12,48 +12,54 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.2" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "proc-macro2" -version = "1.0.39" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.18" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] [[package]] name = "ryu" -version = "1.0.10" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "serde" -version = "1.0.137" +version = "1.0.216" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" +checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.137" +version = "1.0.216" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" +checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" dependencies = [ "proc-macro2", "quote", @@ -62,20 +68,21 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.81" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] [[package]] name = "syn" -version = "1.0.96" +version = "2.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0748dd251e24453cb8717f0354206b91557e4ec8703673a4b30208f2abaf1ebf" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" dependencies = [ "proc-macro2", "quote", @@ -84,6 +91,6 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.0" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" diff --git a/src/tools/miri/bench-cargo-miri/unicode/Cargo.lock b/src/tools/miri/bench-cargo-miri/unicode/Cargo.lock index 80d013b7d6d..170c1529c22 100644 --- a/src/tools/miri/bench-cargo-miri/unicode/Cargo.lock +++ b/src/tools/miri/bench-cargo-miri/unicode/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "unicode" @@ -11,6 +11,6 @@ dependencies = [ [[package]] name = "unicode-xid" -version = "0.2.3" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" diff --git a/src/tools/miri/ci/ci.sh b/src/tools/miri/ci/ci.sh index 8e6e31bee43..5da83a1623c 100755 --- a/src/tools/miri/ci/ci.sh +++ b/src/tools/miri/ci/ci.sh @@ -18,7 +18,7 @@ export RUSTFLAGS="-D warnings" export CARGO_INCREMENTAL=0 export CARGO_EXTRA_FLAGS="--locked" -# Determine configuration for installed build (used by test-cargo-miri). +# Determine configuration for installed build (used by test-cargo-miri and `./miri bench`). echo "Installing release version of Miri" time ./miri install @@ -73,7 +73,7 @@ function run_tests { fi if [ -n "${TEST_BENCH-}" ]; then # Check that the benchmarks build and run, but only once. - time HYPERFINE="hyperfine -w0 -r1" ./miri bench $TARGET_FLAG + time HYPERFINE="hyperfine -w0 -r1 --show-output" ./miri bench $TARGET_FLAG --no-install fi # Smoke-test `./miri run --dep`. ./miri run $TARGET_FLAG --dep tests/pass-dep/getrandom.rs diff --git a/src/tools/miri/miri-script/Cargo.lock b/src/tools/miri/miri-script/Cargo.lock index 0c0fe477cdd..0208327a8dd 100644 --- a/src/tools/miri/miri-script/Cargo.lock +++ b/src/tools/miri/miri-script/Cargo.lock @@ -3,6 +3,55 @@ version = 4 [[package]] +name = "anstream" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" + +[[package]] +name = "anstyle-parse" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" +dependencies = [ + "anstyle", + "windows-sys 0.59.0", +] + +[[package]] name = "anyhow" version = "1.0.80" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -21,6 +70,52 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] +name = "clap" +version = "4.5.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" + +[[package]] +name = "colorchoice" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" + +[[package]] name = "directories" version = "5.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -81,6 +176,12 @@ dependencies = [ ] [[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] name = "home" version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -90,6 +191,12 @@ dependencies = [ ] [[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[package]] name = "itertools" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -137,6 +244,7 @@ name = "miri-script" version = "0.1.0" dependencies = [ "anyhow", + "clap", "directories", "dunce", "itertools", @@ -279,6 +387,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" [[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] name = "syn" version = "2.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -329,6 +443,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] name = "walkdir" version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -362,7 +482,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] diff --git a/src/tools/miri/miri-script/Cargo.toml b/src/tools/miri/miri-script/Cargo.toml index 5b31d5a6ff9..0ab49bbacfc 100644 --- a/src/tools/miri/miri-script/Cargo.toml +++ b/src/tools/miri/miri-script/Cargo.toml @@ -25,3 +25,4 @@ dunce = "1.0.4" directories = "5" serde_json = "1" tempfile = "3.13.0" +clap = { version = "4.5.21", features = ["derive"] } diff --git a/src/tools/miri/miri-script/src/args.rs b/src/tools/miri/miri-script/src/args.rs deleted file mode 100644 index 55d9de4233d..00000000000 --- a/src/tools/miri/miri-script/src/args.rs +++ /dev/null @@ -1,135 +0,0 @@ -use std::{env, iter}; - -use anyhow::{Result, bail}; - -pub struct Args { - args: iter::Peekable<env::Args>, - /// Set to `true` once we saw a `--`. - terminated: bool, -} - -impl Args { - pub fn new() -> Self { - let mut args = Args { args: env::args().peekable(), terminated: false }; - args.args.next().unwrap(); // skip program name - args - } - - /// Get the next argument without any interpretation. - pub fn next_raw(&mut self) -> Option<String> { - self.args.next() - } - - /// Consume a `-$f` flag if present. - pub fn get_short_flag(&mut self, flag: char) -> Result<bool> { - if self.terminated { - return Ok(false); - } - if let Some(next) = self.args.peek() { - if let Some(next) = next.strip_prefix("-") { - if let Some(next) = next.strip_prefix(flag) { - if next.is_empty() { - self.args.next().unwrap(); // consume this argument - return Ok(true); - } else { - bail!("`-{flag}` followed by value"); - } - } - } - } - Ok(false) - } - - /// Consume a `--$name` flag if present. - pub fn get_long_flag(&mut self, name: &str) -> Result<bool> { - if self.terminated { - return Ok(false); - } - if let Some(next) = self.args.peek() { - if let Some(next) = next.strip_prefix("--") { - if next == name { - self.args.next().unwrap(); // consume this argument - return Ok(true); - } - } - } - Ok(false) - } - - /// Consume a `--$name val` or `--$name=val` option if present. - pub fn get_long_opt(&mut self, name: &str) -> Result<Option<String>> { - assert!(!name.is_empty()); - if self.terminated { - return Ok(None); - } - let Some(next) = self.args.peek() else { return Ok(None) }; - let Some(next) = next.strip_prefix("--") else { return Ok(None) }; - let Some(next) = next.strip_prefix(name) else { return Ok(None) }; - // Starts with `--flag`. - Ok(if let Some(val) = next.strip_prefix("=") { - // `--flag=val` form - let val = val.into(); - self.args.next().unwrap(); // consume this argument - Some(val) - } else if next.is_empty() { - // `--flag val` form - self.args.next().unwrap(); // consume this argument - let Some(val) = self.args.next() else { bail!("`--{name}` not followed by value") }; - Some(val) - } else { - // Some unrelated flag, like `--flag-more` or so. - None - }) - } - - /// Consume a `--$name=val` or `--$name` option if present; the latter - /// produces a default value. (`--$name val` is *not* accepted for this form - /// of argument, it understands `val` already as the next argument!) - pub fn get_long_opt_with_default( - &mut self, - name: &str, - default: &str, - ) -> Result<Option<String>> { - assert!(!name.is_empty()); - if self.terminated { - return Ok(None); - } - let Some(next) = self.args.peek() else { return Ok(None) }; - let Some(next) = next.strip_prefix("--") else { return Ok(None) }; - let Some(next) = next.strip_prefix(name) else { return Ok(None) }; - // Starts with `--flag`. - Ok(if let Some(val) = next.strip_prefix("=") { - // `--flag=val` form - let val = val.into(); - self.args.next().unwrap(); // consume this argument - Some(val) - } else if next.is_empty() { - // `--flag` form - self.args.next().unwrap(); // consume this argument - Some(default.into()) - } else { - // Some unrelated flag, like `--flag-more` or so. - None - }) - } - - /// Returns the next free argument or uninterpreted flag, or `None` if there are no more - /// arguments left. `--` is returned as well, but it is interpreted in the sense that no more - /// flags will be parsed after this. - pub fn get_other(&mut self) -> Option<String> { - if self.terminated { - return self.args.next(); - } - let next = self.args.next()?; - if next == "--" { - self.terminated = true; // don't parse any more flags - // This is where our parser is special, we do yield the `--`. - } - Some(next) - } - - /// Return the rest of the aguments entirely unparsed. - pub fn remainder(self) -> Vec<String> { - self.args.collect() - } -} diff --git a/src/tools/miri/miri-script/src/commands.rs b/src/tools/miri/miri-script/src/commands.rs index 21029d0b5b3..55005d86346 100644 --- a/src/tools/miri/miri-script/src/commands.rs +++ b/src/tools/miri/miri-script/src/commands.rs @@ -179,7 +179,8 @@ impl Command { Command::Doc { flags } => Self::doc(flags), Command::Fmt { flags } => Self::fmt(flags), Command::Clippy { flags } => Self::clippy(flags), - Command::Bench { target, benches } => Self::bench(target, benches), + Command::Bench { target, no_install, benches } => + Self::bench(target, no_install, benches), Command::Toolchain { flags } => Self::toolchain(flags), Command::RustcPull { commit } => Self::rustc_pull(commit.clone()), Command::RustcPush { github_user, branch } => Self::rustc_push(github_user, branch), @@ -378,7 +379,7 @@ impl Command { Ok(()) } - fn bench(target: Option<String>, benches: Vec<String>) -> Result<()> { + fn bench(target: Option<String>, no_install: bool, benches: Vec<String>) -> Result<()> { // The hyperfine to use let hyperfine = env::var("HYPERFINE"); let hyperfine = hyperfine.as_deref().unwrap_or("hyperfine -w 1 -m 5 --shell=none"); @@ -386,8 +387,10 @@ impl Command { let Some((program_name, args)) = hyperfine.split_first() else { bail!("expected HYPERFINE environment variable to be non-empty"); }; - // Make sure we have an up-to-date Miri installed and selected the right toolchain. - Self::install(vec![])?; + if !no_install { + // Make sure we have an up-to-date Miri installed and selected the right toolchain. + Self::install(vec![])?; + } let sh = Shell::new()?; sh.change_dir(miri_dir()?); @@ -409,6 +412,7 @@ impl Command { OsString::new() }; let target_flag = &target_flag; + let toolchain = active_toolchain()?; // Run the requested benchmarks for bench in benches { let current_bench = path!(benches_dir / bench / "Cargo.toml"); @@ -416,7 +420,7 @@ impl Command { // That seems to make Windows CI happy. cmd!( sh, - "{program_name} {args...} 'cargo miri run '{target_flag}' --manifest-path \"'{current_bench}'\"'" + "{program_name} {args...} 'cargo +'{toolchain}' miri run '{target_flag}' --manifest-path \"'{current_bench}'\"'" ) .run()?; } diff --git a/src/tools/miri/miri-script/src/main.rs b/src/tools/miri/miri-script/src/main.rs index a329f627903..7592e56cfcf 100644 --- a/src/tools/miri/miri-script/src/main.rs +++ b/src/tools/miri/miri-script/src/main.rs @@ -1,6 +1,5 @@ #![allow(clippy::needless_question_mark)] -mod args; mod commands; mod coverage; mod util; @@ -8,250 +7,191 @@ mod util; use std::ops::Range; use anyhow::{Context, Result, anyhow, bail}; +use clap::{Parser, Subcommand}; + +/// Parses a seed range +/// +/// This function is used for the `--many-seeds` flag. It expects the range in the form +/// `<from>..<to>`. `<from>` is inclusive, `<to>` is exclusive. `<from>` can be omitted, +/// in which case it is assumed to be `0`. +fn parse_range(val: &str) -> anyhow::Result<Range<u32>> { + let (from, to) = val + .split_once("..") + .ok_or_else(|| anyhow!("invalid format for `--many-seeds`: expected `from..to`"))?; + let from: u32 = if from.is_empty() { + 0 + } else { + from.parse().context("invalid `from` in `--many-seeds=from..to")? + }; + let to: u32 = to.parse().context("invalid `to` in `--many-seeds=from..to")?; + Ok(from..to) +} -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Subcommand)] pub enum Command { - /// Installs the miri driver and cargo-miri. + /// Installs the miri driver and cargo-miri to the sysroot of the active toolchain. + /// /// Sets up the rpath such that the installed binary should work in any - /// working directory. Note that the binaries are placed in the `miri` toolchain - /// sysroot, to prevent conflicts with other toolchains. + /// working directory. Install { /// Flags that are passed through to `cargo install`. + #[arg(trailing_var_arg = true, allow_hyphen_values = true)] flags: Vec<String>, }, - /// Just build miri. + /// Build Miri. Build { /// Flags that are passed through to `cargo build`. + #[arg(trailing_var_arg = true, allow_hyphen_values = true)] flags: Vec<String>, }, - /// Just check miri. + /// Check Miri. Check { /// Flags that are passed through to `cargo check`. + #[arg(trailing_var_arg = true, allow_hyphen_values = true)] + flags: Vec<String>, + }, + /// Check Miri with Clippy. + Clippy { + /// Flags that are passed through to `cargo clippy`. + #[arg(trailing_var_arg = true, allow_hyphen_values = true)] flags: Vec<String>, }, - /// Build miri, set up a sysroot and then run the test suite. + /// Run the Miri test suite. Test { + /// Update stdout/stderr reference files. + #[arg(long)] bless: bool, /// The cross-interpretation target. - /// If none then the host is the target. + #[arg(long)] target: Option<String>, - /// Produce coverage report if set. + /// Produce coverage report. + #[arg(long)] coverage: bool, /// Flags that are passed through to the test harness. + #[arg(trailing_var_arg = true, allow_hyphen_values = true)] flags: Vec<String>, }, - /// Build miri, set up a sysroot and then run the driver with the given <flags>. - /// (Also respects MIRIFLAGS environment variable.) + /// Run the Miri driver. + /// + /// Also respects MIRIFLAGS environment variable. Run { + /// Build the program with the dependencies declared in `test_dependencies/Cargo.toml`. + #[arg(long)] dep: bool, + /// Show build progress. + #[arg(long, short)] verbose: bool, + /// Run the driver with the seeds in the given range (`..to` or `from..to`, default: `0..64`). + #[arg(long, value_parser = parse_range)] many_seeds: Option<Range<u32>>, + /// The cross-interpretation target. + #[arg(long)] target: Option<String>, + /// The Rust edition. + #[arg(long)] edition: Option<String>, /// Flags that are passed through to `miri`. + /// + /// The flags set in `MIRIFLAGS` are added in front of these flags. + #[arg(trailing_var_arg = true, allow_hyphen_values = true)] flags: Vec<String>, }, - /// Build documentation + /// Build documentation. Doc { /// Flags that are passed through to `cargo doc`. + #[arg(trailing_var_arg = true, allow_hyphen_values = true)] flags: Vec<String>, }, /// Format all sources and tests. Fmt { /// Flags that are passed through to `rustfmt`. + #[arg(trailing_var_arg = true, allow_hyphen_values = true)] flags: Vec<String>, }, - /// Runs clippy on all sources. - Clippy { - /// Flags that are passed through to `cargo clippy`. - flags: Vec<String>, - }, - /// Runs the benchmarks from bench-cargo-miri in hyperfine. hyperfine needs to be installed. + /// Runs the benchmarks from bench-cargo-miri in hyperfine. + /// + /// hyperfine needs to be installed. Bench { + #[arg(long)] target: Option<String>, - /// List of benchmarks to run. By default all benchmarks are run. + /// When `true`, skip the `./miri install` step. + #[arg(long)] + no_install: bool, + /// List of benchmarks to run (default: run all benchmarks). benches: Vec<String>, }, - /// Update and activate the rustup toolchain 'miri' to the commit given in the - /// `rust-version` file. - /// `rustup-toolchain-install-master` must be installed for this to work. Any extra - /// flags are passed to `rustup-toolchain-install-master`. - Toolchain { flags: Vec<String> }, - /// Pull and merge Miri changes from the rustc repo. Defaults to fetching the latest - /// rustc commit. The fetched commit is stored in the `rust-version` file, so the - /// next `./miri toolchain` will install the rustc that just got pulled. - RustcPull { commit: Option<String> }, - /// Push Miri changes back to the rustc repo. This will pull a copy of the rustc - /// history into the Miri repo, unless you set the RUSTC_GIT env var to an existing - /// clone of the rustc repo. - RustcPush { github_user: String, branch: String }, + /// Update and activate the rustup toolchain 'miri'. + /// + /// The `rust-version` file is used to determine the commit that will be intsalled. + /// `rustup-toolchain-install-master` must be installed for this to work. + Toolchain { + /// Flags that are passed through to `rustup-toolchain-install-master`. + flags: Vec<String>, + }, + /// Pull and merge Miri changes from the rustc repo. + /// + /// The fetched commit is stored in the `rust-version` file, so the next `./miri toolchain` will + /// install the rustc that just got pulled. + RustcPull { + /// The commit to fetch (default: latest rustc commit). + commit: Option<String>, + }, + /// Push Miri changes back to the rustc repo. + /// + /// This will pull a copy of the rustc history into the Miri repo, unless you set the RUSTC_GIT + /// env var to an existing clone of the rustc repo. + RustcPush { + /// The Github user that owns the rustc fork to which we should push. + github_user: String, + /// The branch to push to. + #[arg(default_value = "miri-sync")] + branch: String, + }, } -const HELP: &str = r#" COMMANDS - -./miri build <flags>: -Just build miri. <flags> are passed to `cargo build`. - -./miri check <flags>: -Just check miri. <flags> are passed to `cargo check`. - -./miri test [--bless] [--target <target>] <flags>: -Build miri, set up a sysroot and then run the test suite. -<flags> are passed to the test harness. - -./miri run [--dep] [-v|--verbose] [--many-seeds|--many-seeds=..to|--many-seeds=from..to] <flags>: -Build miri, set up a sysroot and then run the driver with the given <flags>. -(Also respects MIRIFLAGS environment variable.) -If `--many-seeds` is present, Miri is run many times in parallel with different seeds. -The range defaults to `0..64`. - -./miri fmt <flags>: -Format all sources and tests. <flags> are passed to `rustfmt`. - -./miri clippy <flags>: -Runs clippy on all sources. <flags> are passed to `cargo clippy`. - -./miri cargo <flags>: -Runs just `cargo <flags>` with the Miri-specific environment variables. -Mainly meant to be invoked by rust-analyzer. - -./miri install <flags>: -Installs the miri driver and cargo-miri. <flags> are passed to `cargo -install`. Sets up the rpath such that the installed binary should work in any -working directory. Note that the binaries are placed in the `miri` toolchain -sysroot, to prevent conflicts with other toolchains. - -./miri bench [--target <target>] <benches>: -Runs the benchmarks from bench-cargo-miri in hyperfine. hyperfine needs to be installed. -<benches> can explicitly list the benchmarks to run; by default, all of them are run. - -./miri toolchain <flags>: -Update and activate the rustup toolchain 'miri' to the commit given in the -`rust-version` file. -`rustup-toolchain-install-master` must be installed for this to work. Any extra -flags are passed to `rustup-toolchain-install-master`. - -./miri rustc-pull <commit>: -Pull and merge Miri changes from the rustc repo. Defaults to fetching the latest -rustc commit. The fetched commit is stored in the `rust-version` file, so the -next `./miri toolchain` will install the rustc that just got pulled. - -./miri rustc-push <github user> [<branch>]: -Push Miri changes back to the rustc repo. This will pull a copy of the rustc -history into the Miri repo, unless you set the RUSTC_GIT env var to an existing -clone of the rustc repo. The branch defaults to `miri-sync`. - - ENVIRONMENT VARIABLES +impl Command { + fn add_remainder(&mut self, remainder: Vec<String>) -> Result<()> { + if remainder.is_empty() { + return Ok(()); + } -MIRI_SYSROOT: -If already set, the "sysroot setup" step is skipped. + match self { + Self::Install { flags } + | Self::Build { flags } + | Self::Check { flags } + | Self::Doc { flags } + | Self::Fmt { flags } + | Self::Toolchain { flags } + | Self::Clippy { flags } + | Self::Run { flags, .. } + | Self::Test { flags, .. } => { + flags.extend(remainder); + Ok(()) + } + Self::Bench { .. } | Self::RustcPull { .. } | Self::RustcPush { .. } => + bail!("unexpected \"--\" found in arguments"), + } + } +} -CARGO_EXTRA_FLAGS: -Pass extra flags to all cargo invocations. (Ignored by `./miri cargo`.)"#; +#[derive(Parser)] +#[command(after_help = "Environment variables: + MIRI_SYSROOT: If already set, the \"sysroot setup\" step is skipped + CARGO_EXTRA_FLAGS: Pass extra flags to all cargo invocations")] +pub struct Cli { + #[command(subcommand)] + pub command: Command, +} fn main() -> Result<()> { - // We are hand-rolling our own argument parser, since `clap` can't express what we need - // (https://github.com/clap-rs/clap/issues/5055). - let mut args = args::Args::new(); - let command = match args.next_raw().as_deref() { - Some("build") => Command::Build { flags: args.remainder() }, - Some("check") => Command::Check { flags: args.remainder() }, - Some("doc") => Command::Doc { flags: args.remainder() }, - Some("test") => { - let mut target = None; - let mut bless = false; - let mut flags = Vec::new(); - let mut coverage = false; - loop { - if args.get_long_flag("bless")? { - bless = true; - } else if args.get_long_flag("coverage")? { - coverage = true; - } else if let Some(val) = args.get_long_opt("target")? { - target = Some(val); - } else if let Some(flag) = args.get_other() { - flags.push(flag); - } else { - break; - } - } - Command::Test { bless, flags, target, coverage } - } - Some("run") => { - let mut dep = false; - let mut verbose = false; - let mut many_seeds = None; - let mut target = None; - let mut edition = None; - let mut flags = Vec::new(); - loop { - if args.get_long_flag("dep")? { - dep = true; - } else if args.get_long_flag("verbose")? || args.get_short_flag('v')? { - verbose = true; - } else if let Some(val) = args.get_long_opt_with_default("many-seeds", "0..64")? { - let (from, to) = val.split_once("..").ok_or_else(|| { - anyhow!("invalid format for `--many-seeds`: expected `from..to`") - })?; - let from: u32 = if from.is_empty() { - 0 - } else { - from.parse().context("invalid `from` in `--many-seeds=from..to")? - }; - let to: u32 = to.parse().context("invalid `to` in `--many-seeds=from..to")?; - many_seeds = Some(from..to); - } else if let Some(val) = args.get_long_opt("target")? { - target = Some(val); - } else if let Some(val) = args.get_long_opt("edition")? { - edition = Some(val); - } else if let Some(flag) = args.get_other() { - flags.push(flag); - } else { - break; - } - } - Command::Run { dep, verbose, many_seeds, target, edition, flags } - } - Some("fmt") => Command::Fmt { flags: args.remainder() }, - Some("clippy") => Command::Clippy { flags: args.remainder() }, - Some("install") => Command::Install { flags: args.remainder() }, - Some("bench") => { - let mut target = None; - let mut benches = Vec::new(); - loop { - if let Some(val) = args.get_long_opt("target")? { - target = Some(val); - } else if let Some(flag) = args.get_other() { - benches.push(flag); - } else { - break; - } - } - Command::Bench { target, benches } - } - Some("toolchain") => Command::Toolchain { flags: args.remainder() }, - Some("rustc-pull") => { - let commit = args.next_raw(); - if args.next_raw().is_some() { - bail!("Too many arguments for `./miri rustc-pull`"); - } - Command::RustcPull { commit } - } - Some("rustc-push") => { - let github_user = args.next_raw().ok_or_else(|| { - anyhow!("Missing first argument for `./miri rustc-push GITHUB_USER [BRANCH]`") - })?; - let branch = args.next_raw().unwrap_or_else(|| "miri-sync".into()); - if args.next_raw().is_some() { - bail!("Too many arguments for `./miri rustc-push GITHUB_USER BRANCH`"); - } - Command::RustcPush { github_user, branch } - } - _ => { - eprintln!("Unknown or missing command. Usage:\n\n{HELP}"); - std::process::exit(1); - } - }; + // Split the arguments into the part before the `--` and the part after. + // The `--` itself ends up in the second part. + let miri_args: Vec<_> = std::env::args().take_while(|x| *x != "--").collect(); + let remainder: Vec<_> = std::env::args().skip_while(|x| *x != "--").collect(); + + let args = Cli::parse_from(miri_args); + let mut command = args.command; + command.add_remainder(remainder)?; command.exec()?; Ok(()) } diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 57d0b27dfd3..24bef6026d4 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -728f2daab42ba8f1b3d5caab62495798d1eabfa1 +13170cd787cb733ed24842ee825bcbd98dc01476 diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs index 6e157d3fcd3..5d7c3d8c219 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs @@ -237,6 +237,10 @@ impl Permission { pub fn is_active(&self) -> bool { self.inner == Active } + /// Check if `self` is the never-allow-writes-again state of a pointer (is `Frozen`). + pub fn is_frozen(&self) -> bool { + self.inner == Frozen + } /// Default initial permission of the root of a new tree at inbounds positions. /// Must *only* be used for the root, this is not in general an "initial" permission! diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs index 3f524dc589f..fd69278f20a 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs @@ -153,8 +153,31 @@ impl LocationState { ) -> ContinueTraversal { if rel_pos.is_foreign() { let happening_now = IdempotentForeignAccess::from_foreign(access_kind); - let new_access_noop = + let mut new_access_noop = self.idempotent_foreign_access.can_skip_foreign_access(happening_now); + if self.permission.is_disabled() { + // A foreign access to a `Disabled` tag will have almost no observable effect. + // It's a theorem that `Disabled` node have no protected initialized children, + // and so this foreign access will never trigger any protector. + // (Intuition: You're either protected initialized, and thus can't become Disabled + // or you're already Disabled protected, but not initialized, and then can't + // become initialized since that requires a child access, which Disabled blocks.) + // Further, the children will never be able to read or write again, since they + // have a `Disabled` parent. So this only affects diagnostics, such that the + // blocking write will still be identified directly, just at a different tag. + new_access_noop = true; + } + if self.permission.is_frozen() && access_kind == AccessKind::Read { + // A foreign read to a `Frozen` tag will have almost no observable effect. + // It's a theorem that `Frozen` nodes have no active children, so all children + // already survive foreign reads. Foreign reads in general have almost no + // effect, the only further thing they could do is make protected `Reserved` + // nodes become conflicted, i.e. make them reject child writes for the further + // duration of their protector. But such a child write is already rejected + // because this node is frozen. So this only affects diagnostics, but the + // blocking read will still be identified directly, just at a different tag. + new_access_noop = true; + } if new_access_noop { // Abort traversal if the new access is indeed guaranteed // to be noop. diff --git a/src/tools/miri/src/concurrency/thread.rs b/src/tools/miri/src/concurrency/thread.rs index 59e2fdd4285..730c27d0160 100644 --- a/src/tools/miri/src/concurrency/thread.rs +++ b/src/tools/miri/src/concurrency/thread.rs @@ -159,6 +159,8 @@ pub enum BlockReason { Epoll, /// Blocked on eventfd. Eventfd, + /// Blocked on unnamed_socket. + UnnamedSocket, } /// The state of a thread. diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index 41b7be37c37..6b5646d5473 100644 --- a/src/tools/miri/src/diagnostics.rs +++ b/src/tools/miri/src/diagnostics.rs @@ -126,6 +126,7 @@ pub enum NonHaltingDiagnostic { Int2Ptr { details: bool, }, + NativeCallSharedMem, WeakMemoryOutdatedLoad { ptr: Pointer, }, @@ -602,6 +603,8 @@ impl<'tcx> MiriMachine<'tcx> { RejectedIsolatedOp(_) => ("operation rejected by isolation".to_string(), DiagLevel::Warning), Int2Ptr { .. } => ("integer-to-pointer cast".to_string(), DiagLevel::Warning), + NativeCallSharedMem => + ("sharing memory with a native function".to_string(), DiagLevel::Warning), ExternTypeReborrow => ("reborrow of reference to `extern type`".to_string(), DiagLevel::Warning), CreatedPointerTag(..) @@ -637,6 +640,7 @@ impl<'tcx> MiriMachine<'tcx> { ProgressReport { .. } => format!("progress report: current operation being executed is here"), Int2Ptr { .. } => format!("integer-to-pointer cast"), + NativeCallSharedMem => format!("sharing memory with a native function called via FFI"), WeakMemoryOutdatedLoad { ptr } => format!("weak memory emulation: outdated value returned from load at {ptr}"), ExternTypeReborrow => @@ -679,7 +683,29 @@ impl<'tcx> MiriMachine<'tcx> { } v } + NativeCallSharedMem => { + vec![ + note!( + "when memory is shared with a native function call, Miri stops tracking initialization and provenance for that memory" + ), + note!( + "in particular, Miri assumes that the native call initializes all memory it has access to" + ), + note!( + "Miri also assumes that any part of this memory may be a pointer that is permitted to point to arbitrary exposed memory" + ), + note!( + "what this means is that Miri will easily miss Undefined Behavior related to incorrect usage of this shared memory, so you should not take a clean Miri run as a signal that your FFI code is UB-free" + ), + ] + } ExternTypeReborrow => { + assert!(self.borrow_tracker.as_ref().is_some_and(|b| { + matches!( + b.borrow().borrow_tracker_method(), + BorrowTrackerMethod::StackedBorrows + ) + })); vec![ note!( "`extern type` are not compatible with the Stacked Borrows aliasing model implemented by Miri; Miri may miss bugs in this code" diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index 1f7c60ad1bd..bd4a773e23e 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -19,6 +19,7 @@ use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, MaybeResult, TyAndLayout}; use rustc_middle::ty::{self, FloatTy, IntTy, Ty, TyCtxt, UintTy}; use rustc_session::config::CrateType; use rustc_span::{Span, Symbol}; +use rustc_target::callconv::{Conv, FnAbi}; use crate::*; @@ -151,12 +152,14 @@ pub fn iter_exported_symbols<'tcx>( let dependency_format = dependency_formats .get(&CrateType::Executable) .expect("interpreting a non-executable crate"); - for cnum in dependency_format.iter().enumerate().filter_map(|(num, &linkage)| { - // We add 1 to the number because that's what rustc also does everywhere it - // calls `CrateNum::new`... - #[expect(clippy::arithmetic_side_effects)] - (linkage != Linkage::NotLinked).then_some(CrateNum::new(num + 1)) - }) { + for cnum in dependency_format + .iter_enumerated() + .filter_map(|(num, &linkage)| (linkage != Linkage::NotLinked).then_some(num)) + { + if cnum == LOCAL_CRATE { + continue; // Already handled above + } + // We can ignore `_export_info` here: we are a Rust crate, and everything is exported // from a Rust crate. for &(symbol, _export_info) in tcx.exported_symbols(cnum) { @@ -308,18 +311,30 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } /// Project to the given *named* field (which must be a struct or union type). - fn project_field_named<P: Projectable<'tcx, Provenance>>( + fn try_project_field_named<P: Projectable<'tcx, Provenance>>( &self, base: &P, name: &str, - ) -> InterpResult<'tcx, P> { + ) -> InterpResult<'tcx, Option<P>> { let this = self.eval_context_ref(); let adt = base.layout().ty.ty_adt_def().unwrap(); for (idx, field) in adt.non_enum_variant().fields.iter().enumerate() { if field.name.as_str() == name { - return this.project_field(base, idx); + return interp_ok(Some(this.project_field(base, idx)?)); } } + interp_ok(None) + } + + /// Project to the given *named* field (which must be a struct or union type). + fn project_field_named<P: Projectable<'tcx, Provenance>>( + &self, + base: &P, + name: &str, + ) -> InterpResult<'tcx, P> { + if let Some(field) = self.try_project_field_named(base, name)? { + return interp_ok(field); + } bug!("No field named {} in type {}", name, base.layout().ty); } @@ -329,13 +344,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { base: &P, name: &str, ) -> bool { - let adt = base.layout().ty.ty_adt_def().unwrap(); - for field in adt.non_enum_variant().fields.iter() { - if field.name.as_str() == name { - return true; - } - } - false + self.try_project_field_named(base, name).unwrap().is_some() } /// Write an int of the appropriate size to `dest`. The target type may be signed or unsigned, @@ -605,7 +614,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // `UnsafeCell` action. (self.unsafe_cell_action)(v) } - Variants::Single { .. } => { + Variants::Single { .. } | Variants::Empty => { // Proceed further, try to find where exactly that `UnsafeCell` // is hiding. self.walk_value(v) @@ -914,13 +923,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } /// Check that the ABI is what we expect. - fn check_abi<'a>(&self, abi: ExternAbi, exp_abi: ExternAbi) -> InterpResult<'a, ()> { - if abi != exp_abi { + fn check_abi<'a>(&self, fn_abi: &FnAbi<'tcx, Ty<'tcx>>, exp_abi: Conv) -> InterpResult<'a, ()> { + if fn_abi.conv != exp_abi { throw_ub_format!( - "calling a function with ABI {} using caller ABI {}", - exp_abi.name(), - abi.name() - ) + "calling a function with ABI {:?} using caller ABI {:?}", + exp_abi, + fn_abi.conv + ); } interp_ok(()) } @@ -950,8 +959,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn check_abi_and_shim_symbol_clash( &mut self, - abi: ExternAbi, - exp_abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, + exp_abi: Conv, link_name: Symbol, ) -> InterpResult<'tcx, ()> { self.check_abi(abi, exp_abi)?; @@ -975,8 +984,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn check_shim<'a, const N: usize>( &mut self, - abi: ExternAbi, - exp_abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, + exp_abi: Conv, link_name: Symbol, args: &'a [OpTy<'tcx>], ) -> InterpResult<'tcx, &'a [OpTy<'tcx>; N]> diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index 85c896563da..e02d51afcef 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -58,7 +58,7 @@ extern crate tracing; extern crate rustc_abi; extern crate rustc_apfloat; extern crate rustc_ast; -extern crate rustc_attr; +extern crate rustc_attr_parsing; extern crate rustc_const_eval; extern crate rustc_data_structures; extern crate rustc_errors; diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index ac26feb345c..33cefd60764 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -11,7 +11,7 @@ use std::{fmt, process}; use rand::rngs::StdRng; use rand::{Rng, SeedableRng}; use rustc_abi::{Align, ExternAbi, Size}; -use rustc_attr::InlineAttr; +use rustc_attr_parsing::InlineAttr; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; #[allow(unused)] use rustc_data_structures::static_assert_size; @@ -24,6 +24,7 @@ use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; use rustc_session::config::InliningThreshold; use rustc_span::def_id::{CrateNum, DefId}; use rustc_span::{Span, SpanData, Symbol}; +use rustc_target::callconv::FnAbi; use crate::concurrency::cpu_affinity::{self, CpuAffinityMask}; use crate::concurrency::data_race::{self, NaReadType, NaWriteType}; @@ -1010,7 +1011,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { fn find_mir_or_eval_fn( ecx: &mut MiriInterpCx<'tcx>, instance: ty::Instance<'tcx>, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[FnArg<'tcx, Provenance>], dest: &MPlaceTy<'tcx>, ret: Option<mir::BasicBlock>, @@ -1037,7 +1038,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { fn call_extra_fn( ecx: &mut MiriInterpCx<'tcx>, fn_val: DynSym, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[FnArg<'tcx, Provenance>], dest: &MPlaceTy<'tcx>, ret: Option<mir::BasicBlock>, diff --git a/src/tools/miri/src/shims/backtrace.rs b/src/tools/miri/src/shims/backtrace.rs index c7b399228bf..1622ef280d2 100644 --- a/src/tools/miri/src/shims/backtrace.rs +++ b/src/tools/miri/src/shims/backtrace.rs @@ -1,7 +1,8 @@ -use rustc_abi::{ExternAbi, Size}; +use rustc_abi::Size; use rustc_middle::ty::layout::LayoutOf as _; use rustc_middle::ty::{self, Instance, Ty}; use rustc_span::{BytePos, Loc, Symbol, hygiene}; +use rustc_target::callconv::{Conv, FnAbi}; use crate::helpers::check_min_arg_count; use crate::*; @@ -10,13 +11,13 @@ impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn handle_miri_backtrace_size( &mut self, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, link_name: Symbol, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx> { let this = self.eval_context_mut(); - let [flags] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?; + let [flags] = this.check_shim(abi, Conv::Rust, link_name, args)?; let flags = this.read_scalar(flags)?.to_u64()?; if flags != 0 { @@ -30,7 +31,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn handle_miri_get_backtrace( &mut self, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, link_name: Symbol, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, @@ -71,7 +72,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // storage for pointers is allocated by miri // deallocating the slice is undefined behavior with a custom global allocator 0 => { - let [_flags] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?; + let [_flags] = this.check_shim(abi, Conv::Rust, link_name, args)?; let alloc = this.allocate(array_layout, MiriMemoryKind::Rust.into())?; @@ -86,7 +87,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } // storage for pointers is allocated by the caller 1 => { - let [_flags, buf] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?; + let [_flags, buf] = this.check_shim(abi, Conv::Rust, link_name, args)?; let buf_place = this.deref_pointer(buf)?; @@ -136,13 +137,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn handle_miri_resolve_frame( &mut self, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, link_name: Symbol, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx> { let this = self.eval_context_mut(); - let [ptr, flags] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?; + let [ptr, flags] = this.check_shim(abi, Conv::Rust, link_name, args)?; let flags = this.read_scalar(flags)?.to_u64()?; @@ -207,14 +208,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn handle_miri_resolve_frame_names( &mut self, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, link_name: Symbol, args: &[OpTy<'tcx>], ) -> InterpResult<'tcx> { let this = self.eval_context_mut(); let [ptr, flags, name_ptr, filename_ptr] = - this.check_shim(abi, ExternAbi::Rust, link_name, args)?; + this.check_shim(abi, Conv::Rust, link_name, args)?; let flags = this.read_scalar(flags)?.to_u64()?; if flags != 0 { diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index 4dc857ef30b..8c8850ba7e0 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -3,14 +3,16 @@ use std::io::Write; use std::iter; use std::path::Path; -use rustc_abi::{Align, AlignFromBytesError, ExternAbi, Size}; +use rustc_abi::{Align, AlignFromBytesError, Size}; use rustc_apfloat::Float; use rustc_ast::expand::allocator::alloc_error_handler_name; use rustc_hir::def::DefKind; use rustc_hir::def_id::CrateNum; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; +use rustc_middle::ty::Ty; use rustc_middle::{mir, ty}; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; use self::helpers::{ToHost, ToSoft}; use super::alloc::EvalContextExt as _; @@ -39,7 +41,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_foreign_item( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ret: Option<mir::BasicBlock>, @@ -106,7 +108,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_dyn_sym( &mut self, sym: DynSym, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ret: Option<mir::BasicBlock>, @@ -218,7 +220,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_foreign_item_inner( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -235,11 +237,10 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { return interp_ok(EmulateItemResult::NeedsReturn); } } - // When adding a new shim, you should follow the following pattern: // ``` // "shim_name" => { - // let [arg1, arg2, arg3] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + // let [arg1, arg2, arg3] = this.check_shim(abi, Conv::::C , link_name, args)?; // let result = this.shim_name(arg1, arg2, arg3)?; // this.write_scalar(result, dest)?; // } @@ -277,16 +278,16 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { match link_name.as_str() { // Miri-specific extern functions "miri_start_unwind" => { - let [payload] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?; + let [payload] = this.check_shim(abi, Conv::Rust, link_name, args)?; this.handle_miri_start_unwind(payload)?; return interp_ok(EmulateItemResult::NeedsUnwind); } "miri_run_provenance_gc" => { - let [] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?; + let [] = this.check_shim(abi, Conv::Rust, link_name, args)?; this.run_provenance_gc(); } "miri_get_alloc_id" => { - let [ptr] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?; + let [ptr] = this.check_shim(abi, Conv::Rust, link_name, args)?; let ptr = this.read_pointer(ptr)?; let (alloc_id, _, _) = this.ptr_get_alloc_id(ptr, 0).map_err_kind(|_e| { err_machine_stop!(TerminationInfo::Abort(format!( @@ -296,7 +297,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(Scalar::from_u64(alloc_id.0.get()), dest)?; } "miri_print_borrow_state" => { - let [id, show_unnamed] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?; + let [id, show_unnamed] = this.check_shim(abi, Conv::Rust, link_name, args)?; let id = this.read_scalar(id)?.to_u64()?; let show_unnamed = this.read_scalar(show_unnamed)?.to_bool()?; if let Some(id) = std::num::NonZero::new(id).map(AllocId) @@ -310,8 +311,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { "miri_pointer_name" => { // This associates a name to a tag. Very useful for debugging, and also makes // tests more strict. - let [ptr, nth_parent, name] = - this.check_shim(abi, ExternAbi::Rust, link_name, args)?; + let [ptr, nth_parent, name] = this.check_shim(abi, Conv::Rust, link_name, args)?; let ptr = this.read_pointer(ptr)?; let nth_parent = this.read_scalar(nth_parent)?.to_u8()?; let name = this.read_immediate(name)?; @@ -324,7 +324,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { this.give_pointer_debug_name(ptr, nth_parent, &name)?; } "miri_static_root" => { - let [ptr] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?; + let [ptr] = this.check_shim(abi, Conv::Rust, link_name, args)?; let ptr = this.read_pointer(ptr)?; let (alloc_id, offset, _) = this.ptr_get_alloc_id(ptr, 0)?; if offset != Size::ZERO { @@ -335,8 +335,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { this.machine.static_roots.push(alloc_id); } "miri_host_to_target_path" => { - let [ptr, out, out_size] = - this.check_shim(abi, ExternAbi::Rust, link_name, args)?; + let [ptr, out, out_size] = this.check_shim(abi, Conv::Rust, link_name, args)?; let ptr = this.read_pointer(ptr)?; let out = this.read_pointer(out)?; let out_size = this.read_scalar(out_size)?.to_target_usize(this)?; @@ -372,7 +371,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // Writes some bytes to the interpreter's stdout/stderr. See the // README for details. "miri_write_to_stdout" | "miri_write_to_stderr" => { - let [msg] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?; + let [msg] = this.check_shim(abi, Conv::Rust, link_name, args)?; let msg = this.read_immediate(msg)?; let msg = this.read_byte_slice(&msg)?; // Note: we're ignoring errors writing to host stdout/stderr. @@ -386,7 +385,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { "miri_promise_symbolic_alignment" => { use rustc_abi::AlignFromBytesError; - let [ptr, align] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?; + let [ptr, align] = this.check_shim(abi, Conv::Rust, link_name, args)?; let ptr = this.read_pointer(ptr)?; let align = this.read_target_usize(align)?; if !align.is_power_of_two() { @@ -427,13 +426,12 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // Aborting the process. "exit" => { - let [code] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [code] = this.check_shim(abi, Conv::C, link_name, args)?; let code = this.read_scalar(code)?.to_i32()?; throw_machine_stop!(TerminationInfo::Exit { code: code.into(), leak_check: false }); } "abort" => { - let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, Conv::C, link_name, args)?; throw_machine_stop!(TerminationInfo::Abort( "the program aborted execution".to_owned() )) @@ -441,8 +439,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // Standard C allocation "malloc" => { - let [size] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [size] = this.check_shim(abi, Conv::C, link_name, args)?; let size = this.read_target_usize(size)?; if size <= this.max_size_of_val().bytes() { let res = this.malloc(size, /*zero_init:*/ false)?; @@ -456,8 +453,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } } "calloc" => { - let [items, elem_size] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [items, elem_size] = this.check_shim(abi, Conv::C, link_name, args)?; let items = this.read_target_usize(items)?; let elem_size = this.read_target_usize(elem_size)?; if let Some(size) = this.compute_size_in_bytes(Size::from_bytes(elem_size), items) { @@ -472,14 +468,12 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } } "free" => { - let [ptr] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [ptr] = this.check_shim(abi, Conv::C, link_name, args)?; let ptr = this.read_pointer(ptr)?; this.free(ptr)?; } "realloc" => { - let [old_ptr, new_size] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [old_ptr, new_size] = this.check_shim(abi, Conv::C, link_name, args)?; let old_ptr = this.read_pointer(old_ptr)?; let new_size = this.read_target_usize(new_size)?; if new_size <= this.max_size_of_val().bytes() { @@ -499,7 +493,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { let default = |ecx: &mut MiriInterpCx<'tcx>| { // Only call `check_shim` when `#[global_allocator]` isn't used. When that // macro is used, we act like no shim exists, so that the exported function can run. - let [size, align] = ecx.check_shim(abi, ExternAbi::Rust, link_name, args)?; + let [size, align] = ecx.check_shim(abi, Conv::Rust, link_name, args)?; let size = ecx.read_target_usize(size)?; let align = ecx.read_target_usize(align)?; @@ -533,7 +527,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { return this.emulate_allocator(|this| { // See the comment for `__rust_alloc` why `check_shim` is only called in the // default case. - let [size, align] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?; + let [size, align] = this.check_shim(abi, Conv::Rust, link_name, args)?; let size = this.read_target_usize(size)?; let align = this.read_target_usize(align)?; @@ -559,7 +553,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // See the comment for `__rust_alloc` why `check_shim` is only called in the // default case. let [ptr, old_size, align] = - ecx.check_shim(abi, ExternAbi::Rust, link_name, args)?; + ecx.check_shim(abi, Conv::Rust, link_name, args)?; let ptr = ecx.read_pointer(ptr)?; let old_size = ecx.read_target_usize(old_size)?; let align = ecx.read_target_usize(align)?; @@ -594,7 +588,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // See the comment for `__rust_alloc` why `check_shim` is only called in the // default case. let [ptr, old_size, align, new_size] = - this.check_shim(abi, ExternAbi::Rust, link_name, args)?; + this.check_shim(abi, Conv::Rust, link_name, args)?; let ptr = this.read_pointer(ptr)?; let old_size = this.read_target_usize(old_size)?; let align = this.read_target_usize(align)?; @@ -617,8 +611,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // C memory handling functions "memcmp" => { - let [left, right, n] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right, n] = this.check_shim(abi, Conv::C, link_name, args)?; let left = this.read_pointer(left)?; let right = this.read_pointer(right)?; let n = Size::from_bytes(this.read_target_usize(n)?); @@ -642,8 +635,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(Scalar::from_i32(result), dest)?; } "memrchr" => { - let [ptr, val, num] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [ptr, val, num] = this.check_shim(abi, Conv::C, link_name, args)?; let ptr = this.read_pointer(ptr)?; let val = this.read_scalar(val)?.to_i32()?; let num = this.read_target_usize(num)?; @@ -669,8 +661,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } } "memchr" => { - let [ptr, val, num] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [ptr, val, num] = this.check_shim(abi, Conv::C, link_name, args)?; let ptr = this.read_pointer(ptr)?; let val = this.read_scalar(val)?.to_i32()?; let num = this.read_target_usize(num)?; @@ -693,8 +684,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } } "strlen" => { - let [ptr] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [ptr] = this.check_shim(abi, Conv::C, link_name, args)?; let ptr = this.read_pointer(ptr)?; // This reads at least 1 byte, so we are already enforcing that this is a valid pointer. let n = this.read_c_str(ptr)?.len(); @@ -704,8 +694,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { )?; } "wcslen" => { - let [ptr] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [ptr] = this.check_shim(abi, Conv::C, link_name, args)?; let ptr = this.read_pointer(ptr)?; // This reads at least 1 byte, so we are already enforcing that this is a valid pointer. let n = this.read_wchar_t_str(ptr)?.len(); @@ -715,8 +704,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { )?; } "memcpy" => { - let [ptr_dest, ptr_src, n] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [ptr_dest, ptr_src, n] = this.check_shim(abi, Conv::C, link_name, args)?; let ptr_dest = this.read_pointer(ptr_dest)?; let ptr_src = this.read_pointer(ptr_src)?; let n = this.read_target_usize(n)?; @@ -730,8 +718,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_pointer(ptr_dest, dest)?; } "strcpy" => { - let [ptr_dest, ptr_src] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [ptr_dest, ptr_src] = this.check_shim(abi, Conv::C, link_name, args)?; let ptr_dest = this.read_pointer(ptr_dest)?; let ptr_src = this.read_pointer(ptr_src)?; @@ -760,7 +747,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { | "expm1f" | "tgammaf" => { - let [f] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [f] = this.check_shim(abi, Conv::C , link_name, args)?; let f = this.read_scalar(f)?.to_f32()?; // Using host floats (but it's fine, these operations do not have guaranteed precision). let f_host = f.to_host(); @@ -788,7 +775,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { | "atan2f" | "fdimf" => { - let [f1, f2] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [f1, f2] = this.check_shim(abi, Conv::C , link_name, args)?; let f1 = this.read_scalar(f1)?.to_f32()?; let f2 = this.read_scalar(f2)?.to_f32()?; // underscore case for windows, here and below @@ -817,7 +804,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { | "expm1" | "tgamma" => { - let [f] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [f] = this.check_shim(abi, Conv::C , link_name, args)?; let f = this.read_scalar(f)?.to_f64()?; // Using host floats (but it's fine, these operations do not have guaranteed precision). let f_host = f.to_host(); @@ -845,7 +832,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { | "atan2" | "fdim" => { - let [f1, f2] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [f1, f2] = this.check_shim(abi, Conv::C , link_name, args)?; let f1 = this.read_scalar(f1)?.to_f64()?; let f2 = this.read_scalar(f2)?.to_f64()?; // underscore case for windows, here and below @@ -866,7 +853,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { | "ldexp" | "scalbn" => { - let [x, exp] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [x, exp] = this.check_shim(abi, Conv::C , link_name, args)?; // For radix-2 (binary) systems, `ldexp` and `scalbn` are the same. let x = this.read_scalar(x)?.to_f64()?; let exp = this.read_scalar(exp)?.to_i32()?; @@ -876,8 +863,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(res, dest)?; } "lgammaf_r" => { - let [x, signp] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [x, signp] = this.check_shim(abi, Conv::C, link_name, args)?; let x = this.read_scalar(x)?.to_f32()?; let signp = this.deref_pointer(signp)?; @@ -888,8 +874,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(res, dest)?; } "lgamma_r" => { - let [x, signp] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [x, signp] = this.check_shim(abi, Conv::C, link_name, args)?; let x = this.read_scalar(x)?.to_f64()?; let signp = this.deref_pointer(signp)?; @@ -902,8 +887,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // LLVM intrinsics "llvm.prefetch" => { - let [p, rw, loc, ty] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [p, rw, loc, ty] = this.check_shim(abi, Conv::C, link_name, args)?; let _ = this.read_pointer(p)?; let rw = this.read_scalar(rw)?.to_i32()?; @@ -930,7 +914,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // Used to implement the x86 `_mm{,256,512}_popcnt_epi{8,16,32,64}` and wasm // `{i,u}8x16_popcnt` functions. name if name.starts_with("llvm.ctpop.v") => { - let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [op] = this.check_shim(abi, Conv::C, link_name, args)?; let (op, op_len) = this.project_to_simd(op)?; let (dest, dest_len) = this.project_to_simd(dest)?; @@ -961,7 +945,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } // FIXME: Move these to an `arm` submodule. "llvm.aarch64.isb" if this.tcx.sess.target.arch == "aarch64" => { - let [arg] = this.check_shim(abi, ExternAbi::Unadjusted, link_name, args)?; + let [arg] = this.check_shim(abi, Conv::C, link_name, args)?; let arg = this.read_scalar(arg)?.to_i32()?; match arg { // SY ("full system scope") @@ -974,7 +958,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } } "llvm.arm.hint" if this.tcx.sess.target.arch == "arm" => { - let [arg] = this.check_shim(abi, ExternAbi::Unadjusted, link_name, args)?; + let [arg] = this.check_shim(abi, Conv::C, link_name, args)?; let arg = this.read_scalar(arg)?.to_i32()?; // Note that different arguments might have different target feature requirements. match arg { diff --git a/src/tools/miri/src/shims/native_lib.rs b/src/tools/miri/src/shims/native_lib.rs index f18d0236774..345ca3fbcc1 100644 --- a/src/tools/miri/src/shims/native_lib.rs +++ b/src/tools/miri/src/shims/native_lib.rs @@ -1,4 +1,5 @@ //! Implements calling functions from a native library. +use std::cell::RefCell; use std::ops::Deref; use libffi::high::call as ffi; @@ -172,6 +173,18 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Wildcard pointer, whatever it points to must be already exposed. continue; }; + // The first time this happens at a particular location, print a warning. + thread_local! { + static HAVE_WARNED: RefCell<bool> = const { RefCell::new(false) }; + } + HAVE_WARNED.with_borrow_mut(|have_warned| { + if !*have_warned { + // Newly inserted, so first time we see this span. + this.emit_diagnostic(NonHaltingDiagnostic::NativeCallSharedMem); + *have_warned = true; + } + }); + this.prepare_for_native_call(alloc_id, prov)?; } } diff --git a/src/tools/miri/src/shims/time.rs b/src/tools/miri/src/shims/time.rs index 6436823b0fd..72d98bc1c48 100644 --- a/src/tools/miri/src/shims/time.rs +++ b/src/tools/miri/src/shims/time.rs @@ -180,6 +180,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { if !matches!(&*this.tcx.sess.target.os, "solaris" | "illumos") { // tm_zone represents the timezone value in the form of: +0730, +08, -0730 or -08. // This may not be consistent with libc::localtime_r's result. + let offset_in_seconds = dt.offset().fix().local_minus_utc(); let tm_gmtoff = offset_in_seconds; let mut tm_zone = String::new(); @@ -195,11 +196,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { write!(tm_zone, "{:02}", offset_min).unwrap(); } - // FIXME: String de-duplication is needed so that we only allocate this string only once - // even when there are multiple calls to this function. - let tm_zone_ptr = this - .alloc_os_str_as_c_str(&OsString::from(tm_zone), MiriMemoryKind::Machine.into())?; + // Add null terminator for C string compatibility. + tm_zone.push('\0'); + + // Deduplicate and allocate the string. + let tm_zone_ptr = this.allocate_bytes_dedup(tm_zone.as_bytes())?; + // Write the timezone pointer and offset into the result structure. this.write_pointer(tm_zone_ptr, &this.project_field_named(&result, "tm_zone")?)?; this.write_int_fields_named(&[("tm_gmtoff", tm_gmtoff.into())], &result)?; } diff --git a/src/tools/miri/src/shims/unix/android/foreign_items.rs b/src/tools/miri/src/shims/unix/android/foreign_items.rs index f9003885450..0e7cf7153f5 100644 --- a/src/tools/miri/src/shims/unix/android/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/android/foreign_items.rs @@ -1,5 +1,6 @@ -use rustc_abi::ExternAbi; +use rustc_middle::ty::Ty; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; use crate::shims::unix::android::thread::prctl; use crate::shims::unix::linux_like::epoll::EvalContextExt as _; @@ -16,7 +17,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_foreign_item_inner( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -24,32 +25,29 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { match link_name.as_str() { // epoll, eventfd "epoll_create1" => { - let [flag] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [flag] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.epoll_create1(flag)?; this.write_scalar(result, dest)?; } "epoll_ctl" => { - let [epfd, op, fd, event] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [epfd, op, fd, event] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.epoll_ctl(epfd, op, fd, event)?; this.write_scalar(result, dest)?; } "epoll_wait" => { let [epfd, events, maxevents, timeout] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; this.epoll_wait(epfd, events, maxevents, timeout, dest)?; } "eventfd" => { - let [val, flag] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [val, flag] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.eventfd(val, flag)?; this.write_scalar(result, dest)?; } // Miscellaneous "__errno" => { - let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, Conv::C, link_name, args)?; let errno_place = this.last_error_place()?; this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?; } diff --git a/src/tools/miri/src/shims/unix/android/thread.rs b/src/tools/miri/src/shims/unix/android/thread.rs index f8a0b3a85a2..8d5d4a52b6e 100644 --- a/src/tools/miri/src/shims/unix/android/thread.rs +++ b/src/tools/miri/src/shims/unix/android/thread.rs @@ -1,5 +1,7 @@ -use rustc_abi::{ExternAbi, Size}; +use rustc_abi::Size; +use rustc_middle::ty::Ty; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; use crate::helpers::check_min_arg_count; use crate::shims::unix::thread::{EvalContextExt as _, ThreadNameResult}; @@ -10,13 +12,13 @@ const TASK_COMM_LEN: usize = 16; pub fn prctl<'tcx>( ecx: &mut MiriInterpCx<'tcx>, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx> { // We do not use `check_shim` here because `prctl` is variadic. The argument // count is checked bellow. - ecx.check_abi_and_shim_symbol_clash(abi, ExternAbi::C { unwind: false }, link_name)?; + ecx.check_abi_and_shim_symbol_clash(abi, Conv::C, link_name)?; // FIXME: Use constants once https://github.com/rust-lang/libc/pull/3941 backported to the 0.2 branch. let pr_set_name = 15; diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs index 88ec32808b1..f47a96b10fe 100644 --- a/src/tools/miri/src/shims/unix/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/foreign_items.rs @@ -1,9 +1,11 @@ use std::ffi::OsStr; use std::str; -use rustc_abi::{ExternAbi, Size}; +use rustc_abi::Size; +use rustc_middle::ty::Ty; use rustc_middle::ty::layout::LayoutOf; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; use self::shims::unix::android::foreign_items as android; use self::shims::unix::freebsd::foreign_items as freebsd; @@ -100,7 +102,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_foreign_item_inner( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -111,54 +113,52 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { match link_name.as_str() { // Environment related shims "getenv" => { - let [name] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [name] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.getenv(name)?; this.write_pointer(result, dest)?; } "unsetenv" => { - let [name] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [name] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.unsetenv(name)?; this.write_scalar(result, dest)?; } "setenv" => { - let [name, value, overwrite] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [name, value, overwrite] = this.check_shim(abi, Conv::C , link_name, args)?; this.read_scalar(overwrite)?.to_i32()?; let result = this.setenv(name, value)?; this.write_scalar(result, dest)?; } "getcwd" => { - let [buf, size] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [buf, size] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.getcwd(buf, size)?; this.write_pointer(result, dest)?; } "chdir" => { - let [path] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [path] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.chdir(path)?; this.write_scalar(result, dest)?; } "getpid" => { - let [] = this.check_shim(abi, ExternAbi::C { unwind: false}, link_name, args)?; + let [] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.getpid()?; this.write_scalar(result, dest)?; } - "sysconf" => { let [val] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let result = this.sysconf(val)?; this.write_scalar(result, dest)?; } - // File descriptors "read" => { - let [fd, buf, count] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [fd, buf, count] = this.check_shim(abi, Conv::C , link_name, args)?; let fd = this.read_scalar(fd)?.to_i32()?; let buf = this.read_pointer(buf)?; let count = this.read_target_usize(count)?; this.read(fd, buf, count, None, dest)?; } "write" => { - let [fd, buf, n] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [fd, buf, n] = this.check_shim(abi, Conv::C , link_name, args)?; let fd = this.read_scalar(fd)?.to_i32()?; let buf = this.read_pointer(buf)?; let count = this.read_target_usize(n)?; @@ -166,7 +166,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write(fd, buf, count, None, dest)?; } "pread" => { - let [fd, buf, count, offset] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [fd, buf, count, offset] = this.check_shim(abi, Conv::C , link_name, args)?; let fd = this.read_scalar(fd)?.to_i32()?; let buf = this.read_pointer(buf)?; let count = this.read_target_usize(count)?; @@ -174,7 +174,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.read(fd, buf, count, Some(offset), dest)?; } "pwrite" => { - let [fd, buf, n, offset] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [fd, buf, n, offset] = this.check_shim(abi, Conv::C , link_name, args)?; let fd = this.read_scalar(fd)?.to_i32()?; let buf = this.read_pointer(buf)?; let count = this.read_target_usize(n)?; @@ -183,7 +183,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write(fd, buf, count, Some(offset), dest)?; } "pread64" => { - let [fd, buf, count, offset] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [fd, buf, count, offset] = this.check_shim(abi, Conv::C , link_name, args)?; let fd = this.read_scalar(fd)?.to_i32()?; let buf = this.read_pointer(buf)?; let count = this.read_target_usize(count)?; @@ -191,7 +191,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.read(fd, buf, count, Some(offset), dest)?; } "pwrite64" => { - let [fd, buf, n, offset] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [fd, buf, n, offset] = this.check_shim(abi, Conv::C , link_name, args)?; let fd = this.read_scalar(fd)?.to_i32()?; let buf = this.read_pointer(buf)?; let count = this.read_target_usize(n)?; @@ -200,32 +200,32 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write(fd, buf, count, Some(offset), dest)?; } "close" => { - let [fd] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [fd] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.close(fd)?; this.write_scalar(result, dest)?; } "fcntl" => { // `fcntl` is variadic. The argument count is checked based on the first argument // in `this.fcntl()`, so we do not use `check_shim` here. - this.check_abi_and_shim_symbol_clash(abi, ExternAbi::C { unwind: false }, link_name)?; + this.check_abi_and_shim_symbol_clash(abi, Conv::C , link_name)?; let result = this.fcntl(args)?; this.write_scalar(result, dest)?; } "dup" => { - let [old_fd] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [old_fd] = this.check_shim(abi, Conv::C , link_name, args)?; let old_fd = this.read_scalar(old_fd)?.to_i32()?; let new_fd = this.dup(old_fd)?; this.write_scalar(new_fd, dest)?; } "dup2" => { - let [old_fd, new_fd] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [old_fd, new_fd] = this.check_shim(abi, Conv::C , link_name, args)?; let old_fd = this.read_scalar(old_fd)?.to_i32()?; let new_fd = this.read_scalar(new_fd)?.to_i32()?; let result = this.dup2(old_fd, new_fd)?; this.write_scalar(result, dest)?; } "flock" => { - let [fd, op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [fd, op] = this.check_shim(abi, Conv::C , link_name, args)?; let fd = this.read_scalar(fd)?.to_i32()?; let op = this.read_scalar(op)?.to_i32()?; let result = this.flock(fd, op)?; @@ -235,47 +235,47 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // File and file system access "open" | "open64" => { // `open` is variadic, the third argument is only present when the second argument has O_CREAT (or on linux O_TMPFILE, but miri doesn't support that) set - this.check_abi_and_shim_symbol_clash(abi, ExternAbi::C { unwind: false }, link_name)?; + this.check_abi_and_shim_symbol_clash(abi, Conv::C , link_name)?; let result = this.open(args)?; this.write_scalar(result, dest)?; } "unlink" => { - let [path] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [path] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.unlink(path)?; this.write_scalar(result, dest)?; } "symlink" => { - let [target, linkpath] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [target, linkpath] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.symlink(target, linkpath)?; this.write_scalar(result, dest)?; } "rename" => { - let [oldpath, newpath] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [oldpath, newpath] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.rename(oldpath, newpath)?; this.write_scalar(result, dest)?; } "mkdir" => { - let [path, mode] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [path, mode] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.mkdir(path, mode)?; this.write_scalar(result, dest)?; } "rmdir" => { - let [path] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [path] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.rmdir(path)?; this.write_scalar(result, dest)?; } "opendir" => { - let [name] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [name] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.opendir(name)?; this.write_scalar(result, dest)?; } "closedir" => { - let [dirp] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [dirp] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.closedir(dirp)?; this.write_scalar(result, dest)?; } "lseek64" => { - let [fd, offset, whence] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [fd, offset, whence] = this.check_shim(abi, Conv::C , link_name, args)?; let fd = this.read_scalar(fd)?.to_i32()?; let offset = this.read_scalar(offset)?.to_i64()?; let whence = this.read_scalar(whence)?.to_i32()?; @@ -283,7 +283,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(result, dest)?; } "lseek" => { - let [fd, offset, whence] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [fd, offset, whence] = this.check_shim(abi, Conv::C , link_name, args)?; let fd = this.read_scalar(fd)?.to_i32()?; let offset = this.read_scalar(offset)?.to_int(this.libc_ty_layout("off_t").size)?; let whence = this.read_scalar(whence)?.to_i32()?; @@ -292,7 +292,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "ftruncate64" => { let [fd, length] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; let fd = this.read_scalar(fd)?.to_i32()?; let length = this.read_scalar(length)?.to_i64()?; let result = this.ftruncate64(fd, length.into())?; @@ -300,30 +300,30 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "ftruncate" => { let [fd, length] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; let fd = this.read_scalar(fd)?.to_i32()?; let length = this.read_scalar(length)?.to_int(this.libc_ty_layout("off_t").size)?; let result = this.ftruncate64(fd, length)?; this.write_scalar(result, dest)?; } "fsync" => { - let [fd] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [fd] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.fsync(fd)?; this.write_scalar(result, dest)?; } "fdatasync" => { - let [fd] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [fd] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.fdatasync(fd)?; this.write_scalar(result, dest)?; } "readlink" => { - let [pathname, buf, bufsize] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [pathname, buf, bufsize] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.readlink(pathname, buf, bufsize)?; this.write_scalar(Scalar::from_target_isize(result, this), dest)?; } "posix_fadvise" => { let [fd, offset, len, advice] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; this.read_scalar(fd)?.to_i32()?; this.read_target_isize(offset)?; this.read_target_isize(len)?; @@ -332,12 +332,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_null(dest)?; } "realpath" => { - let [path, resolved_path] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [path, resolved_path] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.realpath(path, resolved_path)?; this.write_scalar(result, dest)?; } "mkstemp" => { - let [template] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [template] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.mkstemp(template)?; this.write_scalar(result, dest)?; } @@ -345,13 +345,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Unnamed sockets and pipes "socketpair" => { let [domain, type_, protocol, sv] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; let result = this.socketpair(domain, type_, protocol, sv)?; this.write_scalar(result, dest)?; } "pipe" => { let [pipefd] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; let result = this.pipe2(pipefd, /*flags*/ None)?; this.write_scalar(result, dest)?; } @@ -364,44 +364,44 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ); } let [pipefd, flags] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; let result = this.pipe2(pipefd, Some(flags))?; this.write_scalar(result, dest)?; } // Time "gettimeofday" => { - let [tv, tz] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [tv, tz] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.gettimeofday(tv, tz)?; this.write_scalar(result, dest)?; } "localtime_r" => { - let [timep, result_op] = this.check_shim(abi, ExternAbi::C {unwind: false}, link_name, args)?; + let [timep, result_op] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.localtime_r(timep, result_op)?; this.write_pointer(result, dest)?; } "clock_gettime" => { let [clk_id, tp] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; let result = this.clock_gettime(clk_id, tp)?; this.write_scalar(result, dest)?; } // Allocation "posix_memalign" => { - let [memptr, align, size] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [memptr, align, size] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.posix_memalign(memptr, align, size)?; this.write_scalar(result, dest)?; } "mmap" => { - let [addr, length, prot, flags, fd, offset] = this.check_shim(abi, ExternAbi::C {unwind: false}, link_name, args)?; + let [addr, length, prot, flags, fd, offset] = this.check_shim(abi, Conv::C , link_name, args)?; let offset = this.read_scalar(offset)?.to_int(this.libc_ty_layout("off_t").size)?; let ptr = this.mmap(addr, length, prot, flags, fd, offset)?; this.write_scalar(ptr, dest)?; } "munmap" => { - let [addr, length] = this.check_shim(abi, ExternAbi::C {unwind: false}, link_name, args)?; + let [addr, length] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.munmap(addr, length)?; this.write_scalar(result, dest)?; } @@ -415,7 +415,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ); } let [ptr, nmemb, size] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; let ptr = this.read_pointer(ptr)?; let nmemb = this.read_target_usize(nmemb)?; let size = this.read_target_usize(size)?; @@ -439,14 +439,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // This is a C11 function, we assume all Unixes have it. // (MSVC explicitly does not support this.) let [align, size] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; let res = this.aligned_alloc(align, size)?; this.write_pointer(res, dest)?; } // Dynamic symbol loading "dlsym" => { - let [handle, symbol] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [handle, symbol] = this.check_shim(abi, Conv::C , link_name, args)?; this.read_target_usize(handle)?; let symbol = this.read_pointer(symbol)?; let name = this.read_c_str(symbol)?; @@ -460,7 +460,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Thread-local storage "pthread_key_create" => { - let [key, dtor] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [key, dtor] = this.check_shim(abi, Conv::C , link_name, args)?; let key_place = this.deref_pointer_as(key, this.libc_ty_layout("pthread_key_t"))?; let dtor = this.read_pointer(dtor)?; @@ -488,21 +488,21 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_null(dest)?; } "pthread_key_delete" => { - let [key] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [key] = this.check_shim(abi, Conv::C , link_name, args)?; let key = this.read_scalar(key)?.to_bits(key.layout.size)?; this.machine.tls.delete_tls_key(key)?; // Return success (0) this.write_null(dest)?; } "pthread_getspecific" => { - let [key] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [key] = this.check_shim(abi, Conv::C , link_name, args)?; let key = this.read_scalar(key)?.to_bits(key.layout.size)?; let active_thread = this.active_thread(); let ptr = this.machine.tls.load_tls(key, active_thread, this)?; this.write_scalar(ptr, dest)?; } "pthread_setspecific" => { - let [key, new_ptr] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [key, new_ptr] = this.check_shim(abi, Conv::C , link_name, args)?; let key = this.read_scalar(key)?.to_bits(key.layout.size)?; let active_thread = this.active_thread(); let new_data = this.read_scalar(new_ptr)?; @@ -514,151 +514,151 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Synchronization primitives "pthread_mutexattr_init" => { - let [attr] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [attr] = this.check_shim(abi, Conv::C , link_name, args)?; this.pthread_mutexattr_init(attr)?; this.write_null(dest)?; } "pthread_mutexattr_settype" => { - let [attr, kind] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [attr, kind] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.pthread_mutexattr_settype(attr, kind)?; this.write_scalar(result, dest)?; } "pthread_mutexattr_destroy" => { - let [attr] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [attr] = this.check_shim(abi, Conv::C , link_name, args)?; this.pthread_mutexattr_destroy(attr)?; this.write_null(dest)?; } "pthread_mutex_init" => { - let [mutex, attr] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [mutex, attr] = this.check_shim(abi, Conv::C , link_name, args)?; this.pthread_mutex_init(mutex, attr)?; this.write_null(dest)?; } "pthread_mutex_lock" => { - let [mutex] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [mutex] = this.check_shim(abi, Conv::C , link_name, args)?; this.pthread_mutex_lock(mutex, dest)?; } "pthread_mutex_trylock" => { - let [mutex] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [mutex] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.pthread_mutex_trylock(mutex)?; this.write_scalar(result, dest)?; } "pthread_mutex_unlock" => { - let [mutex] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [mutex] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.pthread_mutex_unlock(mutex)?; this.write_scalar(result, dest)?; } "pthread_mutex_destroy" => { - let [mutex] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [mutex] = this.check_shim(abi, Conv::C , link_name, args)?; this.pthread_mutex_destroy(mutex)?; this.write_int(0, dest)?; } "pthread_rwlock_rdlock" => { - let [rwlock] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [rwlock] = this.check_shim(abi, Conv::C , link_name, args)?; this.pthread_rwlock_rdlock(rwlock, dest)?; } "pthread_rwlock_tryrdlock" => { - let [rwlock] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [rwlock] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.pthread_rwlock_tryrdlock(rwlock)?; this.write_scalar(result, dest)?; } "pthread_rwlock_wrlock" => { - let [rwlock] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [rwlock] = this.check_shim(abi, Conv::C , link_name, args)?; this.pthread_rwlock_wrlock(rwlock, dest)?; } "pthread_rwlock_trywrlock" => { - let [rwlock] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [rwlock] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.pthread_rwlock_trywrlock(rwlock)?; this.write_scalar(result, dest)?; } "pthread_rwlock_unlock" => { - let [rwlock] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [rwlock] = this.check_shim(abi, Conv::C , link_name, args)?; this.pthread_rwlock_unlock(rwlock)?; this.write_null(dest)?; } "pthread_rwlock_destroy" => { - let [rwlock] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [rwlock] = this.check_shim(abi, Conv::C , link_name, args)?; this.pthread_rwlock_destroy(rwlock)?; this.write_null(dest)?; } "pthread_condattr_init" => { - let [attr] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [attr] = this.check_shim(abi, Conv::C , link_name, args)?; this.pthread_condattr_init(attr)?; this.write_null(dest)?; } "pthread_condattr_setclock" => { let [attr, clock_id] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; let result = this.pthread_condattr_setclock(attr, clock_id)?; this.write_scalar(result, dest)?; } "pthread_condattr_getclock" => { let [attr, clock_id] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; this.pthread_condattr_getclock(attr, clock_id)?; this.write_null(dest)?; } "pthread_condattr_destroy" => { - let [attr] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [attr] = this.check_shim(abi, Conv::C , link_name, args)?; this.pthread_condattr_destroy(attr)?; this.write_null(dest)?; } "pthread_cond_init" => { - let [cond, attr] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [cond, attr] = this.check_shim(abi, Conv::C , link_name, args)?; this.pthread_cond_init(cond, attr)?; this.write_null(dest)?; } "pthread_cond_signal" => { - let [cond] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [cond] = this.check_shim(abi, Conv::C , link_name, args)?; this.pthread_cond_signal(cond)?; this.write_null(dest)?; } "pthread_cond_broadcast" => { - let [cond] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [cond] = this.check_shim(abi, Conv::C , link_name, args)?; this.pthread_cond_broadcast(cond)?; this.write_null(dest)?; } "pthread_cond_wait" => { - let [cond, mutex] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [cond, mutex] = this.check_shim(abi, Conv::C , link_name, args)?; this.pthread_cond_wait(cond, mutex, dest)?; } "pthread_cond_timedwait" => { - let [cond, mutex, abstime] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [cond, mutex, abstime] = this.check_shim(abi, Conv::C , link_name, args)?; this.pthread_cond_timedwait(cond, mutex, abstime, dest)?; } "pthread_cond_destroy" => { - let [cond] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [cond] = this.check_shim(abi, Conv::C , link_name, args)?; this.pthread_cond_destroy(cond)?; this.write_null(dest)?; } // Threading "pthread_create" => { - let [thread, attr, start, arg] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [thread, attr, start, arg] = this.check_shim(abi, Conv::C , link_name, args)?; this.pthread_create(thread, attr, start, arg)?; this.write_null(dest)?; } "pthread_join" => { - let [thread, retval] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [thread, retval] = this.check_shim(abi, Conv::C , link_name, args)?; let res = this.pthread_join(thread, retval)?; this.write_scalar(res, dest)?; } "pthread_detach" => { - let [thread] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [thread] = this.check_shim(abi, Conv::C , link_name, args)?; let res = this.pthread_detach(thread)?; this.write_scalar(res, dest)?; } "pthread_self" => { - let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, Conv::C , link_name, args)?; let res = this.pthread_self()?; this.write_scalar(res, dest)?; } "sched_yield" => { - let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, Conv::C , link_name, args)?; this.sched_yield()?; this.write_null(dest)?; } "nanosleep" => { - let [req, rem] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [req, rem] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.nanosleep(req, rem)?; this.write_scalar(result, dest)?; } @@ -672,7 +672,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } let [pid, cpusetsize, mask] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; let pid = this.read_scalar(pid)?.to_u32()?; let cpusetsize = this.read_target_usize(cpusetsize)?; let mask = this.read_pointer(mask)?; @@ -712,7 +712,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } let [pid, cpusetsize, mask] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; let pid = this.read_scalar(pid)?.to_u32()?; let cpusetsize = this.read_target_usize(cpusetsize)?; let mask = this.read_pointer(mask)?; @@ -748,12 +748,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Miscellaneous "isatty" => { - let [fd] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [fd] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.isatty(fd)?; this.write_scalar(result, dest)?; } "pthread_atfork" => { - let [prepare, parent, child] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [prepare, parent, child] = this.check_shim(abi, Conv::C , link_name, args)?; this.read_pointer(prepare)?; this.read_pointer(parent)?; this.read_pointer(child)?; @@ -771,7 +771,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } let [buf, bufsize] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; let buf = this.read_pointer(buf)?; let bufsize = this.read_target_usize(bufsize)?; @@ -790,7 +790,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "strerror_r" => { let [errnum, buf, buflen] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let result = this.strerror_r(errnum, buf, buflen)?; this.write_scalar(result, dest)?; } @@ -805,7 +805,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ); } let [ptr, len, flags] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; let ptr = this.read_pointer(ptr)?; let len = this.read_target_usize(len)?; let _flags = this.read_scalar(flags)?.to_i32()?; @@ -822,7 +822,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.tcx.sess.target.os ); } - let [ptr, len] = this.check_shim(abi, ExternAbi::C { unwind: false}, link_name, args)?; + let [ptr, len] = this.check_shim(abi, Conv::C , link_name, args)?; let ptr = this.read_pointer(ptr)?; let len = this.read_target_usize(len)?; this.gen_random(ptr, len)?; @@ -848,12 +848,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ); } // This function looks and behaves excatly like miri_start_unwind. - let [payload] = this.check_shim(abi, ExternAbi::C { unwind: true }, link_name, args)?; + let [payload] = this.check_shim(abi, Conv::C, link_name, args)?; this.handle_miri_start_unwind(payload)?; return interp_ok(EmulateItemResult::NeedsUnwind); } "getuid" => { - let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, Conv::C , link_name, args)?; // For now, just pretend we always have this fixed UID. this.write_int(UID, dest)?; } @@ -862,7 +862,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // These shims are enabled only when the caller is in the standard library. "pthread_attr_getguardsize" if this.frame_in_std() => { - let [_attr, guard_size] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [_attr, guard_size] = this.check_shim(abi, Conv::C , link_name, args)?; let guard_size = this.deref_pointer(guard_size)?; let guard_size_layout = this.libc_ty_layout("size_t"); this.write_scalar(Scalar::from_uint(this.machine.page_size, guard_size_layout.size), &guard_size)?; @@ -874,12 +874,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { | "pthread_attr_init" | "pthread_attr_destroy" if this.frame_in_std() => { - let [_] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [_] = this.check_shim(abi, Conv::C , link_name, args)?; this.write_null(dest)?; } | "pthread_attr_setstacksize" if this.frame_in_std() => { - let [_, _] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [_, _] = this.check_shim(abi, Conv::C , link_name, args)?; this.write_null(dest)?; } @@ -888,7 +888,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // We don't support "pthread_attr_setstack", so we just pretend all stacks have the same values here. // Hence we can mostly ignore the input `attr_place`. let [attr_place, addr_place, size_place] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; let _attr_place = this.deref_pointer_as(attr_place, this.libc_ty_layout("pthread_attr_t"))?; let addr_place = this.deref_pointer(addr_place)?; let size_place = this.deref_pointer(size_place)?; @@ -909,13 +909,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { | "signal" | "sigaltstack" if this.frame_in_std() => { - let [_, _] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [_, _] = this.check_shim(abi, Conv::C , link_name, args)?; this.write_null(dest)?; } | "sigaction" | "mprotect" if this.frame_in_std() => { - let [_, _, _] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [_, _, _] = this.check_shim(abi, Conv::C , link_name, args)?; this.write_null(dest)?; } @@ -923,7 +923,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { if this.frame_in_std() => { // getpwuid_r is the standard name, __posix_getpwuid_r is used on solarish let [uid, pwd, buf, buflen, result] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; this.check_no_isolation("`getpwuid_r`")?; let uid = this.read_scalar(uid)?.to_u32()?; diff --git a/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs b/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs index 0c9bc005ece..5381234e28c 100644 --- a/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs @@ -1,5 +1,6 @@ -use rustc_abi::ExternAbi; +use rustc_middle::ty::Ty; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; use crate::shims::unix::*; use crate::*; @@ -13,7 +14,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_foreign_item_inner( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -21,8 +22,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { match link_name.as_str() { // Threading "pthread_set_name_np" => { - let [thread, name] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [thread, name] = this.check_shim(abi, Conv::C, link_name, args)?; let max_len = usize::MAX; // FreeBSD does not seem to have a limit. // FreeBSD's pthread_set_name_np does not return anything. this.pthread_setname_np( @@ -33,8 +33,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { )?; } "pthread_get_name_np" => { - let [thread, name, len] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [thread, name, len] = this.check_shim(abi, Conv::C, link_name, args)?; // FreeBSD's pthread_get_name_np does not return anything // and uses strlcpy, which truncates the resulting value, // but always adds a null terminator (except for zero-sized buffers). @@ -51,33 +50,29 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // For those, we both intercept `func` and `call@FBSD_1.0` symbols cases // since freebsd 12 the former form can be expected. "stat" | "stat@FBSD_1.0" => { - let [path, buf] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [path, buf] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.macos_fbsd_solaris_stat(path, buf)?; this.write_scalar(result, dest)?; } "lstat" | "lstat@FBSD_1.0" => { - let [path, buf] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [path, buf] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.macos_fbsd_solaris_lstat(path, buf)?; this.write_scalar(result, dest)?; } "fstat" | "fstat@FBSD_1.0" => { - let [fd, buf] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [fd, buf] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.macos_fbsd_solaris_fstat(fd, buf)?; this.write_scalar(result, dest)?; } "readdir_r" | "readdir_r@FBSD_1.0" => { - let [dirp, entry, result] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [dirp, entry, result] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.macos_fbsd_readdir_r(dirp, entry, result)?; this.write_scalar(result, dest)?; } // Miscellaneous "__error" => { - let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, Conv::C, link_name, args)?; let errno_place = this.last_error_place()?; this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?; } @@ -85,8 +80,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Incomplete shims that we "stub out" just to get pre-main initialization code to work. // These shims are enabled only when the caller is in the standard library. "pthread_attr_get_np" if this.frame_in_std() => { - let [_thread, _attr] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [_thread, _attr] = this.check_shim(abi, Conv::C, link_name, args)?; this.write_null(dest)?; } diff --git a/src/tools/miri/src/shims/unix/fs.rs b/src/tools/miri/src/shims/unix/fs.rs index b41a4d2246f..5682fb659e7 100644 --- a/src/tools/miri/src/shims/unix/fs.rs +++ b/src/tools/miri/src/shims/unix/fs.rs @@ -1048,10 +1048,16 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } } - fn linux_readdir64(&mut self, dirp_op: &OpTy<'tcx>) -> InterpResult<'tcx, Scalar> { + fn linux_solarish_readdir64( + &mut self, + dirent_type: &str, + dirp_op: &OpTy<'tcx>, + ) -> InterpResult<'tcx, Scalar> { let this = self.eval_context_mut(); - this.assert_target_os("linux", "readdir64"); + if !matches!(&*this.tcx.sess.target.os, "linux" | "solaris" | "illumos") { + panic!("`linux_solaris_readdir64` should not be called on {}", this.tcx.sess.target.os); + } let dirp = this.read_target_usize(dirp_op)?; @@ -1070,9 +1076,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { Some(Ok(dir_entry)) => { // Write the directory entry into a newly allocated buffer. // The name is written with write_bytes, while the rest of the - // dirent64 struct is written using write_int_fields. + // dirent64 (or dirent) struct is written using write_int_fields. // For reference: + // On Linux: // pub struct dirent64 { // pub d_ino: ino64_t, // pub d_off: off64_t, @@ -1080,19 +1087,29 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // pub d_type: c_uchar, // pub d_name: [c_char; 256], // } + // + // On Solaris: + // pub struct dirent { + // pub d_ino: ino64_t, + // pub d_off: off64_t, + // pub d_reclen: c_ushort, + // pub d_name: [c_char; 3], + // } let mut name = dir_entry.file_name(); // not a Path as there are no separators! name.push("\0"); // Add a NUL terminator let name_bytes = name.as_encoded_bytes(); let name_len = u64::try_from(name_bytes.len()).unwrap(); - let dirent64_layout = this.libc_ty_layout("dirent64"); - let d_name_offset = dirent64_layout.fields.offset(4 /* d_name */).bytes(); + let dirent_layout = this.libc_ty_layout(dirent_type); + let fields = &dirent_layout.fields; + let last_field = fields.count().strict_sub(1); + let d_name_offset = fields.offset(last_field).bytes(); let size = d_name_offset.strict_add(name_len); let entry = this.allocate_ptr( Size::from_bytes(size), - dirent64_layout.align.abi, + dirent_layout.align.abi, MiriMemoryKind::Runtime.into(), )?; let entry: Pointer = entry.into(); @@ -1105,17 +1122,17 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let ino = 0u64; let file_type = this.file_type_to_d_type(dir_entry.file_type())?; - this.write_int_fields_named( - &[ - ("d_ino", ino.into()), - ("d_off", 0), - ("d_reclen", size.into()), - ("d_type", file_type.into()), - ], - &this.ptr_to_mplace(entry, dirent64_layout), + &[("d_ino", ino.into()), ("d_off", 0), ("d_reclen", size.into())], + &this.ptr_to_mplace(entry, dirent_layout), )?; + if let Some(d_type) = this + .try_project_field_named(&this.ptr_to_mplace(entry, dirent_layout), "d_type")? + { + this.write_int(file_type, &d_type)?; + } + let name_ptr = entry.wrapping_offset(Size::from_bytes(d_name_offset), this); this.write_bytes_ptr(name_ptr, name_bytes.iter().copied())?; diff --git a/src/tools/miri/src/shims/unix/linux/foreign_items.rs b/src/tools/miri/src/shims/unix/linux/foreign_items.rs index bc3619090c0..10af245dcc0 100644 --- a/src/tools/miri/src/shims/unix/linux/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/linux/foreign_items.rs @@ -1,5 +1,6 @@ -use rustc_abi::ExternAbi; +use rustc_middle::ty::Ty; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; use self::shims::unix::linux::mem::EvalContextExt as _; use self::shims::unix::linux_like::epoll::EvalContextExt as _; @@ -24,7 +25,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_foreign_item_inner( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -35,53 +36,47 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { match link_name.as_str() { // File related shims "readdir64" => { - let [dirp] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; - let result = this.linux_readdir64(dirp)?; + let [dirp] = this.check_shim(abi, Conv::C, link_name, args)?; + let result = this.linux_solarish_readdir64("dirent64", dirp)?; this.write_scalar(result, dest)?; } "sync_file_range" => { - let [fd, offset, nbytes, flags] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [fd, offset, nbytes, flags] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.sync_file_range(fd, offset, nbytes, flags)?; this.write_scalar(result, dest)?; } "statx" => { let [dirfd, pathname, flags, mask, statxbuf] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let result = this.linux_statx(dirfd, pathname, flags, mask, statxbuf)?; this.write_scalar(result, dest)?; } // epoll, eventfd "epoll_create1" => { - let [flag] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [flag] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.epoll_create1(flag)?; this.write_scalar(result, dest)?; } "epoll_ctl" => { - let [epfd, op, fd, event] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [epfd, op, fd, event] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.epoll_ctl(epfd, op, fd, event)?; this.write_scalar(result, dest)?; } "epoll_wait" => { let [epfd, events, maxevents, timeout] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; this.epoll_wait(epfd, events, maxevents, timeout, dest)?; } "eventfd" => { - let [val, flag] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [val, flag] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.eventfd(val, flag)?; this.write_scalar(result, dest)?; } // Threading "pthread_setname_np" => { - let [thread, name] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [thread, name] = this.check_shim(abi, Conv::C, link_name, args)?; let res = match this.pthread_setname_np( this.read_scalar(thread)?, this.read_scalar(name)?, @@ -96,8 +91,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(res, dest)?; } "pthread_getname_np" => { - let [thread, name, len] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [thread, name, len] = this.check_shim(abi, Conv::C, link_name, args)?; // The function's behavior isn't portable between platforms. // In case of glibc, the length of the output buffer must // be not shorter than TASK_COMM_LEN. @@ -120,7 +114,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(res, dest)?; } "gettid" => { - let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.linux_gettid()?; this.write_scalar(result, dest)?; } @@ -133,35 +127,34 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Miscellaneous "mmap64" => { let [addr, length, prot, flags, fd, offset] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let offset = this.read_scalar(offset)?.to_i64()?; let ptr = this.mmap(addr, length, prot, flags, fd, offset.into())?; this.write_scalar(ptr, dest)?; } "mremap" => { let [old_address, old_size, new_size, flags] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let ptr = this.mremap(old_address, old_size, new_size, flags)?; this.write_scalar(ptr, dest)?; } "__xpg_strerror_r" => { - let [errnum, buf, buflen] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [errnum, buf, buflen] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.strerror_r(errnum, buf, buflen)?; this.write_scalar(result, dest)?; } "__errno_location" => { - let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, Conv::C, link_name, args)?; let errno_place = this.last_error_place()?; this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?; } "__libc_current_sigrtmin" => { - let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, Conv::C, link_name, args)?; this.write_int(SIGRTMIN, dest)?; } "__libc_current_sigrtmax" => { - let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, Conv::C, link_name, args)?; this.write_int(SIGRTMAX, dest)?; } @@ -169,8 +162,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Incomplete shims that we "stub out" just to get pre-main initialization code to work. // These shims are enabled only when the caller is in the standard library. "pthread_getattr_np" if this.frame_in_std() => { - let [_thread, _attr] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [_thread, _attr] = this.check_shim(abi, Conv::C, link_name, args)?; this.write_null(dest)?; } diff --git a/src/tools/miri/src/shims/unix/linux_like/syscall.rs b/src/tools/miri/src/shims/unix/linux_like/syscall.rs index e9a32a26326..5fb262e176f 100644 --- a/src/tools/miri/src/shims/unix/linux_like/syscall.rs +++ b/src/tools/miri/src/shims/unix/linux_like/syscall.rs @@ -1,5 +1,6 @@ -use rustc_abi::ExternAbi; +use rustc_middle::ty::Ty; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; use crate::helpers::check_min_arg_count; use crate::shims::unix::linux_like::eventfd::EvalContextExt as _; @@ -9,13 +10,13 @@ use crate::*; pub fn syscall<'tcx>( ecx: &mut MiriInterpCx<'tcx>, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx> { // We do not use `check_shim` here because `syscall` is variadic. The argument // count is checked bellow. - ecx.check_abi_and_shim_symbol_clash(abi, ExternAbi::C { unwind: false }, link_name)?; + ecx.check_abi_and_shim_symbol_clash(abi, Conv::C, link_name)?; // The syscall variadic function is legal to call with more arguments than needed, // extra arguments are simply ignored. The important check is that when we use an // argument, we have to also check all arguments *before* it to ensure that they diff --git a/src/tools/miri/src/shims/unix/macos/foreign_items.rs b/src/tools/miri/src/shims/unix/macos/foreign_items.rs index 103bea08620..aa291639a6d 100644 --- a/src/tools/miri/src/shims/unix/macos/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/macos/foreign_items.rs @@ -1,5 +1,6 @@ -use rustc_abi::ExternAbi; +use rustc_middle::ty::Ty; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; use super::sync::EvalContextExt as _; use crate::shims::unix::*; @@ -14,7 +15,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_foreign_item_inner( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -25,66 +26,58 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { match link_name.as_str() { // errno "__error" => { - let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, Conv::C, link_name, args)?; let errno_place = this.last_error_place()?; this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?; } // File related shims "close$NOCANCEL" => { - let [result] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [result] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.close(result)?; this.write_scalar(result, dest)?; } "stat" | "stat64" | "stat$INODE64" => { - let [path, buf] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [path, buf] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.macos_fbsd_solaris_stat(path, buf)?; this.write_scalar(result, dest)?; } "lstat" | "lstat64" | "lstat$INODE64" => { - let [path, buf] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [path, buf] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.macos_fbsd_solaris_lstat(path, buf)?; this.write_scalar(result, dest)?; } "fstat" | "fstat64" | "fstat$INODE64" => { - let [fd, buf] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [fd, buf] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.macos_fbsd_solaris_fstat(fd, buf)?; this.write_scalar(result, dest)?; } "opendir$INODE64" => { - let [name] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [name] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.opendir(name)?; this.write_scalar(result, dest)?; } "readdir_r" | "readdir_r$INODE64" => { - let [dirp, entry, result] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [dirp, entry, result] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.macos_fbsd_readdir_r(dirp, entry, result)?; this.write_scalar(result, dest)?; } "realpath$DARWIN_EXTSN" => { - let [path, resolved_path] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [path, resolved_path] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.realpath(path, resolved_path)?; this.write_scalar(result, dest)?; } // Environment related shims "_NSGetEnviron" => { - let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, Conv::C, link_name, args)?; let environ = this.machine.env_vars.unix().environ(); this.write_pointer(environ, dest)?; } // Random data generation "CCRandomGenerateBytes" => { - let [bytes, count] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [bytes, count] = this.check_shim(abi, Conv::C, link_name, args)?; let bytes = this.read_pointer(bytes)?; let count = this.read_target_usize(count)?; let success = this.eval_libc_i32("kCCSuccess"); @@ -94,30 +87,28 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Time related shims "mach_absolute_time" => { - let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.mach_absolute_time()?; this.write_scalar(result, dest)?; } "mach_timebase_info" => { - let [info] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [info] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.mach_timebase_info(info)?; this.write_scalar(result, dest)?; } // Access to command-line arguments "_NSGetArgc" => { - let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, Conv::C, link_name, args)?; this.write_pointer(this.machine.argc.expect("machine must be initialized"), dest)?; } "_NSGetArgv" => { - let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, Conv::C, link_name, args)?; this.write_pointer(this.machine.argv.expect("machine must be initialized"), dest)?; } "_NSGetExecutablePath" => { - let [buf, bufsize] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [buf, bufsize] = this.check_shim(abi, Conv::C, link_name, args)?; this.check_no_isolation("`_NSGetExecutablePath`")?; let buf_ptr = this.read_pointer(buf)?; @@ -142,8 +133,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Thread-local storage "_tlv_atexit" => { - let [dtor, data] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [dtor, data] = this.check_shim(abi, Conv::C, link_name, args)?; let dtor = this.read_pointer(dtor)?; let dtor = this.get_ptr_fn(dtor)?.as_instance()?; let data = this.read_scalar(data)?; @@ -153,15 +143,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Querying system information "pthread_get_stackaddr_np" => { - let [thread] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [thread] = this.check_shim(abi, Conv::C, link_name, args)?; this.read_target_usize(thread)?; let stack_addr = Scalar::from_uint(this.machine.stack_addr, this.pointer_size()); this.write_scalar(stack_addr, dest)?; } "pthread_get_stacksize_np" => { - let [thread] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [thread] = this.check_shim(abi, Conv::C, link_name, args)?; this.read_target_usize(thread)?; let stack_size = Scalar::from_uint(this.machine.stack_size, this.pointer_size()); this.write_scalar(stack_size, dest)?; @@ -169,8 +157,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Threading "pthread_setname_np" => { - let [name] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [name] = this.check_shim(abi, Conv::C, link_name, args)?; // The real implementation has logic in two places: // * in userland at https://github.com/apple-oss-distributions/libpthread/blob/c032e0b076700a0a47db75528a282b8d3a06531a/src/pthread.c#L1178-L1200, @@ -197,8 +184,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(res, dest)?; } "pthread_getname_np" => { - let [thread, name, len] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [thread, name, len] = this.check_shim(abi, Conv::C, link_name, args)?; // The function's behavior isn't portable between platforms. // In case of macOS, a truncated name (due to a too small buffer) @@ -223,28 +209,23 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "os_unfair_lock_lock" => { - let [lock_op] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [lock_op] = this.check_shim(abi, Conv::C, link_name, args)?; this.os_unfair_lock_lock(lock_op)?; } "os_unfair_lock_trylock" => { - let [lock_op] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [lock_op] = this.check_shim(abi, Conv::C, link_name, args)?; this.os_unfair_lock_trylock(lock_op, dest)?; } "os_unfair_lock_unlock" => { - let [lock_op] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [lock_op] = this.check_shim(abi, Conv::C, link_name, args)?; this.os_unfair_lock_unlock(lock_op)?; } "os_unfair_lock_assert_owner" => { - let [lock_op] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [lock_op] = this.check_shim(abi, Conv::C, link_name, args)?; this.os_unfair_lock_assert_owner(lock_op)?; } "os_unfair_lock_assert_not_owner" => { - let [lock_op] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [lock_op] = this.check_shim(abi, Conv::C, link_name, args)?; this.os_unfair_lock_assert_not_owner(lock_op)?; } diff --git a/src/tools/miri/src/shims/unix/solarish/foreign_items.rs b/src/tools/miri/src/shims/unix/solarish/foreign_items.rs index e4529170368..c99e8ae7c6e 100644 --- a/src/tools/miri/src/shims/unix/solarish/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/solarish/foreign_items.rs @@ -1,5 +1,6 @@ -use rustc_abi::ExternAbi; +use rustc_middle::ty::Ty; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; use crate::shims::unix::foreign_items::EvalContextExt as _; use crate::shims::unix::*; @@ -14,7 +15,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_foreign_item_inner( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -22,8 +23,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { match link_name.as_str() { // Threading "pthread_setname_np" => { - let [thread, name] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [thread, name] = this.check_shim(abi, Conv::C, link_name, args)?; // THREAD_NAME_MAX allows a thread name of 31+1 length // https://github.com/illumos/illumos-gate/blob/7671517e13b8123748eda4ef1ee165c6d9dba7fe/usr/src/uts/common/sys/thread.h#L613 let max_len = 32; @@ -41,8 +41,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(res, dest)?; } "pthread_getname_np" => { - let [thread, name, len] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [thread, name, len] = this.check_shim(abi, Conv::C, link_name, args)?; // See https://illumos.org/man/3C/pthread_getname_np for the error codes. let res = match this.pthread_getname_np( this.read_scalar(thread)?, @@ -59,34 +58,35 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // File related shims "stat" | "stat64" => { - let [path, buf] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [path, buf] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.macos_fbsd_solaris_stat(path, buf)?; this.write_scalar(result, dest)?; } "lstat" | "lstat64" => { - let [path, buf] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [path, buf] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.macos_fbsd_solaris_lstat(path, buf)?; this.write_scalar(result, dest)?; } "fstat" | "fstat64" => { - let [fd, buf] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [fd, buf] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.macos_fbsd_solaris_fstat(fd, buf)?; this.write_scalar(result, dest)?; } + "readdir" => { + let [dirp] = this.check_shim(abi, Conv::C, link_name, args)?; + let result = this.linux_solarish_readdir64("dirent", dirp)?; + this.write_scalar(result, dest)?; + } // Miscellaneous "___errno" => { - let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, Conv::C, link_name, args)?; let errno_place = this.last_error_place()?; this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?; } "stack_getbounds" => { - let [stack] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [stack] = this.check_shim(abi, Conv::C, link_name, args)?; let stack = this.deref_pointer_as(stack, this.libc_ty_layout("stack_t"))?; this.write_int_fields_named( @@ -104,8 +104,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "pset_info" => { - let [pset, tpe, cpus, list] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [pset, tpe, cpus, list] = this.check_shim(abi, Conv::C, link_name, args)?; // We do not need to handle the current process cpu mask, available_parallelism // implementation pass null anyway. We only care for the number of // cpus. @@ -134,8 +133,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "__sysconf_xpg7" => { - let [val] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [val] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.sysconf(val)?; this.write_scalar(result, dest)?; } diff --git a/src/tools/miri/src/shims/unix/unnamed_socket.rs b/src/tools/miri/src/shims/unix/unnamed_socket.rs index 40a76ea7439..86ebe95762a 100644 --- a/src/tools/miri/src/shims/unix/unnamed_socket.rs +++ b/src/tools/miri/src/shims/unix/unnamed_socket.rs @@ -36,6 +36,12 @@ struct AnonSocket { /// This flag is set to `true` if the peer's `readbuf` is non-empty at the time /// of closure. peer_lost_data: Cell<bool>, + /// A list of thread ids blocked because the buffer was empty. + /// Once another thread writes some bytes, these threads will be unblocked. + blocked_read_tid: RefCell<Vec<ThreadId>>, + /// A list of thread ids blocked because the buffer was full. + /// Once another thread reads some bytes, these threads will be unblocked. + blocked_write_tid: RefCell<Vec<ThreadId>>, is_nonblock: bool, } @@ -83,7 +89,7 @@ impl FileDescription for AnonSocket { fn read<'tcx>( &self, - _self_ref: &FileDescriptionRef, + self_ref: &FileDescriptionRef, _communicate_allowed: bool, ptr: Pointer, len: usize, @@ -100,33 +106,21 @@ impl FileDescription for AnonSocket { // corresponding ErrorKind variant. throw_unsup_format!("reading from the write end of a pipe"); }; - if readbuf.borrow().buf.is_empty() { - if self.peer_fd().upgrade().is_none() { - // Socketpair with no peer and empty buffer. - // 0 bytes successfully read indicates end-of-file. - return ecx.return_read_success(ptr, &[], 0, dest); - } else { - if self.is_nonblock { - // Non-blocking socketpair with writer and empty buffer. - // https://linux.die.net/man/2/read - // EAGAIN or EWOULDBLOCK can be returned for socket, - // POSIX.1-2001 allows either error to be returned for this case. - // Since there is no ErrorKind for EAGAIN, WouldBlock is used. - return ecx.set_last_error_and_return(ErrorKind::WouldBlock, dest); - } else { - // Blocking socketpair with writer and empty buffer. - // FIXME: blocking is currently not supported - throw_unsup_format!("socketpair/pipe/pipe2 read: blocking isn't supported yet"); - } - } + + if readbuf.borrow().buf.is_empty() && self.is_nonblock { + // Non-blocking socketpair with writer and empty buffer. + // https://linux.die.net/man/2/read + // EAGAIN or EWOULDBLOCK can be returned for socket, + // POSIX.1-2001 allows either error to be returned for this case. + // Since there is no ErrorKind for EAGAIN, WouldBlock is used. + return ecx.set_last_error_and_return(ErrorKind::WouldBlock, dest); } - // TODO: We might need to decide what to do if peer_fd is closed when read is blocked. - anonsocket_read(self, self.peer_fd().upgrade(), len, ptr, dest, ecx) + anonsocket_read(self_ref.downgrade(), len, ptr, dest.clone(), ecx) } fn write<'tcx>( &self, - _self_ref: &FileDescriptionRef, + self_ref: &FileDescriptionRef, _communicate_allowed: bool, ptr: Pointer, len: usize, @@ -153,16 +147,11 @@ impl FileDescription for AnonSocket { }; let available_space = MAX_SOCKETPAIR_BUFFER_CAPACITY.strict_sub(writebuf.borrow().buf.len()); - if available_space == 0 { - if self.is_nonblock { - // Non-blocking socketpair with a full buffer. - return ecx.set_last_error_and_return(ErrorKind::WouldBlock, dest); - } else { - // Blocking socketpair with a full buffer. - throw_unsup_format!("socketpair/pipe/pipe2 write: blocking isn't supported yet"); - } + if available_space == 0 && self.is_nonblock { + // Non-blocking socketpair with a full buffer. + return ecx.set_last_error_and_return(ErrorKind::WouldBlock, dest); } - anonsocket_write(available_space, &peer_fd, ptr, len, dest, ecx) + anonsocket_write(self_ref.downgrade(), ptr, len, dest.clone(), ecx) } fn as_unix(&self) -> &dyn UnixFileDescription { @@ -172,81 +161,161 @@ impl FileDescription for AnonSocket { /// Write to AnonSocket based on the space available and return the written byte size. fn anonsocket_write<'tcx>( - available_space: usize, - peer_fd: &FileDescriptionRef, + weak_self_ref: WeakFileDescriptionRef, ptr: Pointer, len: usize, - dest: &MPlaceTy<'tcx>, + dest: MPlaceTy<'tcx>, ecx: &mut MiriInterpCx<'tcx>, ) -> InterpResult<'tcx> { + let Some(self_ref) = weak_self_ref.upgrade() else { + // FIXME: We should raise a deadlock error if the self_ref upgrade failed. + throw_unsup_format!("This will be a deadlock error in future") + }; + let self_anonsocket = self_ref.downcast::<AnonSocket>().unwrap(); + let Some(peer_fd) = self_anonsocket.peer_fd().upgrade() else { + // If the upgrade from Weak to Rc fails, it indicates that all read ends have been + // closed. + return ecx.set_last_error_and_return(ErrorKind::BrokenPipe, &dest); + }; let Some(writebuf) = &peer_fd.downcast::<AnonSocket>().unwrap().readbuf else { // FIXME: This should return EBADF, but there's no nice way to do that as there's no // corresponding ErrorKind variant. throw_unsup_format!("writing to the reading end of a pipe") }; - let mut writebuf = writebuf.borrow_mut(); - // Remember this clock so `read` can synchronize with us. - ecx.release_clock(|clock| { - writebuf.clock.join(clock); - }); - // Do full write / partial write based on the space available. - let actual_write_size = len.min(available_space); - let bytes = ecx.read_bytes_ptr_strip_provenance(ptr, Size::from_bytes(len))?; - writebuf.buf.extend(&bytes[..actual_write_size]); + let available_space = MAX_SOCKETPAIR_BUFFER_CAPACITY.strict_sub(writebuf.borrow().buf.len()); + + if available_space == 0 { + // Blocking socketpair with a full buffer. + let dest = dest.clone(); + self_anonsocket.blocked_write_tid.borrow_mut().push(ecx.active_thread()); + ecx.block_thread( + BlockReason::UnnamedSocket, + None, + callback!( + @capture<'tcx> { + weak_self_ref: WeakFileDescriptionRef, + ptr: Pointer, + len: usize, + dest: MPlaceTy<'tcx>, + } + @unblock = |this| { + anonsocket_write(weak_self_ref, ptr, len, dest, this) + } + ), + ); + } else { + let mut writebuf = writebuf.borrow_mut(); + // Remember this clock so `read` can synchronize with us. + ecx.release_clock(|clock| { + writebuf.clock.join(clock); + }); + // Do full write / partial write based on the space available. + let actual_write_size = len.min(available_space); + let bytes = ecx.read_bytes_ptr_strip_provenance(ptr, Size::from_bytes(len))?; + writebuf.buf.extend(&bytes[..actual_write_size]); - // Need to stop accessing peer_fd so that it can be notified. - drop(writebuf); + // Need to stop accessing peer_fd so that it can be notified. + drop(writebuf); - // Notification should be provided for peer fd as it became readable. - // The kernel does this even if the fd was already readable before, so we follow suit. - ecx.check_and_update_readiness(peer_fd)?; + // Notification should be provided for peer fd as it became readable. + // The kernel does this even if the fd was already readable before, so we follow suit. + ecx.check_and_update_readiness(&peer_fd)?; + let peer_anonsocket = peer_fd.downcast::<AnonSocket>().unwrap(); + // Unblock all threads that are currently blocked on peer_fd's read. + let waiting_threads = std::mem::take(&mut *peer_anonsocket.blocked_read_tid.borrow_mut()); + // FIXME: We can randomize the order of unblocking. + for thread_id in waiting_threads { + ecx.unblock_thread(thread_id, BlockReason::UnnamedSocket)?; + } - ecx.return_write_success(actual_write_size, dest) + return ecx.return_write_success(actual_write_size, &dest); + } + interp_ok(()) } /// Read from AnonSocket and return the number of bytes read. fn anonsocket_read<'tcx>( - anonsocket: &AnonSocket, - peer_fd: Option<FileDescriptionRef>, + weak_self_ref: WeakFileDescriptionRef, len: usize, ptr: Pointer, - dest: &MPlaceTy<'tcx>, + dest: MPlaceTy<'tcx>, ecx: &mut MiriInterpCx<'tcx>, ) -> InterpResult<'tcx> { - let mut bytes = vec![0; len]; + let Some(self_ref) = weak_self_ref.upgrade() else { + // FIXME: We should raise a deadlock error if the self_ref upgrade failed. + throw_unsup_format!("This will be a deadlock error in future") + }; + let self_anonsocket = self_ref.downcast::<AnonSocket>().unwrap(); - let Some(readbuf) = &anonsocket.readbuf else { + let Some(readbuf) = &self_anonsocket.readbuf else { // FIXME: This should return EBADF, but there's no nice way to do that as there's no // corresponding ErrorKind variant. throw_unsup_format!("reading from the write end of a pipe") }; - let mut readbuf = readbuf.borrow_mut(); - - // Synchronize with all previous writes to this buffer. - // FIXME: this over-synchronizes; a more precise approach would be to - // only sync with the writes whose data we will read. - ecx.acquire_clock(&readbuf.clock); - - // Do full read / partial read based on the space available. - // Conveniently, `read` exists on `VecDeque` and has exactly the desired behavior. - let actual_read_size = readbuf.buf.read(&mut bytes[..]).unwrap(); - - // Need to drop before others can access the readbuf again. - drop(readbuf); - - // A notification should be provided for the peer file description even when it can - // only write 1 byte. This implementation is not compliant with the actual Linux kernel - // implementation. For optimization reasons, the kernel will only mark the file description - // as "writable" when it can write more than a certain number of bytes. Since we - // don't know what that *certain number* is, we will provide a notification every time - // a read is successful. This might result in our epoll emulation providing more - // notifications than the real system. - if let Some(peer_fd) = peer_fd { - ecx.check_and_update_readiness(&peer_fd)?; - } - ecx.return_read_success(ptr, &bytes, actual_read_size, dest) + if readbuf.borrow_mut().buf.is_empty() { + if self_anonsocket.peer_fd().upgrade().is_none() { + // Socketpair with no peer and empty buffer. + // 0 bytes successfully read indicates end-of-file. + return ecx.return_read_success(ptr, &[], 0, &dest); + } else { + // Blocking socketpair with writer and empty buffer. + let weak_self_ref = weak_self_ref.clone(); + self_anonsocket.blocked_read_tid.borrow_mut().push(ecx.active_thread()); + ecx.block_thread( + BlockReason::UnnamedSocket, + None, + callback!( + @capture<'tcx> { + weak_self_ref: WeakFileDescriptionRef, + len: usize, + ptr: Pointer, + dest: MPlaceTy<'tcx>, + } + @unblock = |this| { + anonsocket_read(weak_self_ref, len, ptr, dest, this) + } + ), + ); + } + } else { + let mut bytes = vec![0; len]; + let mut readbuf = readbuf.borrow_mut(); + // Synchronize with all previous writes to this buffer. + // FIXME: this over-synchronizes; a more precise approach would be to + // only sync with the writes whose data we will read. + ecx.acquire_clock(&readbuf.clock); + + // Do full read / partial read based on the space available. + // Conveniently, `read` exists on `VecDeque` and has exactly the desired behavior. + let actual_read_size = readbuf.buf.read(&mut bytes[..]).unwrap(); + + // Need to drop before others can access the readbuf again. + drop(readbuf); + + // A notification should be provided for the peer file description even when it can + // only write 1 byte. This implementation is not compliant with the actual Linux kernel + // implementation. For optimization reasons, the kernel will only mark the file description + // as "writable" when it can write more than a certain number of bytes. Since we + // don't know what that *certain number* is, we will provide a notification every time + // a read is successful. This might result in our epoll emulation providing more + // notifications than the real system. + if let Some(peer_fd) = self_anonsocket.peer_fd().upgrade() { + ecx.check_and_update_readiness(&peer_fd)?; + let peer_anonsocket = peer_fd.downcast::<AnonSocket>().unwrap(); + // Unblock all threads that are currently blocked on peer_fd's write. + let waiting_threads = + std::mem::take(&mut *peer_anonsocket.blocked_write_tid.borrow_mut()); + // FIXME: We can randomize the order of unblocking. + for thread_id in waiting_threads { + ecx.unblock_thread(thread_id, BlockReason::UnnamedSocket)?; + } + }; + + return ecx.return_read_success(ptr, &bytes, actual_read_size, &dest); + } + interp_ok(()) } impl UnixFileDescription for AnonSocket { @@ -360,12 +429,16 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { readbuf: Some(RefCell::new(Buffer::new())), peer_fd: OnceCell::new(), peer_lost_data: Cell::new(false), + blocked_read_tid: RefCell::new(Vec::new()), + blocked_write_tid: RefCell::new(Vec::new()), is_nonblock: is_sock_nonblock, }); let fd1 = fds.new_ref(AnonSocket { readbuf: Some(RefCell::new(Buffer::new())), peer_fd: OnceCell::new(), peer_lost_data: Cell::new(false), + blocked_read_tid: RefCell::new(Vec::new()), + blocked_write_tid: RefCell::new(Vec::new()), is_nonblock: is_sock_nonblock, }); @@ -424,12 +497,16 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { readbuf: Some(RefCell::new(Buffer::new())), peer_fd: OnceCell::new(), peer_lost_data: Cell::new(false), + blocked_read_tid: RefCell::new(Vec::new()), + blocked_write_tid: RefCell::new(Vec::new()), is_nonblock, }); let fd1 = fds.new_ref(AnonSocket { readbuf: None, peer_fd: OnceCell::new(), peer_lost_data: Cell::new(false), + blocked_read_tid: RefCell::new(Vec::new()), + blocked_write_tid: RefCell::new(Vec::new()), is_nonblock, }); diff --git a/src/tools/miri/src/shims/wasi/foreign_items.rs b/src/tools/miri/src/shims/wasi/foreign_items.rs index 2c349203d46..90de62b9e57 100644 --- a/src/tools/miri/src/shims/wasi/foreign_items.rs +++ b/src/tools/miri/src/shims/wasi/foreign_items.rs @@ -1,5 +1,6 @@ -use rustc_abi::ExternAbi; +use rustc_middle::ty::Ty; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; use crate::shims::alloc::EvalContextExt as _; use crate::*; @@ -13,7 +14,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_foreign_item_inner( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -21,14 +22,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { match link_name.as_str() { // Allocation "posix_memalign" => { - let [memptr, align, size] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [memptr, align, size] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.posix_memalign(memptr, align, size)?; this.write_scalar(result, dest)?; } "aligned_alloc" => { - let [align, size] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [align, size] = this.check_shim(abi, Conv::C, link_name, args)?; let res = this.aligned_alloc(align, size)?; this.write_pointer(res, dest)?; } diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs index d6a180451d7..fe4d2158ff9 100644 --- a/src/tools/miri/src/shims/windows/foreign_items.rs +++ b/src/tools/miri/src/shims/windows/foreign_items.rs @@ -2,8 +2,10 @@ use std::ffi::OsStr; use std::path::{self, Path, PathBuf}; use std::{io, iter, str}; -use rustc_abi::{Align, ExternAbi, Size}; +use rustc_abi::{Align, Size}; +use rustc_middle::ty::Ty; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; use self::shims::windows::handle::{Handle, PseudoHandle}; use crate::shims::os_str::bytes_to_os_str; @@ -83,12 +85,18 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_foreign_item_inner( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { let this = self.eval_context_mut(); + // According to + // https://github.com/rust-lang/rust/blob/fb00adbdb69266f10df95a4527b767b0ad35ea48/compiler/rustc_target/src/spec/mod.rs#L2766-L2768, + // x86-32 Windows uses a different calling convention than other Windows targets + // for the "system" ABI. + let sys_conv = if this.tcx.sess.target.arch == "x86" { Conv::X86Stdcall } else { Conv::C }; + // See `fn emulate_foreign_item_inner` in `shims/foreign_items.rs` for the general pattern. // Windows API stubs. @@ -100,50 +108,42 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { match link_name.as_str() { // Environment related shims "GetEnvironmentVariableW" => { - let [name, buf, size] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [name, buf, size] = this.check_shim(abi, sys_conv, link_name, args)?; let result = this.GetEnvironmentVariableW(name, buf, size)?; this.write_scalar(result, dest)?; } "SetEnvironmentVariableW" => { - let [name, value] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [name, value] = this.check_shim(abi, sys_conv, link_name, args)?; let result = this.SetEnvironmentVariableW(name, value)?; this.write_scalar(result, dest)?; } "GetEnvironmentStringsW" => { - let [] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, sys_conv, link_name, args)?; let result = this.GetEnvironmentStringsW()?; this.write_pointer(result, dest)?; } "FreeEnvironmentStringsW" => { - let [env_block] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [env_block] = this.check_shim(abi, sys_conv, link_name, args)?; let result = this.FreeEnvironmentStringsW(env_block)?; this.write_scalar(result, dest)?; } "GetCurrentDirectoryW" => { - let [size, buf] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [size, buf] = this.check_shim(abi, sys_conv, link_name, args)?; let result = this.GetCurrentDirectoryW(size, buf)?; this.write_scalar(result, dest)?; } "SetCurrentDirectoryW" => { - let [path] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [path] = this.check_shim(abi, sys_conv, link_name, args)?; let result = this.SetCurrentDirectoryW(path)?; this.write_scalar(result, dest)?; } "GetUserProfileDirectoryW" => { - let [token, buf, size] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [token, buf, size] = this.check_shim(abi, sys_conv, link_name, args)?; let result = this.GetUserProfileDirectoryW(token, buf, size)?; this.write_scalar(result, dest)?; } "GetCurrentProcessId" => { - let [] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, sys_conv, link_name, args)?; let result = this.GetCurrentProcessId()?; this.write_scalar(result, dest)?; } @@ -166,7 +166,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { n, byte_offset, _key, - ] = this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + ] = this.check_shim(abi, sys_conv, link_name, args)?; let handle = this.read_target_isize(handle)?; let buf = this.read_pointer(buf)?; let n = this.read_scalar(n)?.to_u32()?; @@ -218,7 +218,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "GetFullPathNameW" => { let [filename, size, buffer, filepart] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; this.check_no_isolation("`GetFullPathNameW`")?; let filename = this.read_pointer(filename)?; @@ -249,8 +249,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Allocation "HeapAlloc" => { - let [handle, flags, size] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [handle, flags, size] = this.check_shim(abi, sys_conv, link_name, args)?; this.read_target_isize(handle)?; let flags = this.read_scalar(flags)?.to_u32()?; let size = this.read_target_usize(size)?; @@ -273,8 +272,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_pointer(ptr, dest)?; } "HeapFree" => { - let [handle, flags, ptr] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [handle, flags, ptr] = this.check_shim(abi, sys_conv, link_name, args)?; this.read_target_isize(handle)?; this.read_scalar(flags)?.to_u32()?; let ptr = this.read_pointer(ptr)?; @@ -287,7 +285,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "HeapReAlloc" => { let [handle, flags, old_ptr, size] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; this.read_target_isize(handle)?; this.read_scalar(flags)?.to_u32()?; let old_ptr = this.read_pointer(old_ptr)?; @@ -306,8 +304,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_pointer(new_ptr, dest)?; } "LocalFree" => { - let [ptr] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [ptr] = this.check_shim(abi, sys_conv, link_name, args)?; let ptr = this.read_pointer(ptr)?; // "If the hMem parameter is NULL, LocalFree ignores the parameter and returns NULL." // (https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-localfree) @@ -319,14 +316,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // errno "SetLastError" => { - let [error] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [error] = this.check_shim(abi, sys_conv, link_name, args)?; let error = this.read_scalar(error)?; this.set_last_error(error)?; } "GetLastError" => { - let [] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, sys_conv, link_name, args)?; let last_error = this.get_last_error()?; this.write_scalar(last_error, dest)?; } @@ -334,8 +329,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Querying system information "GetSystemInfo" => { // Also called from `page_size` crate. - let [system_info] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [system_info] = this.check_shim(abi, sys_conv, link_name, args)?; let system_info = this.deref_pointer_as(system_info, this.windows_ty_layout("SYSTEM_INFO"))?; // Initialize with `0`. @@ -358,22 +352,19 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // This just creates a key; Windows does not natively support TLS destructors. // Create key and return it. - let [] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, sys_conv, link_name, args)?; let key = this.machine.tls.create_tls_key(None, dest.layout.size)?; this.write_scalar(Scalar::from_uint(key, dest.layout.size), dest)?; } "TlsGetValue" => { - let [key] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [key] = this.check_shim(abi, sys_conv, link_name, args)?; let key = u128::from(this.read_scalar(key)?.to_u32()?); let active_thread = this.active_thread(); let ptr = this.machine.tls.load_tls(key, active_thread, this)?; this.write_scalar(ptr, dest)?; } "TlsSetValue" => { - let [key, new_ptr] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [key, new_ptr] = this.check_shim(abi, sys_conv, link_name, args)?; let key = u128::from(this.read_scalar(key)?.to_u32()?); let active_thread = this.active_thread(); let new_data = this.read_scalar(new_ptr)?; @@ -383,8 +374,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_int(1, dest)?; } "TlsFree" => { - let [key] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [key] = this.check_shim(abi, sys_conv, link_name, args)?; let key = u128::from(this.read_scalar(key)?.to_u32()?); this.machine.tls.delete_tls_key(key)?; @@ -394,8 +384,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Access to command-line arguments "GetCommandLineW" => { - let [] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, sys_conv, link_name, args)?; this.write_pointer( this.machine.cmd_line.expect("machine must be initialized"), dest, @@ -405,33 +394,29 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Time related shims "GetSystemTimeAsFileTime" | "GetSystemTimePreciseAsFileTime" => { #[allow(non_snake_case)] - let [LPFILETIME] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [LPFILETIME] = this.check_shim(abi, sys_conv, link_name, args)?; this.GetSystemTimeAsFileTime(link_name.as_str(), LPFILETIME)?; } "QueryPerformanceCounter" => { #[allow(non_snake_case)] - let [lpPerformanceCount] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [lpPerformanceCount] = this.check_shim(abi, sys_conv, link_name, args)?; let result = this.QueryPerformanceCounter(lpPerformanceCount)?; this.write_scalar(result, dest)?; } "QueryPerformanceFrequency" => { #[allow(non_snake_case)] - let [lpFrequency] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [lpFrequency] = this.check_shim(abi, sys_conv, link_name, args)?; let result = this.QueryPerformanceFrequency(lpFrequency)?; this.write_scalar(result, dest)?; } "Sleep" => { - let [timeout] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [timeout] = this.check_shim(abi, sys_conv, link_name, args)?; this.Sleep(timeout)?; } "CreateWaitableTimerExW" => { let [attributes, name, flags, access] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; this.read_pointer(attributes)?; this.read_pointer(name)?; this.read_scalar(flags)?.to_u32()?; @@ -445,30 +430,27 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Synchronization primitives "InitOnceBeginInitialize" => { let [ptr, flags, pending, context] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; this.InitOnceBeginInitialize(ptr, flags, pending, context, dest)?; } "InitOnceComplete" => { - let [ptr, flags, context] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [ptr, flags, context] = this.check_shim(abi, sys_conv, link_name, args)?; let result = this.InitOnceComplete(ptr, flags, context)?; this.write_scalar(result, dest)?; } "WaitOnAddress" => { let [ptr_op, compare_op, size_op, timeout_op] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; this.WaitOnAddress(ptr_op, compare_op, size_op, timeout_op, dest)?; } "WakeByAddressSingle" => { - let [ptr_op] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [ptr_op] = this.check_shim(abi, sys_conv, link_name, args)?; this.WakeByAddressSingle(ptr_op)?; } "WakeByAddressAll" => { - let [ptr_op] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [ptr_op] = this.check_shim(abi, sys_conv, link_name, args)?; this.WakeByAddressAll(ptr_op)?; } @@ -476,8 +458,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Dynamic symbol loading "GetProcAddress" => { #[allow(non_snake_case)] - let [hModule, lpProcName] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [hModule, lpProcName] = this.check_shim(abi, sys_conv, link_name, args)?; this.read_target_isize(hModule)?; let name = this.read_c_str(this.read_pointer(lpProcName)?)?; if let Ok(name) = str::from_utf8(name) @@ -493,7 +474,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Threading "CreateThread" => { let [security, stacksize, start, arg, flags, thread] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; let thread_id = this.CreateThread(security, stacksize, start, arg, flags, thread)?; @@ -501,15 +482,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(Handle::Thread(thread_id).to_scalar(this), dest)?; } "WaitForSingleObject" => { - let [handle, timeout] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [handle, timeout] = this.check_shim(abi, sys_conv, link_name, args)?; let ret = this.WaitForSingleObject(handle, timeout)?; this.write_scalar(ret, dest)?; } "GetCurrentThread" => { - let [] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, sys_conv, link_name, args)?; this.write_scalar( Handle::Pseudo(PseudoHandle::CurrentThread).to_scalar(this), @@ -517,8 +496,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { )?; } "SetThreadDescription" => { - let [handle, name] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [handle, name] = this.check_shim(abi, sys_conv, link_name, args)?; let handle = this.read_scalar(handle)?; let name = this.read_wide_str(this.read_pointer(name)?)?; @@ -542,8 +520,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(res, dest)?; } "GetThreadDescription" => { - let [handle, name_ptr] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [handle, name_ptr] = this.check_shim(abi, sys_conv, link_name, args)?; let handle = this.read_scalar(handle)?; let name_ptr = this.deref_pointer(name_ptr)?; // the pointer where we should store the ptr to the name @@ -574,16 +551,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Miscellaneous "ExitProcess" => { - let [code] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [code] = this.check_shim(abi, sys_conv, link_name, args)?; let code = this.read_scalar(code)?.to_u32()?; throw_machine_stop!(TerminationInfo::Exit { code: code.into(), leak_check: false }); } "SystemFunction036" => { // used by getrandom 0.1 // This is really 'RtlGenRandom'. - let [ptr, len] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [ptr, len] = this.check_shim(abi, sys_conv, link_name, args)?; let ptr = this.read_pointer(ptr)?; let len = this.read_scalar(len)?.to_u32()?; this.gen_random(ptr, len.into())?; @@ -591,8 +566,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "ProcessPrng" => { // used by `std` - let [ptr, len] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [ptr, len] = this.check_shim(abi, sys_conv, link_name, args)?; let ptr = this.read_pointer(ptr)?; let len = this.read_target_usize(len)?; this.gen_random(ptr, len)?; @@ -601,7 +575,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "BCryptGenRandom" => { // used by getrandom 0.2 let [algorithm, ptr, len, flags] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; let algorithm = this.read_scalar(algorithm)?; let algorithm = algorithm.to_target_usize(this)?; let ptr = this.read_pointer(ptr)?; @@ -635,8 +609,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "GetConsoleScreenBufferInfo" => { // `term` needs this, so we fake it. - let [console, buffer_info] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [console, buffer_info] = this.check_shim(abi, sys_conv, link_name, args)?; this.read_target_isize(console)?; // FIXME: this should use deref_pointer_as, but CONSOLE_SCREEN_BUFFER_INFO is not in std this.deref_pointer(buffer_info)?; @@ -645,8 +618,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_null(dest)?; } "GetStdHandle" => { - let [which] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [which] = this.check_shim(abi, sys_conv, link_name, args)?; let which = this.read_scalar(which)?.to_i32()?; // We just make this the identity function, so we know later in `NtWriteFile` which // one it is. This is very fake, but libtest needs it so we cannot make it a @@ -655,16 +627,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(Scalar::from_target_isize(which.into(), this), dest)?; } "CloseHandle" => { - let [handle] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [handle] = this.check_shim(abi, sys_conv, link_name, args)?; let ret = this.CloseHandle(handle)?; this.write_scalar(ret, dest)?; } "GetModuleFileNameW" => { - let [handle, filename, size] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [handle, filename, size] = this.check_shim(abi, sys_conv, link_name, args)?; this.check_no_isolation("`GetModuleFileNameW`")?; let handle = this.read_target_usize(handle)?; @@ -698,7 +668,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "FormatMessageW" => { let [flags, module, message_id, language_id, buffer, size, arguments] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; let flags = this.read_scalar(flags)?.to_u32()?; let _module = this.read_pointer(module)?; // seems to contain a module name @@ -733,29 +703,26 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Incomplete shims that we "stub out" just to get pre-main initialization code to work. // These shims are enabled only when the caller is in the standard library. "GetProcessHeap" if this.frame_in_std() => { - let [] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, sys_conv, link_name, args)?; // Just fake a HANDLE // It's fine to not use the Handle type here because its a stub this.write_int(1, dest)?; } "GetModuleHandleA" if this.frame_in_std() => { #[allow(non_snake_case)] - let [_lpModuleName] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [_lpModuleName] = this.check_shim(abi, sys_conv, link_name, args)?; // We need to return something non-null here to make `compat_fn!` work. this.write_int(1, dest)?; } "SetConsoleTextAttribute" if this.frame_in_std() => { #[allow(non_snake_case)] let [_hConsoleOutput, _wAttribute] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; // Pretend these does not exist / nothing happened, by returning zero. this.write_null(dest)?; } "GetConsoleMode" if this.frame_in_std() => { - let [console, mode] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [console, mode] = this.check_shim(abi, sys_conv, link_name, args)?; this.read_target_isize(console)?; this.deref_pointer(mode)?; // Indicate an error. @@ -763,29 +730,25 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "GetFileType" if this.frame_in_std() => { #[allow(non_snake_case)] - let [_hFile] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [_hFile] = this.check_shim(abi, sys_conv, link_name, args)?; // Return unknown file type. this.write_null(dest)?; } "AddVectoredExceptionHandler" if this.frame_in_std() => { #[allow(non_snake_case)] - let [_First, _Handler] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [_First, _Handler] = this.check_shim(abi, sys_conv, link_name, args)?; // Any non zero value works for the stdlib. This is just used for stack overflows anyway. this.write_int(1, dest)?; } "SetThreadStackGuarantee" if this.frame_in_std() => { #[allow(non_snake_case)] - let [_StackSizeInBytes] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [_StackSizeInBytes] = this.check_shim(abi, sys_conv, link_name, args)?; // Any non zero value works for the stdlib. This is just used for stack overflows anyway. this.write_int(1, dest)?; } // this is only callable from std because we know that std ignores the return value "SwitchToThread" if this.frame_in_std() => { - let [] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, sys_conv, link_name, args)?; this.yield_active_thread(); @@ -804,8 +767,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ); } // This function looks and behaves excatly like miri_start_unwind. - let [payload] = - this.check_shim(abi, ExternAbi::C { unwind: true }, link_name, args)?; + let [payload] = this.check_shim(abi, Conv::C, link_name, args)?; this.handle_miri_start_unwind(payload)?; return interp_ok(EmulateItemResult::NeedsUnwind); } diff --git a/src/tools/miri/src/shims/x86/aesni.rs b/src/tools/miri/src/shims/x86/aesni.rs index 4c6c1cefeb1..c6784db67fb 100644 --- a/src/tools/miri/src/shims/x86/aesni.rs +++ b/src/tools/miri/src/shims/x86/aesni.rs @@ -1,7 +1,7 @@ -use rustc_abi::ExternAbi; use rustc_middle::ty::Ty; use rustc_middle::ty::layout::LayoutOf as _; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; use crate::*; @@ -10,7 +10,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_aesni_intrinsic( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -26,9 +26,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // `state` with the corresponding 128-bit key of `key`. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesdec_si128 "aesdec" | "aesdec.256" | "aesdec.512" => { - let [state, key] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; - + let [state, key] = this.check_shim(abi, Conv::C, link_name, args)?; aes_round(this, state, key, dest, |state, key| { let key = aes::Block::from(key.to_le_bytes()); let mut state = aes::Block::from(state.to_le_bytes()); @@ -44,8 +42,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // `state` with the corresponding 128-bit key of `key`. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesdeclast_si128 "aesdeclast" | "aesdeclast.256" | "aesdeclast.512" => { - let [state, key] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [state, key] = this.check_shim(abi, Conv::C, link_name, args)?; aes_round(this, state, key, dest, |state, key| { let mut state = aes::Block::from(state.to_le_bytes()); @@ -69,9 +66,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // `state` with the corresponding 128-bit key of `key`. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesenc_si128 "aesenc" | "aesenc.256" | "aesenc.512" => { - let [state, key] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; - + let [state, key] = this.check_shim(abi, Conv::C, link_name, args)?; aes_round(this, state, key, dest, |state, key| { let key = aes::Block::from(key.to_le_bytes()); let mut state = aes::Block::from(state.to_le_bytes()); @@ -87,9 +82,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // `state` with the corresponding 128-bit key of `key`. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesenclast_si128 "aesenclast" | "aesenclast.256" | "aesenclast.512" => { - let [state, key] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; - + let [state, key] = this.check_shim(abi, Conv::C, link_name, args)?; aes_round(this, state, key, dest, |state, key| { let mut state = aes::Block::from(state.to_le_bytes()); // `aes::hazmat::cipher_round` does the following operations: @@ -109,8 +102,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Used to implement the _mm_aesimc_si128 function. // Performs the AES InvMixColumns operation on `op` "aesimc" => { - let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; - + let [op] = this.check_shim(abi, Conv::C, link_name, args)?; // Transmute to `u128` let op = op.transmute(this.machine.layouts.u128, this)?; let dest = dest.transmute(this.machine.layouts.u128, this)?; diff --git a/src/tools/miri/src/shims/x86/avx.rs b/src/tools/miri/src/shims/x86/avx.rs index 3971fa3b913..3aeb2b429da 100644 --- a/src/tools/miri/src/shims/x86/avx.rs +++ b/src/tools/miri/src/shims/x86/avx.rs @@ -1,9 +1,9 @@ -use rustc_abi::ExternAbi; use rustc_apfloat::ieee::{Double, Single}; use rustc_middle::mir; use rustc_middle::ty::Ty; use rustc_middle::ty::layout::LayoutOf as _; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; use super::{ FloatBinOp, FloatUnaryOp, bin_op_simd_float_all, conditional_dot_product, convert_float_to_int, @@ -17,7 +17,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_avx_intrinsic( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -33,8 +33,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // matches the IEEE min/max operations, while x86 has different // semantics. "min.ps.256" | "max.ps.256" => { - let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let which = match unprefixed_name { "min.ps.256" => FloatBinOp::Min, @@ -46,8 +45,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } // Used to implement _mm256_min_pd and _mm256_max_pd functions. "min.pd.256" | "max.pd.256" => { - let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let which = match unprefixed_name { "min.pd.256" => FloatBinOp::Min, @@ -60,23 +58,21 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Used to implement the _mm256_round_ps function. // Rounds the elements of `op` according to `rounding`. "round.ps.256" => { - let [op, rounding] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [op, rounding] = this.check_shim(abi, Conv::C, link_name, args)?; round_all::<rustc_apfloat::ieee::Single>(this, op, rounding, dest)?; } // Used to implement the _mm256_round_pd function. // Rounds the elements of `op` according to `rounding`. "round.pd.256" => { - let [op, rounding] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [op, rounding] = this.check_shim(abi, Conv::C, link_name, args)?; round_all::<rustc_apfloat::ieee::Double>(this, op, rounding, dest)?; } // Used to implement _mm256_{rcp,rsqrt}_ps functions. // Performs the operations on all components of `op`. "rcp.ps.256" | "rsqrt.ps.256" => { - let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [op] = this.check_shim(abi, Conv::C, link_name, args)?; let which = match unprefixed_name { "rcp.ps.256" => FloatUnaryOp::Rcp, @@ -88,8 +84,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } // Used to implement the _mm256_dp_ps function. "dp.ps.256" => { - let [left, right, imm] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right, imm] = this.check_shim(abi, Conv::C, link_name, args)?; conditional_dot_product(this, left, right, imm, dest)?; } @@ -97,8 +92,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Horizontally add/subtract adjacent floating point values // in `left` and `right`. "hadd.ps.256" | "hadd.pd.256" | "hsub.ps.256" | "hsub.pd.256" => { - let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let which = match unprefixed_name { "hadd.ps.256" | "hadd.pd.256" => mir::BinOp::Add, @@ -113,8 +107,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // and `right`. For each component, returns 0 if false or u32::MAX // if true. "cmp.ps.256" => { - let [left, right, imm] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right, imm] = this.check_shim(abi, Conv::C, link_name, args)?; let which = FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?; @@ -126,8 +119,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // and `right`. For each component, returns 0 if false or u64::MAX // if true. "cmp.pd.256" => { - let [left, right, imm] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right, imm] = this.check_shim(abi, Conv::C, link_name, args)?; let which = FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?; @@ -138,7 +130,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // and _mm256_cvttpd_epi32 functions. // Converts packed f32/f64 to packed i32. "cvt.ps2dq.256" | "cvtt.ps2dq.256" | "cvt.pd2dq.256" | "cvtt.pd2dq.256" => { - let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [op] = this.check_shim(abi, Conv::C, link_name, args)?; let rnd = match unprefixed_name { // "current SSE rounding mode", assume nearest @@ -156,8 +148,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // sequence of 4-element arrays, and we shuffle each of these arrays, where // `control` determines which element of the current `data` array is written. "vpermilvar.ps" | "vpermilvar.ps.256" => { - let [data, control] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [data, control] = this.check_shim(abi, Conv::C, link_name, args)?; let (data, data_len) = this.project_to_simd(data)?; let (control, control_len) = this.project_to_simd(control)?; @@ -190,8 +181,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // where `right` determines which element of the current `left` array is // written. "vpermilvar.pd" | "vpermilvar.pd.256" => { - let [data, control] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [data, control] = this.check_shim(abi, Conv::C, link_name, args)?; let (data, data_len) = this.project_to_simd(data)?; let (control, control_len) = this.project_to_simd(control)?; @@ -223,8 +213,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // For each 128-bit element of `dest`, copies one from `left`, `right` or // zero, according to `imm`. "vperm2f128.ps.256" | "vperm2f128.pd.256" | "vperm2f128.si.256" => { - let [left, right, imm] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right, imm] = this.check_shim(abi, Conv::C, link_name, args)?; assert_eq!(dest.layout, left.layout); assert_eq!(dest.layout, right.layout); @@ -267,8 +256,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // is one, it is loaded from `ptr.wrapping_add(i)`, otherwise zero is // loaded. "maskload.ps" | "maskload.pd" | "maskload.ps.256" | "maskload.pd.256" => { - let [ptr, mask] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [ptr, mask] = this.check_shim(abi, Conv::C, link_name, args)?; mask_load(this, ptr, mask, dest)?; } @@ -278,8 +266,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // is one, it is stored into `ptr.wapping_add(i)`. // Unlike SSE2's _mm_maskmoveu_si128, these are not non-temporal stores. "maskstore.ps" | "maskstore.pd" | "maskstore.ps.256" | "maskstore.pd.256" => { - let [ptr, mask, value] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [ptr, mask, value] = this.check_shim(abi, Conv::C, link_name, args)?; mask_store(this, ptr, mask, value)?; } @@ -289,8 +276,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // the data crosses a cache line, but for Miri this is just a regular // unaligned read. "ldu.dq.256" => { - let [src_ptr] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [src_ptr] = this.check_shim(abi, Conv::C, link_name, args)?; let src_ptr = this.read_pointer(src_ptr)?; let dest = dest.force_mplace(this)?; @@ -302,8 +288,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Tests `op & mask == 0`, `op & mask == mask` or // `op & mask != 0 && op & mask != mask` "ptestz.256" | "ptestc.256" | "ptestnzc.256" => { - let [op, mask] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [op, mask] = this.check_shim(abi, Conv::C, link_name, args)?; let (all_zero, masked_set) = test_bits_masked(this, op, mask)?; let res = match unprefixed_name { @@ -326,8 +311,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "vtestz.pd.256" | "vtestc.pd.256" | "vtestnzc.pd.256" | "vtestz.pd" | "vtestc.pd" | "vtestnzc.pd" | "vtestz.ps.256" | "vtestc.ps.256" | "vtestnzc.ps.256" | "vtestz.ps" | "vtestc.ps" | "vtestnzc.ps" => { - let [op, mask] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [op, mask] = this.check_shim(abi, Conv::C, link_name, args)?; let (direct, negated) = test_high_bits_masked(this, op, mask)?; let res = match unprefixed_name { @@ -349,7 +333,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // compiler, making these functions no-ops. // The only thing that needs to be ensured is the correct calling convention. - let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, Conv::C, link_name, args)?; } _ => return interp_ok(EmulateItemResult::NotSupported), } diff --git a/src/tools/miri/src/shims/x86/avx2.rs b/src/tools/miri/src/shims/x86/avx2.rs index 6aefb87d4d0..c79899285cd 100644 --- a/src/tools/miri/src/shims/x86/avx2.rs +++ b/src/tools/miri/src/shims/x86/avx2.rs @@ -1,8 +1,8 @@ -use rustc_abi::ExternAbi; use rustc_middle::mir; use rustc_middle::ty::Ty; use rustc_middle::ty::layout::LayoutOf as _; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; use super::{ ShiftOp, horizontal_bin_op, int_abs, mask_load, mask_store, mpsadbw, packssdw, packsswb, @@ -15,7 +15,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_avx2_intrinsic( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -28,7 +28,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Used to implement the _mm256_abs_epi{8,16,32} functions. // Calculates the absolute value of packed 8/16/32-bit integers. "pabs.b" | "pabs.w" | "pabs.d" => { - let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [op] = this.check_shim(abi, Conv::C, link_name, args)?; int_abs(this, op, dest)?; } @@ -36,8 +36,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Horizontally add / add with saturation / subtract adjacent 16/32-bit // integer values in `left` and `right`. "phadd.w" | "phadd.sw" | "phadd.d" | "phsub.w" | "phsub.sw" | "phsub.d" => { - let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let (which, saturating) = match unprefixed_name { "phadd.w" | "phadd.d" => (mir::BinOp::Add, false), @@ -58,7 +57,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { | "gather.d.pd.256" | "gather.q.pd" | "gather.q.pd.256" | "gather.d.ps" | "gather.d.ps.256" | "gather.q.ps" | "gather.q.ps.256" => { let [src, slice, offsets, mask, scale] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; assert_eq!(dest.layout, src.layout); @@ -115,8 +114,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // intermediate signed 32-bit integers. Horizontally add adjacent pairs of // intermediate 32-bit integers, and pack the results in `dest`. "pmadd.wd" => { - let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -152,8 +150,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // the saturating sum of the products with indices `2*i` and `2*i+1` // produces the output at index `i`. "pmadd.ub.sw" => { - let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -187,8 +184,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // is one, it is loaded from `ptr.wrapping_add(i)`, otherwise zero is // loaded. "maskload.d" | "maskload.q" | "maskload.d.256" | "maskload.q.256" => { - let [ptr, mask] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [ptr, mask] = this.check_shim(abi, Conv::C, link_name, args)?; mask_load(this, ptr, mask, dest)?; } @@ -198,8 +194,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // is one, it is stored into `ptr.wapping_add(i)`. // Unlike SSE2's _mm_maskmoveu_si128, these are not non-temporal stores. "maskstore.d" | "maskstore.q" | "maskstore.d.256" | "maskstore.q.256" => { - let [ptr, mask, value] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [ptr, mask, value] = this.check_shim(abi, Conv::C, link_name, args)?; mask_store(this, ptr, mask, value)?; } @@ -210,8 +205,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // offsets specified in `imm`. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_mpsadbw_epu8 "mpsadbw" => { - let [left, right, imm] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right, imm] = this.check_shim(abi, Conv::C, link_name, args)?; mpsadbw(this, left, right, imm, dest)?; } @@ -222,8 +216,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // 1 and then taking the bits `1..=16`. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_mulhrs_epi16 "pmul.hr.sw" => { - let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; pmulhrsw(this, left, right, dest)?; } @@ -231,8 +224,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Converts two 16-bit integer vectors to a single 8-bit integer // vector with signed saturation. "packsswb" => { - let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; packsswb(this, left, right, dest)?; } @@ -240,8 +232,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Converts two 32-bit integer vectors to a single 16-bit integer // vector with signed saturation. "packssdw" => { - let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; packssdw(this, left, right, dest)?; } @@ -249,8 +240,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Converts two 16-bit signed integer vectors to a single 8-bit // unsigned integer vector with saturation. "packuswb" => { - let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; packuswb(this, left, right, dest)?; } @@ -258,8 +248,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Concatenates two 32-bit signed integer vectors and converts // the result to a 16-bit unsigned integer vector with saturation. "packusdw" => { - let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; packusdw(this, left, right, dest)?; } @@ -268,8 +257,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Shuffles `left` using the three low bits of each element of `right` // as indices. "permd" | "permps" => { - let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -289,8 +277,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Used to implement the _mm256_permute2x128_si256 function. // Shuffles 128-bit blocks of `a` and `b` using `imm` as pattern. "vperm2i128" => { - let [left, right, imm] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right, imm] = this.check_shim(abi, Conv::C, link_name, args)?; assert_eq!(left.layout.size.bits(), 256); assert_eq!(right.layout.size.bits(), 256); @@ -327,8 +314,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // in `dest`. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_sad_epu8 "psad.bw" => { - let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -360,8 +346,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Shuffles bytes from `left` using `right` as pattern. // Each 128-bit block is shuffled independently. "pshuf.b" => { - let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -392,8 +377,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // is writen to the corresponding output element. // Basically, we multiply `left` with `right.signum()`. "psign.b" | "psign.w" | "psign.d" => { - let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; psign(this, left, right, dest)?; } @@ -407,8 +391,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // is copied to remaining bits. "psll.w" | "psrl.w" | "psra.w" | "psll.d" | "psrl.d" | "psra.d" | "psll.q" | "psrl.q" => { - let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let which = match unprefixed_name { "psll.w" | "psll.d" | "psll.q" => ShiftOp::Left, @@ -423,8 +406,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // (except _mm{,256}_srav_epi64, which are not available in AVX2). "psllv.d" | "psllv.d.256" | "psllv.q" | "psllv.q.256" | "psrlv.d" | "psrlv.d.256" | "psrlv.q" | "psrlv.q.256" | "psrav.d" | "psrav.d.256" => { - let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let which = match unprefixed_name { "psllv.d" | "psllv.d.256" | "psllv.q" | "psllv.q.256" => ShiftOp::Left, diff --git a/src/tools/miri/src/shims/x86/bmi.rs b/src/tools/miri/src/shims/x86/bmi.rs index 0f9e8d6f025..8af59df0a68 100644 --- a/src/tools/miri/src/shims/x86/bmi.rs +++ b/src/tools/miri/src/shims/x86/bmi.rs @@ -1,5 +1,6 @@ -use rustc_abi::ExternAbi; +use rustc_middle::ty::Ty; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; use crate::*; @@ -8,7 +9,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_bmi_intrinsic( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -33,8 +34,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { return interp_ok(EmulateItemResult::NotSupported); } - let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let left = this.read_scalar(left)?; let right = this.read_scalar(right)?; diff --git a/src/tools/miri/src/shims/x86/gfni.rs b/src/tools/miri/src/shims/x86/gfni.rs index 92010345f55..4774ec9f9d8 100644 --- a/src/tools/miri/src/shims/x86/gfni.rs +++ b/src/tools/miri/src/shims/x86/gfni.rs @@ -1,5 +1,6 @@ -use rustc_abi::ExternAbi; +use rustc_middle::ty::Ty; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; use crate::*; @@ -8,7 +9,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_gfni_intrinsic( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -29,16 +30,14 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // See `affine_transform` for details. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=gf2p8affine_ "vgf2p8affineqb.128" | "vgf2p8affineqb.256" | "vgf2p8affineqb.512" => { - let [left, right, imm8] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right, imm8] = this.check_shim(abi, Conv::C, link_name, args)?; affine_transform(this, left, right, imm8, dest, /* inverse */ false)?; } // Used to implement the `_mm{, 256, 512}_gf2p8affineinv_epi64_epi8` functions. // See `affine_transform` for details. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=gf2p8affineinv "vgf2p8affineinvqb.128" | "vgf2p8affineinvqb.256" | "vgf2p8affineinvqb.512" => { - let [left, right, imm8] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right, imm8] = this.check_shim(abi, Conv::C, link_name, args)?; affine_transform(this, left, right, imm8, dest, /* inverse */ true)?; } // Used to implement the `_mm{, 256, 512}_gf2p8mul_epi8` functions. @@ -47,9 +46,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // polynomial representation with the reduction polynomial x^8 + x^4 + x^3 + x + 1. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=gf2p8mul "vgf2p8mulb.128" | "vgf2p8mulb.256" | "vgf2p8mulb.512" => { - let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; - + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; let (dest, dest_len) = this.project_to_simd(dest)?; diff --git a/src/tools/miri/src/shims/x86/mod.rs b/src/tools/miri/src/shims/x86/mod.rs index 3e02a4b3637..e57217dc6f2 100644 --- a/src/tools/miri/src/shims/x86/mod.rs +++ b/src/tools/miri/src/shims/x86/mod.rs @@ -1,10 +1,11 @@ -use rustc_abi::{ExternAbi, Size}; +use rustc_abi::Size; use rustc_apfloat::Float; use rustc_apfloat::ieee::Single; use rustc_middle::ty::Ty; use rustc_middle::ty::layout::LayoutOf as _; use rustc_middle::{mir, ty}; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; use self::helpers::bool_to_simd_element; use crate::*; @@ -27,7 +28,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_intrinsic( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -45,8 +46,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { return interp_ok(EmulateItemResult::NotSupported); } - let [cb_in, a, b] = this.check_shim(abi, ExternAbi::Unadjusted, link_name, args)?; - + let [cb_in, a, b] = this.check_shim(abi, Conv::C, link_name, args)?; let op = if unprefixed_name.starts_with("add") { mir::BinOp::AddWithOverflow } else { @@ -68,9 +68,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { if is_u64 && this.tcx.sess.target.arch != "x86_64" { return interp_ok(EmulateItemResult::NotSupported); } - - let [c_in, a, b, out] = - this.check_shim(abi, ExternAbi::Unadjusted, link_name, args)?; + let [c_in, a, b, out] = this.check_shim(abi, Conv::C, link_name, args)?; let out = this.deref_pointer_as( out, if is_u64 { this.machine.layouts.u64 } else { this.machine.layouts.u32 }, @@ -87,7 +85,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // the instruction behaves like a no-op, so it is always safe to call the // intrinsic. "sse2.pause" => { - let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, Conv::C, link_name, args)?; // Only exhibit the spin-loop hint behavior when SSE2 is enabled. if this.tcx.sess.unstable_target_features.contains(&Symbol::intern("sse2")) { this.yield_active_thread(); @@ -106,8 +104,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { len = 8; } - let [left, right, imm] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right, imm] = this.check_shim(abi, Conv::C, link_name, args)?; pclmulqdq(this, left, right, imm, dest, len)?; } diff --git a/src/tools/miri/src/shims/x86/sha.rs b/src/tools/miri/src/shims/x86/sha.rs index f18ff1ec253..6d2c151243c 100644 --- a/src/tools/miri/src/shims/x86/sha.rs +++ b/src/tools/miri/src/shims/x86/sha.rs @@ -4,8 +4,9 @@ //! //! [RustCrypto's sha256 module]: https://github.com/RustCrypto/hashes/blob/6be8466247e936c415d8aafb848697f39894a386/sha2/src/sha256/soft.rs -use rustc_abi::ExternAbi; +use rustc_middle::ty::Ty; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; use crate::*; @@ -14,7 +15,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_sha_intrinsic( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -51,8 +52,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { match unprefixed_name { // Used to implement the _mm_sha256rnds2_epu32 function. "256rnds2" => { - let [a, b, k] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [a, b, k] = this.check_shim(abi, Conv::C, link_name, args)?; let (a_reg, a_len) = this.project_to_simd(a)?; let (b_reg, b_len) = this.project_to_simd(b)?; @@ -73,8 +73,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } // Used to implement the _mm_sha256msg1_epu32 function. "256msg1" => { - let [a, b] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [a, b] = this.check_shim(abi, Conv::C, link_name, args)?; let (a_reg, a_len) = this.project_to_simd(a)?; let (b_reg, b_len) = this.project_to_simd(b)?; @@ -92,8 +91,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } // Used to implement the _mm_sha256msg2_epu32 function. "256msg2" => { - let [a, b] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [a, b] = this.check_shim(abi, Conv::C, link_name, args)?; let (a_reg, a_len) = this.project_to_simd(a)?; let (b_reg, b_len) = this.project_to_simd(b)?; diff --git a/src/tools/miri/src/shims/x86/sse.rs b/src/tools/miri/src/shims/x86/sse.rs index 9432b40a805..fd7aba2437a 100644 --- a/src/tools/miri/src/shims/x86/sse.rs +++ b/src/tools/miri/src/shims/x86/sse.rs @@ -1,6 +1,7 @@ -use rustc_abi::ExternAbi; use rustc_apfloat::ieee::Single; +use rustc_middle::ty::Ty; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; use super::{ FloatBinOp, FloatUnaryOp, bin_op_simd_float_all, bin_op_simd_float_first, unary_op_ps, @@ -13,7 +14,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_sse_intrinsic( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -32,8 +33,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Performs the operations on the first component of `left` and // `right` and copies the remaining components from `left`. "min.ss" | "max.ss" => { - let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let which = match unprefixed_name { "min.ss" => FloatBinOp::Min, @@ -49,8 +49,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // matches the IEEE min/max operations, while x86 has different // semantics. "min.ps" | "max.ps" => { - let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let which = match unprefixed_name { "min.ps" => FloatBinOp::Min, @@ -64,7 +63,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Performs the operations on the first component of `op` and // copies the remaining components from `op`. "rcp.ss" | "rsqrt.ss" => { - let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [op] = this.check_shim(abi, Conv::C, link_name, args)?; let which = match unprefixed_name { "rcp.ss" => FloatUnaryOp::Rcp, @@ -77,7 +76,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Used to implement _mm_{sqrt,rcp,rsqrt}_ps functions. // Performs the operations on all components of `op`. "rcp.ps" | "rsqrt.ps" => { - let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [op] = this.check_shim(abi, Conv::C, link_name, args)?; let which = match unprefixed_name { "rcp.ps" => FloatUnaryOp::Rcp, @@ -96,8 +95,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // _mm_cmp{eq,lt,le,gt,ge,neq,nlt,nle,ngt,nge,ord,unord}_ss are SSE functions // with hard-coded operations. "cmp.ss" => { - let [left, right, imm] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right, imm] = this.check_shim(abi, Conv::C, link_name, args)?; let which = FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?; @@ -113,8 +111,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // _mm_cmp{eq,lt,le,gt,ge,neq,nlt,nle,ngt,nge,ord,unord}_ps are SSE functions // with hard-coded operations. "cmp.ps" => { - let [left, right, imm] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right, imm] = this.check_shim(abi, Conv::C, link_name, args)?; let which = FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?; @@ -127,8 +124,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "comieq.ss" | "comilt.ss" | "comile.ss" | "comigt.ss" | "comige.ss" | "comineq.ss" | "ucomieq.ss" | "ucomilt.ss" | "ucomile.ss" | "ucomigt.ss" | "ucomige.ss" | "ucomineq.ss" => { - let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -156,7 +152,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // _mm_cvtss_si64 and _mm_cvttss_si64 functions. // Converts the first component of `op` from f32 to i32/i64. "cvtss2si" | "cvttss2si" | "cvtss2si64" | "cvttss2si64" => { - let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [op] = this.check_shim(abi, Conv::C, link_name, args)?; let (op, _) = this.project_to_simd(op)?; let op = this.read_immediate(&this.project_index(&op, 0)?)?; @@ -184,8 +180,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // are copied from `left`. // https://www.felixcloutier.com/x86/cvtsi2ss "cvtsi2ss" | "cvtsi642ss" => { - let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (dest, dest_len) = this.project_to_simd(dest)?; diff --git a/src/tools/miri/src/shims/x86/sse2.rs b/src/tools/miri/src/shims/x86/sse2.rs index 4ff999be7cc..e0695b7cb7b 100644 --- a/src/tools/miri/src/shims/x86/sse2.rs +++ b/src/tools/miri/src/shims/x86/sse2.rs @@ -1,6 +1,7 @@ -use rustc_abi::ExternAbi; use rustc_apfloat::ieee::Double; +use rustc_middle::ty::Ty; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; use super::{ FloatBinOp, ShiftOp, bin_op_simd_float_all, bin_op_simd_float_first, convert_float_to_int, @@ -13,7 +14,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_sse2_intrinsic( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -39,8 +40,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // intermediate signed 32-bit integers. Horizontally add adjacent pairs of // intermediate 32-bit integers, and pack the results in `dest`. "pmadd.wd" => { - let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -78,8 +78,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_sad_epu8 "psad.bw" => { - let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -117,8 +116,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // is copied to remaining bits. "psll.w" | "psrl.w" | "psra.w" | "psll.d" | "psrl.d" | "psra.d" | "psll.q" | "psrl.q" => { - let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let which = match unprefixed_name { "psll.w" | "psll.d" | "psll.q" => ShiftOp::Left, @@ -133,7 +131,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // and _mm_cvttpd_epi32 functions. // Converts packed f32/f64 to packed i32. "cvtps2dq" | "cvttps2dq" | "cvtpd2dq" | "cvttpd2dq" => { - let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [op] = this.check_shim(abi, Conv::C, link_name, args)?; let (op_len, _) = op.layout.ty.simd_size_and_type(*this.tcx); let (dest_len, _) = dest.layout.ty.simd_size_and_type(*this.tcx); @@ -170,8 +168,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Converts two 16-bit integer vectors to a single 8-bit integer // vector with signed saturation. "packsswb.128" => { - let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; packsswb(this, left, right, dest)?; } @@ -179,8 +176,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Converts two 16-bit signed integer vectors to a single 8-bit // unsigned integer vector with saturation. "packuswb.128" => { - let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; packuswb(this, left, right, dest)?; } @@ -188,8 +184,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Converts two 32-bit integer vectors to a single 16-bit integer // vector with signed saturation. "packssdw.128" => { - let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; packssdw(this, left, right, dest)?; } @@ -199,8 +194,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // matches the IEEE min/max operations, while x86 has different // semantics. "min.sd" | "max.sd" => { - let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let which = match unprefixed_name { "min.sd" => FloatBinOp::Min, @@ -216,8 +210,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // matches the IEEE min/max operations, while x86 has different // semantics. "min.pd" | "max.pd" => { - let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let which = match unprefixed_name { "min.pd" => FloatBinOp::Min, @@ -236,8 +229,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // _mm_cmp{eq,lt,le,gt,ge,neq,nlt,nle,ngt,nge,ord,unord}_sd are SSE2 functions // with hard-coded operations. "cmp.sd" => { - let [left, right, imm] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right, imm] = this.check_shim(abi, Conv::C, link_name, args)?; let which = FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?; @@ -253,8 +245,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // _mm_cmp{eq,lt,le,gt,ge,neq,nlt,nle,ngt,nge,ord,unord}_pd are SSE2 functions // with hard-coded operations. "cmp.pd" => { - let [left, right, imm] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right, imm] = this.check_shim(abi, Conv::C, link_name, args)?; let which = FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?; @@ -267,8 +258,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "comieq.sd" | "comilt.sd" | "comile.sd" | "comigt.sd" | "comige.sd" | "comineq.sd" | "ucomieq.sd" | "ucomilt.sd" | "ucomile.sd" | "ucomigt.sd" | "ucomige.sd" | "ucomineq.sd" => { - let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -296,7 +286,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // _mm_cvtsd_si64 and _mm_cvttsd_si64 functions. // Converts the first component of `op` from f64 to i32/i64. "cvtsd2si" | "cvttsd2si" | "cvtsd2si64" | "cvttsd2si64" => { - let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [op] = this.check_shim(abi, Conv::C, link_name, args)?; let (op, _) = this.project_to_simd(op)?; let op = this.read_immediate(&this.project_index(&op, 0)?)?; @@ -322,8 +312,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Converts the first f64/f32 from `right` to f32/f64 and copies // the remaining elements from `left` "cvtsd2ss" | "cvtss2sd" => { - let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, _) = this.project_to_simd(right)?; diff --git a/src/tools/miri/src/shims/x86/sse3.rs b/src/tools/miri/src/shims/x86/sse3.rs index 86153d71b28..60b7764a01e 100644 --- a/src/tools/miri/src/shims/x86/sse3.rs +++ b/src/tools/miri/src/shims/x86/sse3.rs @@ -1,6 +1,7 @@ -use rustc_abi::ExternAbi; use rustc_middle::mir; +use rustc_middle::ty::Ty; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; use super::horizontal_bin_op; use crate::*; @@ -10,7 +11,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_sse3_intrinsic( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -24,8 +25,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Horizontally add/subtract adjacent floating point values // in `left` and `right`. "hadd.ps" | "hadd.pd" | "hsub.ps" | "hsub.pd" => { - let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let which = match unprefixed_name { "hadd.ps" | "hadd.pd" => mir::BinOp::Add, @@ -41,8 +41,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // the data crosses a cache line, but for Miri this is just a regular // unaligned read. "ldu.dq" => { - let [src_ptr] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [src_ptr] = this.check_shim(abi, Conv::C, link_name, args)?; let src_ptr = this.read_pointer(src_ptr)?; let dest = dest.force_mplace(this)?; diff --git a/src/tools/miri/src/shims/x86/sse41.rs b/src/tools/miri/src/shims/x86/sse41.rs index b81d6f24141..93d689a3044 100644 --- a/src/tools/miri/src/shims/x86/sse41.rs +++ b/src/tools/miri/src/shims/x86/sse41.rs @@ -1,5 +1,6 @@ -use rustc_abi::ExternAbi; +use rustc_middle::ty::Ty; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; use super::{conditional_dot_product, mpsadbw, packusdw, round_all, round_first, test_bits_masked}; use crate::*; @@ -9,7 +10,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_sse41_intrinsic( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -26,8 +27,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // bits `4..=5` if `imm`, and `i`th bit specifies whether element // `i` is zeroed. "insertps" => { - let [left, right, imm] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right, imm] = this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -62,8 +62,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Concatenates two 32-bit signed integer vectors and converts // the result to a 16-bit unsigned integer vector with saturation. "packusdw" => { - let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; packusdw(this, left, right, dest)?; } @@ -73,8 +72,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // products, and conditionally stores the sum in `dest` using the low // 4 bits of `imm`. "dpps" | "dppd" => { - let [left, right, imm] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right, imm] = this.check_shim(abi, Conv::C, link_name, args)?; conditional_dot_product(this, left, right, imm, dest)?; } @@ -82,16 +80,14 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // functions. Rounds the first element of `right` according to `rounding` // and copies the remaining elements from `left`. "round.ss" => { - let [left, right, rounding] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right, rounding] = this.check_shim(abi, Conv::C, link_name, args)?; round_first::<rustc_apfloat::ieee::Single>(this, left, right, rounding, dest)?; } // Used to implement the _mm_floor_ps, _mm_ceil_ps and _mm_round_ps // functions. Rounds the elements of `op` according to `rounding`. "round.ps" => { - let [op, rounding] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [op, rounding] = this.check_shim(abi, Conv::C, link_name, args)?; round_all::<rustc_apfloat::ieee::Single>(this, op, rounding, dest)?; } @@ -99,16 +95,14 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // functions. Rounds the first element of `right` according to `rounding` // and copies the remaining elements from `left`. "round.sd" => { - let [left, right, rounding] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right, rounding] = this.check_shim(abi, Conv::C, link_name, args)?; round_first::<rustc_apfloat::ieee::Double>(this, left, right, rounding, dest)?; } // Used to implement the _mm_floor_pd, _mm_ceil_pd and _mm_round_pd // functions. Rounds the elements of `op` according to `rounding`. "round.pd" => { - let [op, rounding] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [op, rounding] = this.check_shim(abi, Conv::C, link_name, args)?; round_all::<rustc_apfloat::ieee::Double>(this, op, rounding, dest)?; } @@ -116,7 +110,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Find the minimum unsinged 16-bit integer in `op` and // returns its value and position. "phminposuw" => { - let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [op] = this.check_shim(abi, Conv::C, link_name, args)?; let (op, op_len) = this.project_to_simd(op)?; let (dest, dest_len) = this.project_to_simd(dest)?; @@ -150,8 +144,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // offsets specified in `imm`. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_mpsadbw_epu8 "mpsadbw" => { - let [left, right, imm] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right, imm] = this.check_shim(abi, Conv::C, link_name, args)?; mpsadbw(this, left, right, imm, dest)?; } @@ -160,8 +153,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Tests `(op & mask) == 0`, `(op & mask) == mask` or // `(op & mask) != 0 && (op & mask) != mask` "ptestz" | "ptestc" | "ptestnzc" => { - let [op, mask] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [op, mask] = this.check_shim(abi, Conv::C, link_name, args)?; let (all_zero, masked_set) = test_bits_masked(this, op, mask)?; let res = match unprefixed_name { diff --git a/src/tools/miri/src/shims/x86/sse42.rs b/src/tools/miri/src/shims/x86/sse42.rs index 0b058a9911e..02336a722f7 100644 --- a/src/tools/miri/src/shims/x86/sse42.rs +++ b/src/tools/miri/src/shims/x86/sse42.rs @@ -1,8 +1,9 @@ -use rustc_abi::{ExternAbi, Size}; +use rustc_abi::Size; use rustc_middle::mir; use rustc_middle::ty::Ty; use rustc_middle::ty::layout::LayoutOf as _; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; use crate::*; @@ -200,7 +201,7 @@ fn deconstruct_args<'tcx>( unprefixed_name: &str, ecx: &mut MiriInterpCx<'tcx>, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], ) -> InterpResult<'tcx, (OpTy<'tcx>, OpTy<'tcx>, Option<(u64, u64)>, u8)> { let array_layout_fn = |ecx: &mut MiriInterpCx<'tcx>, imm: u8| { @@ -222,8 +223,7 @@ fn deconstruct_args<'tcx>( }; if is_explicit { - let [str1, len1, str2, len2, imm] = - ecx.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [str1, len1, str2, len2, imm] = ecx.check_shim(abi, Conv::C, link_name, args)?; let imm = ecx.read_scalar(imm)?.to_u8()?; let default_len = default_len::<u32>(imm); @@ -236,8 +236,7 @@ fn deconstruct_args<'tcx>( interp_ok((str1, str2, Some((len1, len2)), imm)) } else { - let [str1, str2, imm] = - ecx.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [str1, str2, imm] = ecx.check_shim(abi, Conv::C, link_name, args)?; let imm = ecx.read_scalar(imm)?.to_u8()?; let array_layout = array_layout_fn(ecx, imm)?; @@ -279,7 +278,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_sse42_intrinsic( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -387,8 +386,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // search for a null terminator (see `deconstruct_args` for more details). // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#ig_expand=924,925 "pcmpistriz128" | "pcmpistris128" => { - let [str1, str2, imm] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [str1, str2, imm] = this.check_shim(abi, Conv::C, link_name, args)?; let imm = this.read_scalar(imm)?.to_u8()?; let str = if unprefixed_name == "pcmpistris128" { str1 } else { str2 }; @@ -408,8 +406,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // than 16 for byte-sized operands or 8 for word-sized operands. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#ig_expand=1046,1047 "pcmpestriz128" | "pcmpestris128" => { - let [_, len1, _, len2, imm] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [_, len1, _, len2, imm] = this.check_shim(abi, Conv::C, link_name, args)?; let len = if unprefixed_name == "pcmpestris128" { len1 } else { len2 }; let len = this.read_scalar(len)?.to_i32()?; let imm = this.read_scalar(imm)?.to_u8()?; @@ -436,8 +433,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { return interp_ok(EmulateItemResult::NotSupported); } - let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let left = this.read_scalar(left)?; let right = this.read_scalar(right)?; diff --git a/src/tools/miri/src/shims/x86/ssse3.rs b/src/tools/miri/src/shims/x86/ssse3.rs index cdab78bc742..f3e9ac0e5dc 100644 --- a/src/tools/miri/src/shims/x86/ssse3.rs +++ b/src/tools/miri/src/shims/x86/ssse3.rs @@ -1,6 +1,7 @@ -use rustc_abi::ExternAbi; use rustc_middle::mir; +use rustc_middle::ty::Ty; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; use super::{horizontal_bin_op, int_abs, pmulhrsw, psign}; use crate::*; @@ -10,7 +11,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_ssse3_intrinsic( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -23,7 +24,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Used to implement the _mm_abs_epi{8,16,32} functions. // Calculates the absolute value of packed 8/16/32-bit integers. "pabs.b.128" | "pabs.w.128" | "pabs.d.128" => { - let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [op] = this.check_shim(abi, Conv::C, link_name, args)?; int_abs(this, op, dest)?; } @@ -31,8 +32,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Shuffles bytes from `left` using `right` as pattern. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_shuffle_epi8 "pshuf.b.128" => { - let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -61,8 +61,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // integer values in `left` and `right`. "phadd.w.128" | "phadd.sw.128" | "phadd.d.128" | "phsub.w.128" | "phsub.sw.128" | "phsub.d.128" => { - let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let (which, saturating) = match unprefixed_name { "phadd.w.128" | "phadd.d.128" => (mir::BinOp::Add, false), @@ -81,8 +80,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // produces the output at index `i`. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_maddubs_epi16 "pmadd.ub.sw.128" => { - let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -117,8 +115,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // 1 and then taking the bits `1..=16`. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_mulhrs_epi16 "pmul.hr.sw.128" => { - let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; pmulhrsw(this, left, right, dest)?; } @@ -128,8 +125,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // is writen to the corresponding output element. // Basically, we multiply `left` with `right.signum()`. "psign.b.128" | "psign.w.128" | "psign.d.128" => { - let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; psign(this, left, right, dest)?; } diff --git a/src/tools/miri/tests/fail-dep/libc/socketpair_block_read_twice.rs b/src/tools/miri/tests/fail-dep/libc/socketpair_block_read_twice.rs new file mode 100644 index 00000000000..d3e4c43f2b7 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/libc/socketpair_block_read_twice.rs @@ -0,0 +1,47 @@ +//@ignore-target: windows # No libc socketpair on Windows +//~^ERROR: deadlocked +//~^^ERROR: deadlocked +// test_race depends on a deterministic schedule. +//@compile-flags: -Zmiri-preemption-rate=0 +//@error-in-other-file: deadlock + +use std::thread; + +// Test the behaviour of a thread being blocked on read, get unblocked, then blocked again. + +// The expected execution is +// 1. Thread 1 blocks. +// 2. Thread 2 blocks. +// 3. Thread 3 unblocks both thread 1 and thread 2. +// 4. Thread 1 reads. +// 5. Thread 2's `read` can never complete -> deadlocked. + +fn main() { + let mut fds = [-1, -1]; + let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }; + assert_eq!(res, 0); + let thread1 = thread::spawn(move || { + // Let this thread block on read. + let mut buf: [u8; 3] = [0; 3]; + let res = unsafe { libc::read(fds[1], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) }; + assert_eq!(res, 3); + assert_eq!(&buf, "abc".as_bytes()); + }); + let thread2 = thread::spawn(move || { + // Let this thread block on read. + let mut buf: [u8; 3] = [0; 3]; + let res = unsafe { libc::read(fds[1], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) }; + //~^ERROR: deadlocked + assert_eq!(res, 3); + assert_eq!(&buf, "abc".as_bytes()); + }); + let thread3 = thread::spawn(move || { + // Unblock thread1 by writing something. + let data = "abc".as_bytes().as_ptr(); + let res = unsafe { libc::write(fds[0], data as *const libc::c_void, 3) }; + assert_eq!(res, 3); + }); + thread1.join().unwrap(); + thread2.join().unwrap(); + thread3.join().unwrap(); +} diff --git a/src/tools/miri/tests/fail-dep/libc/socketpair_block_read_twice.stderr b/src/tools/miri/tests/fail-dep/libc/socketpair_block_read_twice.stderr new file mode 100644 index 00000000000..ab807a579db --- /dev/null +++ b/src/tools/miri/tests/fail-dep/libc/socketpair_block_read_twice.stderr @@ -0,0 +1,41 @@ +error: deadlock: the evaluated program deadlocked + --> RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC + | +LL | let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) }; + | ^ the evaluated program deadlocked + | + = note: BACKTRACE: + = note: inside `std::sys::pal::PLATFORM::thread::Thread::join` at RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC + = note: inside `std::thread::JoinInner::<'_, ()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC + = note: inside `std::thread::JoinHandle::<()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC +note: inside `main` + --> tests/fail-dep/libc/socketpair_block_read_twice.rs:LL:CC + | +LL | thread2.join().unwrap(); + | ^^^^^^^^^^^^^^ + +error: deadlock: the evaluated program deadlocked + | + = note: the evaluated program deadlocked + = note: (no span available) + = note: BACKTRACE on thread `unnamed-ID`: + +error: deadlock: the evaluated program deadlocked + --> tests/fail-dep/libc/socketpair_block_read_twice.rs:LL:CC + | +LL | let res = unsafe { libc::read(fds[1], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) }; + | ^ the evaluated program deadlocked + | + = note: BACKTRACE on thread `unnamed-ID`: + = note: inside closure at tests/fail-dep/libc/socketpair_block_read_twice.rs:LL:CC + +error: deadlock: the evaluated program deadlocked + | + = note: the evaluated program deadlocked + = note: (no span available) + = note: BACKTRACE on thread `unnamed-ID`: + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 4 previous errors + diff --git a/src/tools/miri/tests/fail-dep/libc/socketpair_block_write_twice.rs b/src/tools/miri/tests/fail-dep/libc/socketpair_block_write_twice.rs new file mode 100644 index 00000000000..4f951acb2c3 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/libc/socketpair_block_write_twice.rs @@ -0,0 +1,49 @@ +//@ignore-target: windows # No libc socketpair on Windows +//~^ERROR: deadlocked +//~^^ERROR: deadlocked +// test_race depends on a deterministic schedule. +//@compile-flags: -Zmiri-preemption-rate=0 +//@error-in-other-file: deadlock + +use std::thread; + +// Test the behaviour of a thread being blocked on write, get unblocked, then blocked again. + +// The expected execution is +// 1. Thread 1 blocks. +// 2. Thread 2 blocks. +// 3. Thread 3 unblocks both thread 1 and thread 2. +// 4. Thread 1 reads. +// 5. Thread 2's `write` can never complete -> deadlocked. +fn main() { + let mut fds = [-1, -1]; + let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }; + assert_eq!(res, 0); + let arr1: [u8; 212992] = [1; 212992]; + // Exhaust the space in the buffer so the subsequent write will block. + let res = unsafe { libc::write(fds[0], arr1.as_ptr() as *const libc::c_void, 212992) }; + assert_eq!(res, 212992); + let thread1 = thread::spawn(move || { + let data = "abc".as_bytes().as_ptr(); + // The write below will be blocked because the buffer is already full. + let res = unsafe { libc::write(fds[0], data as *const libc::c_void, 3) }; + assert_eq!(res, 3); + }); + let thread2 = thread::spawn(move || { + let data = "abc".as_bytes().as_ptr(); + // The write below will be blocked because the buffer is already full. + let res = unsafe { libc::write(fds[0], data as *const libc::c_void, 3) }; + //~^ERROR: deadlocked + assert_eq!(res, 3); + }); + let thread3 = thread::spawn(move || { + // Unblock thread1 by freeing up some space. + let mut buf: [u8; 3] = [0; 3]; + let res = unsafe { libc::read(fds[1], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) }; + assert_eq!(res, 3); + assert_eq!(buf, [1, 1, 1]); + }); + thread1.join().unwrap(); + thread2.join().unwrap(); + thread3.join().unwrap(); +} diff --git a/src/tools/miri/tests/fail-dep/libc/socketpair_block_write_twice.stderr b/src/tools/miri/tests/fail-dep/libc/socketpair_block_write_twice.stderr new file mode 100644 index 00000000000..44cda11102d --- /dev/null +++ b/src/tools/miri/tests/fail-dep/libc/socketpair_block_write_twice.stderr @@ -0,0 +1,41 @@ +error: deadlock: the evaluated program deadlocked + --> RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC + | +LL | let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) }; + | ^ the evaluated program deadlocked + | + = note: BACKTRACE: + = note: inside `std::sys::pal::PLATFORM::thread::Thread::join` at RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC + = note: inside `std::thread::JoinInner::<'_, ()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC + = note: inside `std::thread::JoinHandle::<()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC +note: inside `main` + --> tests/fail-dep/libc/socketpair_block_write_twice.rs:LL:CC + | +LL | thread2.join().unwrap(); + | ^^^^^^^^^^^^^^ + +error: deadlock: the evaluated program deadlocked + | + = note: the evaluated program deadlocked + = note: (no span available) + = note: BACKTRACE on thread `unnamed-ID`: + +error: deadlock: the evaluated program deadlocked + --> tests/fail-dep/libc/socketpair_block_write_twice.rs:LL:CC + | +LL | let res = unsafe { libc::write(fds[0], data as *const libc::c_void, 3) }; + | ^ the evaluated program deadlocked + | + = note: BACKTRACE on thread `unnamed-ID`: + = note: inside closure at tests/fail-dep/libc/socketpair_block_write_twice.rs:LL:CC + +error: deadlock: the evaluated program deadlocked + | + = note: the evaluated program deadlocked + = note: (no span available) + = note: BACKTRACE on thread `unnamed-ID`: + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 4 previous errors + diff --git a/src/tools/miri/tests/fail-dep/libc/socketpair_read_blocking.rs b/src/tools/miri/tests/fail-dep/libc/socketpair_read_blocking.rs deleted file mode 100644 index ffa4e36f0f4..00000000000 --- a/src/tools/miri/tests/fail-dep/libc/socketpair_read_blocking.rs +++ /dev/null @@ -1,12 +0,0 @@ -//@ignore-target: windows # no libc socketpair on Windows - -// This is temporarily here because blocking on fd is not supported yet. -// When blocking is eventually supported, this will be moved to pass-dep/libc/libc-socketpair - -fn main() { - let mut fds = [-1, -1]; - let _ = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }; - // The read below will be blocked because the buffer is empty. - let mut buf: [u8; 3] = [0; 3]; - let _res = unsafe { libc::read(fds[1], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) }; //~ERROR: blocking isn't supported -} diff --git a/src/tools/miri/tests/fail-dep/libc/socketpair_read_blocking.stderr b/src/tools/miri/tests/fail-dep/libc/socketpair_read_blocking.stderr index 16892614c63..caf23da1150 100644 --- a/src/tools/miri/tests/fail-dep/libc/socketpair_read_blocking.stderr +++ b/src/tools/miri/tests/fail-dep/libc/socketpair_read_blocking.stderr @@ -1,10 +1,9 @@ -error: unsupported operation: socketpair/pipe/pipe2 read: blocking isn't supported yet +error: deadlock: the evaluated program deadlocked --> tests/fail-dep/libc/socketpair_read_blocking.rs:LL:CC | LL | let _res = unsafe { libc::read(fds[1], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ socketpair/pipe/pipe2 read: blocking isn't supported yet + | ^ the evaluated program deadlocked | - = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support = note: BACKTRACE: = note: inside `main` at tests/fail-dep/libc/socketpair_read_blocking.rs:LL:CC diff --git a/src/tools/miri/tests/fail-dep/libc/socketpair_write_blocking.rs b/src/tools/miri/tests/fail-dep/libc/socketpair_write_blocking.rs deleted file mode 100644 index e83197dfc0f..00000000000 --- a/src/tools/miri/tests/fail-dep/libc/socketpair_write_blocking.rs +++ /dev/null @@ -1,16 +0,0 @@ -//@ignore-target: windows # no libc socketpair on Windows -// This is temporarily here because blocking on fd is not supported yet. -// When blocking is eventually supported, this will be moved to pass-dep/libc/libc-socketpair -fn main() { - let mut fds = [-1, -1]; - let _ = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }; - // Write size > buffer capacity - // Used up all the space in the buffer. - let arr1: [u8; 212992] = [1; 212992]; - let _ = unsafe { libc::write(fds[0], arr1.as_ptr() as *const libc::c_void, 212992) }; - let data = "abc".as_bytes().as_ptr(); - // The write below will be blocked as the buffer is full. - let _ = unsafe { libc::write(fds[0], data as *const libc::c_void, 3) }; //~ERROR: blocking isn't supported - let mut buf: [u8; 3] = [0; 3]; - let _res = unsafe { libc::read(fds[1], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) }; -} diff --git a/src/tools/miri/tests/fail-dep/libc/socketpair_write_blocking.stderr b/src/tools/miri/tests/fail-dep/libc/socketpair_write_blocking.stderr index a2fcf87578a..2dc420d5f1e 100644 --- a/src/tools/miri/tests/fail-dep/libc/socketpair_write_blocking.stderr +++ b/src/tools/miri/tests/fail-dep/libc/socketpair_write_blocking.stderr @@ -1,10 +1,9 @@ -error: unsupported operation: socketpair/pipe/pipe2 write: blocking isn't supported yet +error: deadlock: the evaluated program deadlocked --> tests/fail-dep/libc/socketpair_write_blocking.rs:LL:CC | LL | let _ = unsafe { libc::write(fds[0], data as *const libc::c_void, 3) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ socketpair/pipe/pipe2 write: blocking isn't supported yet + | ^ the evaluated program deadlocked | - = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support = note: BACKTRACE: = note: inside `main` at tests/fail-dep/libc/socketpair_write_blocking.rs:LL:CC diff --git a/src/tools/miri/tests/fail/tree_borrows/subtree_traversal_skipping_diagnostics.rs b/src/tools/miri/tests/fail/tree_borrows/subtree_traversal_skipping_diagnostics.rs new file mode 100644 index 00000000000..6514334b09d --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/subtree_traversal_skipping_diagnostics.rs @@ -0,0 +1,29 @@ +//@compile-flags: -Zmiri-tree-borrows -Zmiri-provenance-gc=0 + +// Shows the effect of the optimization of #4008. +// The diagnostics change, but not the error itself. + +// When this method is called, the tree will be a single line and look like this, +// with other_ptr being the root at the top +// other_ptr = root : Active +// intermediary : Frozen // an intermediary node +// m : Reserved +fn write_to_mut(m: &mut u8, other_ptr: *const u8) { + unsafe { + std::hint::black_box(*other_ptr); + } + // In line 17 above, m should have become Reserved (protected) so that this write is impossible. + // However, that does not happen because the read above is not forwarded to the subtree below + // the Frozen intermediary node. This does not affect UB, however, because the Frozen that blocked + // the read already prevents any child writes. + *m = 42; //~ERROR: /write access through .* is forbidden/ +} + +fn main() { + let root = 42u8; + unsafe { + let intermediary = &root; + let data = &mut *(core::ptr::addr_of!(*intermediary) as *mut u8); + write_to_mut(data, core::ptr::addr_of!(root)); + } +} diff --git a/src/tools/miri/tests/fail/tree_borrows/subtree_traversal_skipping_diagnostics.stderr b/src/tools/miri/tests/fail/tree_borrows/subtree_traversal_skipping_diagnostics.stderr new file mode 100644 index 00000000000..d3ad2a39f2d --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/subtree_traversal_skipping_diagnostics.stderr @@ -0,0 +1,31 @@ +error: Undefined Behavior: write access through <TAG> at ALLOC[0x0] is forbidden + --> tests/fail/tree_borrows/subtree_traversal_skipping_diagnostics.rs:LL:CC + | +LL | *m = 42; + | ^^^^^^^ write access through <TAG> at ALLOC[0x0] is forbidden + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: the accessed tag <TAG> is a child of the conflicting tag <TAG> + = help: the conflicting tag <TAG> has state Frozen which forbids this child write access +help: the accessed tag <TAG> was created here + --> tests/fail/tree_borrows/subtree_traversal_skipping_diagnostics.rs:LL:CC + | +LL | fn write_to_mut(m: &mut u8, other_ptr: *const u8) { + | ^ +help: the conflicting tag <TAG> was created here, in the initial state Frozen + --> tests/fail/tree_borrows/subtree_traversal_skipping_diagnostics.rs:LL:CC + | +LL | let intermediary = &root; + | ^^^^^ + = note: BACKTRACE (of the first span): + = note: inside `write_to_mut` at tests/fail/tree_borrows/subtree_traversal_skipping_diagnostics.rs:LL:CC +note: inside `main` + --> tests/fail/tree_borrows/subtree_traversal_skipping_diagnostics.rs:LL:CC + | +LL | write_to_mut(data, core::ptr::addr_of!(root)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +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/native-lib/pass/ptr_read_access.stderr b/src/tools/miri/tests/native-lib/pass/ptr_read_access.stderr new file mode 100644 index 00000000000..ab40811a9d1 --- /dev/null +++ b/src/tools/miri/tests/native-lib/pass/ptr_read_access.stderr @@ -0,0 +1,18 @@ +warning: sharing memory with a native function + --> tests/native-lib/pass/ptr_read_access.rs:LL:CC + | +LL | unsafe { print_pointer(&x) }; + | ^^^^^^^^^^^^^^^^^ sharing memory with a native function called via FFI + | + = help: when memory is shared with a native function call, Miri stops tracking initialization and provenance for that memory + = help: in particular, Miri assumes that the native call initializes all memory it has access to + = help: Miri also assumes that any part of this memory may be a pointer that is permitted to point to arbitrary exposed memory + = help: what this means is that Miri will easily miss Undefined Behavior related to incorrect usage of this shared memory, so you should not take a clean Miri run as a signal that your FFI code is UB-free + = note: BACKTRACE: + = note: inside `test_access_pointer` at tests/native-lib/pass/ptr_read_access.rs:LL:CC +note: inside `main` + --> tests/native-lib/pass/ptr_read_access.rs:LL:CC + | +LL | test_access_pointer(); + | ^^^^^^^^^^^^^^^^^^^^^ + diff --git a/src/tools/miri/tests/native-lib/pass/ptr_write_access.stderr b/src/tools/miri/tests/native-lib/pass/ptr_write_access.stderr new file mode 100644 index 00000000000..a059d7740ff --- /dev/null +++ b/src/tools/miri/tests/native-lib/pass/ptr_write_access.stderr @@ -0,0 +1,18 @@ +warning: sharing memory with a native function + --> tests/native-lib/pass/ptr_write_access.rs:LL:CC + | +LL | unsafe { increment_int(&mut x) }; + | ^^^^^^^^^^^^^^^^^^^^^ sharing memory with a native function called via FFI + | + = help: when memory is shared with a native function call, Miri stops tracking initialization and provenance for that memory + = help: in particular, Miri assumes that the native call initializes all memory it has access to + = help: Miri also assumes that any part of this memory may be a pointer that is permitted to point to arbitrary exposed memory + = help: what this means is that Miri will easily miss Undefined Behavior related to incorrect usage of this shared memory, so you should not take a clean Miri run as a signal that your FFI code is UB-free + = note: BACKTRACE: + = note: inside `test_increment_int` at tests/native-lib/pass/ptr_write_access.rs:LL:CC +note: inside `main` + --> tests/native-lib/pass/ptr_write_access.rs:LL:CC + | +LL | test_increment_int(); + | ^^^^^^^^^^^^^^^^^^^^ + diff --git a/src/tools/miri/tests/pass-dep/libc/libc-socketpair.rs b/src/tools/miri/tests/pass-dep/libc/libc-socketpair.rs index 64819e57679..bbf0e215953 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-socketpair.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-socketpair.rs @@ -10,6 +10,8 @@ fn main() { test_socketpair(); test_socketpair_threaded(); test_race(); + test_blocking_read(); + test_blocking_write(); } fn test_socketpair() { @@ -136,3 +138,51 @@ fn test_race() { thread::yield_now(); thread1.join().unwrap(); } + +// Test the behaviour of a socketpair getting blocked on read and subsequently unblocked. +fn test_blocking_read() { + let mut fds = [-1, -1]; + let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }; + assert_eq!(res, 0); + let thread1 = thread::spawn(move || { + // Let this thread block on read. + let mut buf: [u8; 3] = [0; 3]; + let res = unsafe { libc::read(fds[1], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) }; + assert_eq!(res, 3); + assert_eq!(&buf, "abc".as_bytes()); + }); + let thread2 = thread::spawn(move || { + // Unblock thread1 by doing writing something. + let data = "abc".as_bytes().as_ptr(); + let res = unsafe { libc::write(fds[0], data as *const libc::c_void, 3) }; + assert_eq!(res, 3); + }); + thread1.join().unwrap(); + thread2.join().unwrap(); +} + +// Test the behaviour of a socketpair getting blocked on write and subsequently unblocked. +fn test_blocking_write() { + let mut fds = [-1, -1]; + let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }; + assert_eq!(res, 0); + let arr1: [u8; 212992] = [1; 212992]; + // Exhaust the space in the buffer so the subsequent write will block. + let res = unsafe { libc::write(fds[0], arr1.as_ptr() as *const libc::c_void, 212992) }; + assert_eq!(res, 212992); + let thread1 = thread::spawn(move || { + let data = "abc".as_bytes().as_ptr(); + // The write below will be blocked because the buffer is already full. + let res = unsafe { libc::write(fds[0], data as *const libc::c_void, 3) }; + assert_eq!(res, 3); + }); + let thread2 = thread::spawn(move || { + // Unblock thread1 by freeing up some space. + let mut buf: [u8; 3] = [0; 3]; + let res = unsafe { libc::read(fds[1], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) }; + assert_eq!(res, 3); + assert_eq!(buf, [1, 1, 1]); + }); + thread1.join().unwrap(); + thread2.join().unwrap(); +} diff --git a/src/tools/miri/tests/pass-dep/libc/libc-time.rs b/src/tools/miri/tests/pass-dep/libc/libc-time.rs index 84dbd8ad768..e53201e0bc5 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-time.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-time.rs @@ -5,7 +5,21 @@ use std::{env, mem, ptr}; fn main() { test_clocks(); test_posix_gettimeofday(); - test_localtime_r(); + test_localtime_r_gmt(); + test_localtime_r_pst(); + test_localtime_r_epoch(); + #[cfg(any( + target_os = "linux", + target_os = "macos", + target_os = "freebsd", + target_os = "android" + ))] + test_localtime_r_multiple_calls_deduplication(); + // Architecture-specific tests. + #[cfg(target_pointer_width = "32")] + test_localtime_r_future_32b(); + #[cfg(target_pointer_width = "64")] + test_localtime_r_future_64b(); } /// Tests whether clock support exists at all @@ -46,14 +60,9 @@ fn test_posix_gettimeofday() { assert_eq!(is_error, -1); } -fn test_localtime_r() { - // Set timezone to GMT. - let key = "TZ"; - env::set_var(key, "GMT"); - - const TIME_SINCE_EPOCH: libc::time_t = 1712475836; - let custom_time_ptr = &TIME_SINCE_EPOCH; - let mut tm = libc::tm { +/// Helper function to create an empty tm struct. +fn create_empty_tm() -> libc::tm { + libc::tm { tm_sec: 0, tm_min: 0, tm_hour: 0, @@ -77,7 +86,17 @@ fn test_localtime_r() { target_os = "android" ))] tm_zone: std::ptr::null_mut::<libc::c_char>(), - }; + } +} + +/// Original GMT test +fn test_localtime_r_gmt() { + // Set timezone to GMT. + let key = "TZ"; + env::set_var(key, "GMT"); + const TIME_SINCE_EPOCH: libc::time_t = 1712475836; // 2024-04-07 07:43:56 GMT + let custom_time_ptr = &TIME_SINCE_EPOCH; + let mut tm = create_empty_tm(); let res = unsafe { libc::localtime_r(custom_time_ptr, &mut tm) }; assert_eq!(tm.tm_sec, 56); @@ -95,20 +114,204 @@ fn test_localtime_r() { target_os = "freebsd", target_os = "android" ))] - assert_eq!(tm.tm_gmtoff, 0); + { + assert_eq!(tm.tm_gmtoff, 0); + unsafe { + assert_eq!(std::ffi::CStr::from_ptr(tm.tm_zone).to_str().unwrap(), "+00"); + } + } + + // The returned value is the pointer passed in. + assert!(ptr::eq(res, &mut tm)); + + // Remove timezone setting. + env::remove_var(key); +} + +/// PST timezone test (testing different timezone handling). +fn test_localtime_r_pst() { + let key = "TZ"; + env::set_var(key, "PST8PDT"); + const TIME_SINCE_EPOCH: libc::time_t = 1712475836; // 2024-04-07 07:43:56 GMT + let custom_time_ptr = &TIME_SINCE_EPOCH; + let mut tm = create_empty_tm(); + + let res = unsafe { libc::localtime_r(custom_time_ptr, &mut tm) }; + + assert_eq!(tm.tm_sec, 56); + assert_eq!(tm.tm_min, 43); + assert_eq!(tm.tm_hour, 0); // 7 - 7 = 0 (PDT offset) + assert_eq!(tm.tm_mday, 7); + assert_eq!(tm.tm_mon, 3); + assert_eq!(tm.tm_year, 124); + assert_eq!(tm.tm_wday, 0); + assert_eq!(tm.tm_yday, 97); + assert_eq!(tm.tm_isdst, -1); // DST information unavailable + #[cfg(any( target_os = "linux", target_os = "macos", target_os = "freebsd", target_os = "android" ))] - unsafe { - assert_eq!(std::ffi::CStr::from_ptr(tm.tm_zone).to_str().unwrap(), "+00") - }; + { + assert_eq!(tm.tm_gmtoff, -7 * 3600); // -7 hours in seconds + unsafe { + assert_eq!(std::ffi::CStr::from_ptr(tm.tm_zone).to_str().unwrap(), "-07"); + } + } - // The returned value is the pointer passed in. assert!(ptr::eq(res, &mut tm)); + env::remove_var(key); +} - // Remove timezone setting. +/// Unix epoch test (edge case testing). +fn test_localtime_r_epoch() { + let key = "TZ"; + env::set_var(key, "GMT"); + const TIME_SINCE_EPOCH: libc::time_t = 0; // 1970-01-01 00:00:00 + let custom_time_ptr = &TIME_SINCE_EPOCH; + let mut tm = create_empty_tm(); + + let res = unsafe { libc::localtime_r(custom_time_ptr, &mut tm) }; + + assert_eq!(tm.tm_sec, 0); + assert_eq!(tm.tm_min, 0); + assert_eq!(tm.tm_hour, 0); + assert_eq!(tm.tm_mday, 1); + assert_eq!(tm.tm_mon, 0); + assert_eq!(tm.tm_year, 70); + assert_eq!(tm.tm_wday, 4); // Thursday + assert_eq!(tm.tm_yday, 0); + assert_eq!(tm.tm_isdst, -1); + + #[cfg(any( + target_os = "linux", + target_os = "macos", + target_os = "freebsd", + target_os = "android" + ))] + { + assert_eq!(tm.tm_gmtoff, 0); + unsafe { + assert_eq!(std::ffi::CStr::from_ptr(tm.tm_zone).to_str().unwrap(), "+00"); + } + } + + assert!(ptr::eq(res, &mut tm)); + env::remove_var(key); +} + +/// Future date test (testing large values). +#[cfg(target_pointer_width = "64")] +fn test_localtime_r_future_64b() { + let key = "TZ"; + env::set_var(key, "GMT"); + + // Using 2050-01-01 00:00:00 for 64-bit systems + // value that's safe for 64-bit time_t + const TIME_SINCE_EPOCH: libc::time_t = 2524608000; + let custom_time_ptr = &TIME_SINCE_EPOCH; + let mut tm = create_empty_tm(); + + let res = unsafe { libc::localtime_r(custom_time_ptr, &mut tm) }; + + assert_eq!(tm.tm_sec, 0); + assert_eq!(tm.tm_min, 0); + assert_eq!(tm.tm_hour, 0); + assert_eq!(tm.tm_mday, 1); + assert_eq!(tm.tm_mon, 0); + assert_eq!(tm.tm_year, 150); // 2050 - 1900 + assert_eq!(tm.tm_wday, 6); // Saturday + assert_eq!(tm.tm_yday, 0); + assert_eq!(tm.tm_isdst, -1); + + #[cfg(any( + target_os = "linux", + target_os = "macos", + target_os = "freebsd", + target_os = "android" + ))] + { + assert_eq!(tm.tm_gmtoff, 0); + unsafe { + assert_eq!(std::ffi::CStr::from_ptr(tm.tm_zone).to_str().unwrap(), "+00"); + } + } + + assert!(ptr::eq(res, &mut tm)); + env::remove_var(key); +} + +/// Future date test (testing large values for 32b target). +#[cfg(target_pointer_width = "32")] +fn test_localtime_r_future_32b() { + let key = "TZ"; + env::set_var(key, "GMT"); + + // Using 2030-01-01 00:00:00 for 32-bit systems + // Safe value within i32 range + const TIME_SINCE_EPOCH: libc::time_t = 1893456000; + let custom_time_ptr = &TIME_SINCE_EPOCH; + let mut tm = create_empty_tm(); + + let res = unsafe { libc::localtime_r(custom_time_ptr, &mut tm) }; + + // Verify 2030-01-01 00:00:00 + assert_eq!(tm.tm_sec, 0); + assert_eq!(tm.tm_min, 0); + assert_eq!(tm.tm_hour, 0); + assert_eq!(tm.tm_mday, 1); + assert_eq!(tm.tm_mon, 0); + assert_eq!(tm.tm_year, 130); // 2030 - 1900 + assert_eq!(tm.tm_wday, 2); // Tuesday + assert_eq!(tm.tm_yday, 0); + assert_eq!(tm.tm_isdst, -1); + + #[cfg(any( + target_os = "linux", + target_os = "macos", + target_os = "freebsd", + target_os = "android" + ))] + { + assert_eq!(tm.tm_gmtoff, 0); + unsafe { + assert_eq!(std::ffi::CStr::from_ptr(tm.tm_zone).to_str().unwrap(), "+00"); + } + } + + assert!(ptr::eq(res, &mut tm)); env::remove_var(key); } + +/// Tests the behavior of `localtime_r` with multiple calls to ensure deduplication of `tm_zone` pointers. +#[cfg(any(target_os = "linux", target_os = "macos", target_os = "freebsd", target_os = "android"))] +fn test_localtime_r_multiple_calls_deduplication() { + let key = "TZ"; + env::set_var(key, "PST8PDT"); + + const TIME_SINCE_EPOCH_BASE: libc::time_t = 1712475836; // Base timestamp: 2024-04-07 07:43:56 GMT + const NUM_CALLS: usize = 50; + + let mut unique_pointers = std::collections::HashSet::new(); + + for i in 0..NUM_CALLS { + let timestamp = TIME_SINCE_EPOCH_BASE + (i as libc::time_t * 3600); // Increment by 1 hour for each call + let mut tm: libc::tm = create_empty_tm(); + let tm_ptr = unsafe { libc::localtime_r(×tamp, &mut tm) }; + + assert!(!tm_ptr.is_null(), "localtime_r failed for timestamp {timestamp}"); + + unique_pointers.insert(tm.tm_zone); + } + + let unique_count = unique_pointers.len(); + + assert!( + unique_count >= 2 && unique_count <= (NUM_CALLS - 1), + "Unexpected number of unique tm_zone pointers: {} (expected between 2 and {})", + unique_count, + NUM_CALLS - 1 + ); +} diff --git a/src/tools/miri/tests/pass/shims/fs.rs b/src/tools/miri/tests/pass/shims/fs.rs index 3e514d95ee9..289c6aa2fce 100644 --- a/src/tools/miri/tests/pass/shims/fs.rs +++ b/src/tools/miri/tests/pass/shims/fs.rs @@ -27,11 +27,8 @@ fn main() { test_file_sync(); test_errors(); test_rename(); - // solarish needs to support readdir/readdir64 for these tests. - if cfg!(not(any(target_os = "solaris", target_os = "illumos"))) { - test_directory(); - test_canonicalize(); - } + test_directory(); + test_canonicalize(); test_from_raw_os_error(); #[cfg(unix)] test_pread_pwrite(); @@ -279,7 +276,12 @@ fn test_directory() { .collect::<BTreeMap<_, _>>() ); // Deleting the directory should fail, since it is not empty. - assert_eq!(ErrorKind::DirectoryNotEmpty, remove_dir(&dir_path).unwrap_err().kind()); + + // Solaris/Illumos `rmdir` call set errno to EEXIST if directory contains + // other entries than `.` and `..`. + // https://docs.oracle.com/cd/E86824_01/html/E54765/rmdir-2.html + let err = remove_dir(&dir_path).unwrap_err().kind(); + assert!(matches!(err, ErrorKind::AlreadyExists | ErrorKind::DirectoryNotEmpty)); // Clean up the files in the directory remove_file(&path_1).unwrap(); remove_file(&path_2).unwrap(); diff --git a/src/tools/miri/triagebot.toml b/src/tools/miri/triagebot.toml index 2d93777f61d..3192882dff6 100644 --- a/src/tools/miri/triagebot.toml +++ b/src/tools/miri/triagebot.toml @@ -29,3 +29,6 @@ review_labels = ["S-waiting-on-review"] remove_labels = ["S-waiting-on-author"] # Those labels are added when PR author requests a review from an assignee add_labels = ["S-waiting-on-review"] + +# Automatically close and reopen PRs made by bots to run CI on them +[bot-pull-requests] diff --git a/src/tools/run-make-support/src/assertion_helpers.rs b/src/tools/run-make-support/src/assertion_helpers.rs index b4da65aff4a..e84a3cf633f 100644 --- a/src/tools/run-make-support/src/assertion_helpers.rs +++ b/src/tools/run-make-support/src/assertion_helpers.rs @@ -5,16 +5,31 @@ use std::path::Path; use crate::{fs, regex}; +fn print<'a, 'e, A: AsRef<str>, E: AsRef<str>>( + assertion_kind: &str, + haystack: &'a A, + needle: &'e E, +) -> (&'a str, &'e str) { + let haystack = haystack.as_ref(); + let needle = needle.as_ref(); + eprintln!("{assertion_kind}:"); + eprintln!("=== HAYSTACK ==="); + eprintln!("{}", haystack); + eprintln!("=== NEEDLE ==="); + eprintln!("{}", needle); + (haystack, needle) +} + /// Assert that `actual` is equal to `expected`. #[track_caller] pub fn assert_equals<A: AsRef<str>, E: AsRef<str>>(actual: A, expected: E) { let actual = actual.as_ref(); let expected = expected.as_ref(); + eprintln!("=== ACTUAL TEXT ==="); + eprintln!("{}", actual); + eprintln!("=== EXPECTED ==="); + eprintln!("{}", expected); if actual != expected { - eprintln!("=== ACTUAL TEXT ==="); - eprintln!("{}", actual); - eprintln!("=== EXPECTED ==="); - eprintln!("{}", expected); panic!("expected text was not found in actual text"); } } @@ -22,13 +37,8 @@ pub fn assert_equals<A: AsRef<str>, E: AsRef<str>>(actual: A, expected: E) { /// Assert that `haystack` contains `needle`. #[track_caller] pub fn assert_contains<H: AsRef<str>, N: AsRef<str>>(haystack: H, needle: N) { - let haystack = haystack.as_ref(); - let needle = needle.as_ref(); + let (haystack, needle) = print("assert_contains", &haystack, &needle); if !haystack.contains(needle) { - eprintln!("=== HAYSTACK ==="); - eprintln!("{}", haystack); - eprintln!("=== NEEDLE ==="); - eprintln!("{}", needle); panic!("needle was not found in haystack"); } } @@ -36,13 +46,8 @@ pub fn assert_contains<H: AsRef<str>, N: AsRef<str>>(haystack: H, needle: N) { /// Assert that `haystack` does not contain `needle`. #[track_caller] pub fn assert_not_contains<H: AsRef<str>, N: AsRef<str>>(haystack: H, needle: N) { - let haystack = haystack.as_ref(); - let needle = needle.as_ref(); + let (haystack, needle) = print("assert_not_contains", &haystack, &needle); if haystack.contains(needle) { - eprintln!("=== HAYSTACK ==="); - eprintln!("{}", haystack); - eprintln!("=== NEEDLE ==="); - eprintln!("{}", needle); panic!("needle was unexpectedly found in haystack"); } } @@ -50,14 +55,9 @@ pub fn assert_not_contains<H: AsRef<str>, N: AsRef<str>>(haystack: H, needle: N) /// Assert that `haystack` contains the regex pattern `needle`. #[track_caller] pub fn assert_contains_regex<H: AsRef<str>, N: AsRef<str>>(haystack: H, needle: N) { - let haystack = haystack.as_ref(); - let needle = needle.as_ref(); + let (haystack, needle) = print("assert_contains_regex", &haystack, &needle); let re = regex::Regex::new(needle).unwrap(); if !re.is_match(haystack) { - eprintln!("=== HAYSTACK ==="); - eprintln!("{}", haystack); - eprintln!("=== NEEDLE ==="); - eprintln!("{}", needle); panic!("needle was not found in haystack"); } } @@ -65,14 +65,9 @@ pub fn assert_contains_regex<H: AsRef<str>, N: AsRef<str>>(haystack: H, needle: /// Assert that `haystack` does not contain the regex pattern `needle`. #[track_caller] pub fn assert_not_contains_regex<H: AsRef<str>, N: AsRef<str>>(haystack: H, needle: N) { - let haystack = haystack.as_ref(); - let needle = needle.as_ref(); + let (haystack, needle) = print("assert_not_contains_regex", &haystack, &needle); let re = regex::Regex::new(needle).unwrap(); if re.is_match(haystack) { - eprintln!("=== HAYSTACK ==="); - eprintln!("{}", haystack); - eprintln!("=== NEEDLE ==="); - eprintln!("{}", needle); panic!("needle was unexpectedly found in haystack"); } } @@ -80,13 +75,8 @@ pub fn assert_not_contains_regex<H: AsRef<str>, N: AsRef<str>>(haystack: H, need /// Assert that `haystack` contains `needle` a `count` number of times. #[track_caller] pub fn assert_count_is<H: AsRef<str>, N: AsRef<str>>(count: usize, haystack: H, needle: N) { - let haystack = haystack.as_ref(); - let needle = needle.as_ref(); + let (haystack, needle) = print("assert_count_is", &haystack, &needle); if count != haystack.matches(needle).count() { - eprintln!("=== HAYSTACK ==="); - eprintln!("{}", haystack); - eprintln!("=== NEEDLE ==="); - eprintln!("{}", needle); panic!("needle did not appear {count} times in haystack"); } } 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 ffe10092cc2..8894ea7fb20 100644 --- a/src/tools/run-make-support/src/external_deps/rustc.rs +++ b/src/tools/run-make-support/src/external_deps/rustc.rs @@ -325,6 +325,12 @@ impl Rustc { self } + /// Pass the `--verbose` flag. + pub fn verbose(&mut self) -> &mut Self { + self.cmd.arg("--verbose"); + self + } + /// `EXTRARSCXXFLAGS` pub fn extra_rs_cxx_flags(&mut self) -> &mut Self { // Adapted from tools.mk (trimmed): diff --git a/src/tools/rust-analyzer/.github/workflows/ci.yaml b/src/tools/rust-analyzer/.github/workflows/ci.yaml index d82e46016dc..46bae20054c 100644 --- a/src/tools/rust-analyzer/.github/workflows/ci.yaml +++ b/src/tools/rust-analyzer/.github/workflows/ci.yaml @@ -220,7 +220,7 @@ jobs: timeout-minutes: 10 env: FORCE_COLOR: 1 - TYPOS_VERSION: v1.18.0 + TYPOS_VERSION: v1.28.3 steps: - name: download typos run: curl -LsSf https://github.com/crate-ci/typos/releases/download/$TYPOS_VERSION/typos-$TYPOS_VERSION-x86_64-unknown-linux-musl.tar.gz | tar zxf - -C ${CARGO_HOME:-~/.cargo}/bin diff --git a/src/tools/rust-analyzer/.typos.toml b/src/tools/rust-analyzer/.typos.toml index febfb233bd9..0f2f9b1b275 100644 --- a/src/tools/rust-analyzer/.typos.toml +++ b/src/tools/rust-analyzer/.typos.toml @@ -16,7 +16,8 @@ extend-ignore-re = [ "raison d'être", "inout", "INOUT", - "optin" + "optin", + "=Pn", ] [default.extend-words] @@ -26,8 +27,12 @@ fo = "fo" ket = "ket" makro = "makro" trivias = "trivias" +thir = "thir" +jod = "jod" [default.extend-identifiers] +anc = "anc" datas = "datas" impl_froms = "impl_froms" selfs = "selfs" +taits = "taits" diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index 8c1d82de1da..ab6580a97a7 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -390,6 +390,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9bda8e21c04aca2ae33ffc2fd8c23134f3cac46db123ba97bd9d3f3b8a4a85e1" [[package]] +name = "edition" +version = "0.0.0" + +[[package]] name = "either" version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1266,6 +1270,7 @@ name = "parser" version = "0.0.0" dependencies = [ "drop_bomb", + "edition", "expect-test", "limit", "ra-ap-rustc_lexer", @@ -2662,6 +2667,7 @@ version = "0.1.0" dependencies = [ "anyhow", "directories", + "edition", "either", "flate2", "itertools", diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml index f7074f91354..8086569a781 100644 --- a/src/tools/rust-analyzer/Cargo.toml +++ b/src/tools/rust-analyzer/Cargo.toml @@ -83,6 +83,7 @@ toolchain = { path = "./crates/toolchain", version = "0.0.0" } tt = { path = "./crates/tt", version = "0.0.0" } vfs-notify = { path = "./crates/vfs-notify", version = "0.0.0" } vfs = { path = "./crates/vfs", version = "0.0.0" } +edition = { path = "./crates/edition", version = "0.0.0" } ra-ap-rustc_lexer = { version = "0.85", default-features = false } ra-ap-rustc_parse_format = { version = "0.85", default-features = false } diff --git a/src/tools/rust-analyzer/crates/edition/Cargo.toml b/src/tools/rust-analyzer/crates/edition/Cargo.toml new file mode 100644 index 00000000000..926b1e1cd41 --- /dev/null +++ b/src/tools/rust-analyzer/crates/edition/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "edition" +version = "0.0.0" +rust-version.workspace = true +edition.workspace = true +license.workspace = true +authors.workspace = true +repository.workspace = true + +[dependencies] + +[lints] +workspace = true diff --git a/src/tools/rust-analyzer/crates/parser/src/edition.rs b/src/tools/rust-analyzer/crates/edition/src/lib.rs index 702b16252d4..c25d5b9557b 100644 --- a/src/tools/rust-analyzer/crates/parser/src/edition.rs +++ b/src/tools/rust-analyzer/crates/edition/src/lib.rs @@ -1,6 +1,5 @@ //! The edition of the Rust language used in a crate. -// Ideally this would be defined in the span crate, but the dependency chain is all over the place -// wrt to span, parser and syntax. +// This should live in a separate crate because we use it in both actual code and codegen. use std::fmt; #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs index 4894c7a9311..b76db2e0052 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs @@ -74,7 +74,7 @@ impl BuiltinFnLikeExpander { } pub fn is_asm(&self) -> bool { - matches!(self, Self::Asm | Self::GlobalAsm) + matches!(self, Self::Asm | Self::GlobalAsm | Self::NakedAsm) } } @@ -122,6 +122,7 @@ register_builtin! { (stringify, Stringify) => stringify_expand, (asm, Asm) => asm_expand, (global_asm, GlobalAsm) => asm_expand, + (naked_asm, NakedAsm) => asm_expand, (cfg, Cfg) => cfg_expand, (core_panic, CorePanic) => panic_expand, (std_panic, StdPanic) => panic_expand, diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs index 9a7a1a01a09..2bba410de02 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs @@ -237,7 +237,7 @@ pub const INERT_ATTRIBUTES: &[BuiltinAttribute] = &[ template!(List: "address, kcfi, memory, thread"), DuplicatesOk, experimental!(no_sanitize) ), - gated!(coverage, Normal, template!(Word, List: "on|off"), WarnFollowing, coverage_attribute, experimental!(coverage)), + ungated!(coverage, Normal, template!(Word, List: "on|off"), WarnFollowing), ungated!( doc, Normal, template!(List: "hidden|inline|...", NameValueStr: "string"), DuplicatesOk diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs index 2ee598dfbfd..5aafe6db527 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs @@ -28,6 +28,7 @@ use rustc_hash::FxHashMap; use stdx::TupleExt; use triomphe::Arc; +use core::fmt; use std::hash::Hash; use base_db::{ra_salsa::InternValueTrivial, CrateId}; @@ -147,6 +148,10 @@ impl ExpandError { pub fn span(&self) -> Span { self.inner.1 } + + pub fn render_to_string(&self, db: &dyn ExpandDatabase) -> RenderedExpandError { + self.inner.0.render_to_string(db) + } } #[derive(Debug, PartialEq, Eq, Clone, Hash)] @@ -164,18 +169,18 @@ pub enum ExpandErrorKind { ProcMacroPanic(Box<str>), } -impl ExpandError { - pub fn render_to_string(&self, db: &dyn ExpandDatabase) -> RenderedExpandError { - self.inner.0.render_to_string(db) - } -} - pub struct RenderedExpandError { pub message: String, pub error: bool, pub kind: &'static str, } +impl fmt::Display for RenderedExpandError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.message) + } +} + impl RenderedExpandError { const GENERAL_KIND: &str = "macro-error"; } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs index 3dfa0e97cec..de8ce56df64 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs @@ -1053,8 +1053,21 @@ impl HirDisplay for Ty { generic_args_sans_defaults(f, Some(generic_def_id), parameters); assert!(params_len >= parameters.len()); let defaults = params_len - parameters.len(); - let without_impl = - self_param as usize + type_ + const_ + lifetime - defaults; + + // Normally, functions cannot have default parameters, but they can, + // for function-like things such as struct names or enum variants. + // The former cannot have defaults but parents, and the later cannot have + // parents but defaults. + // So, if `parent_len` > 0, it have a parent and thus it doesn't have any + // default. Therefore, we shouldn't subtract defaults because those defaults + // are from their parents. + // And if `parent_len` == 0, either parents don't exists or they don't have + // any defaults. Thus, we can - and should - subtract defaults. + let without_impl = if parent_len > 0 { + params_len - parent_len - impl_ + } else { + params_len - parent_len - impl_ - defaults + }; // parent's params (those from enclosing impl or trait, if any). let (fn_params, parent_params) = parameters.split_at(without_impl + impl_); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/interner.rs b/src/tools/rust-analyzer/crates/hir-ty/src/interner.rs index 3dbefc5cec8..804c3aea3a5 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/interner.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/interner.rs @@ -55,7 +55,7 @@ impl chalk_ir::interner::Interner for Interner { type InternedConst = Interned<InternedWrapper<ConstData>>; type InternedConcreteConst = ConstScalar; type InternedGenericArg = GenericArgData; - // We could do the following, but that saves "only" 20mb on self while increasing inferecene + // We could do the following, but that saves "only" 20mb on self while increasing inference // time by ~2.5% // type InternedGoal = Interned<InternedWrapper<GoalData>>; type InternedGoal = Arc<GoalData>; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs index d7029651fc1..e3072d6ee79 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs @@ -813,7 +813,7 @@ impl Evaluator<'_> { ProjectionElem::Field(Either::Left(f)) => { let layout = self.layout(&prev_ty)?; let variant_layout = match &layout.variants { - Variants::Single { .. } => &layout, + Variants::Single { .. } | Variants::Empty => &layout, Variants::Multiple { variants, .. } => { &variants[match f.parent { hir_def::VariantId::EnumVariantId(it) => { @@ -1638,6 +1638,7 @@ impl Evaluator<'_> { return Ok(0); }; match &layout.variants { + Variants::Empty => unreachable!(), Variants::Single { index } => { let r = self.const_eval_discriminant(self.db.enum_data(e).variants[index.0].0)?; Ok(r) @@ -1800,7 +1801,7 @@ impl Evaluator<'_> { } let layout = self.layout_adt(adt, subst)?; Ok(match &layout.variants { - Variants::Single { .. } => (layout.size.bytes_usize(), layout, None), + Variants::Single { .. } | Variants::Empty => (layout.size.bytes_usize(), layout, None), Variants::Multiple { variants, tag, tag_encoding, .. } => { let enum_variant_id = match it { VariantId::EnumVariantId(it) => it, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs index e15d44bd6de..dda7bfb2baf 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs @@ -4380,7 +4380,7 @@ fn test() { fn associated_type_in_struct_expr_path() { // FIXME: All annotation should be resolvable. // For lines marked as unstable, see rust-lang/rust#86935. - // FIXME: Remove the comments once stablized. + // FIXME: Remove the comments once stabilized. check_types( r#" trait Trait { @@ -4416,7 +4416,7 @@ impl Trait for () { fn associated_type_in_struct_expr_path_enum() { // FIXME: All annotation should be resolvable. // For lines marked as unstable, see rust-lang/rust#86935. - // FIXME: Remove the comments once stablized. + // FIXME: Remove the comments once stabilized. check_types( r#" trait Trait { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs b/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs index 06719b09f73..42e7edaf0f4 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs @@ -334,6 +334,7 @@ pub(crate) fn detect_variant_from_bytes<'a>( e: EnumId, ) -> Option<(EnumVariantId, &'a Layout)> { let (var_id, var_layout) = match &layout.variants { + hir_def::layout::Variants::Empty => unreachable!(), hir_def::layout::Variants::Single { index } => { (db.enum_data(e).variants[index.0].0, layout) } diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index 83d72dfcf14..3bc2eee1e7c 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -2649,24 +2649,31 @@ impl Const { Type::from_value_def(db, self.id) } - /// Evaluate the constant and return the result as a string. - /// - /// This function is intended for IDE assistance, different from [`Const::render_eval`]. - pub fn eval(self, db: &dyn HirDatabase) -> Result<String, ConstEvalError> { - let c = db.const_eval(self.id.into(), Substitution::empty(Interner), None)?; - Ok(format!("{}", c.display(db, self.krate(db).edition(db)))) + /// Evaluate the constant. + pub fn eval(self, db: &dyn HirDatabase) -> Result<EvaluatedConst, ConstEvalError> { + db.const_eval(self.id.into(), Substitution::empty(Interner), None) + .map(|it| EvaluatedConst { const_: it, def: self.id.into() }) } +} - /// Evaluate the constant and return the result as a string, with more detailed information. - /// - /// This function is intended for user-facing display. - pub fn render_eval( - self, - db: &dyn HirDatabase, - edition: Edition, - ) -> Result<String, ConstEvalError> { - let c = db.const_eval(self.id.into(), Substitution::empty(Interner), None)?; - let data = &c.data(Interner); +impl HasVisibility for Const { + fn visibility(&self, db: &dyn HirDatabase) -> Visibility { + db.const_visibility(self.id) + } +} + +pub struct EvaluatedConst { + def: DefWithBodyId, + const_: hir_ty::Const, +} + +impl EvaluatedConst { + pub fn render(&self, db: &dyn HirDatabase, edition: Edition) -> String { + format!("{}", self.const_.display(db, edition)) + } + + pub fn render_debug(&self, db: &dyn HirDatabase) -> Result<String, MirEvalError> { + let data = self.const_.data(Interner); if let TyKind::Scalar(s) = data.ty.kind(Interner) { if matches!(s, Scalar::Int(_) | Scalar::Uint(_)) { if let hir_ty::ConstValue::Concrete(c) = &data.value { @@ -2689,17 +2696,7 @@ impl Const { } } } - if let Ok(s) = mir::render_const_using_debug_impl(db, self.id.into(), &c) { - Ok(s) - } else { - Ok(format!("{}", c.display(db, edition))) - } - } -} - -impl HasVisibility for Const { - fn visibility(&self, db: &dyn HirDatabase) -> Visibility { - db.const_visibility(self.id) + mir::render_const_using_debug_impl(db, self.def, &self.const_) } } @@ -2729,51 +2726,10 @@ impl Static { Type::from_value_def(db, self.id) } - /// Evaluate the static and return the result as a string. - /// - /// This function is intended for IDE assistance, different from [`Static::render_eval`]. - pub fn eval(self, db: &dyn HirDatabase) -> Result<String, ConstEvalError> { - let c = db.const_eval(self.id.into(), Substitution::empty(Interner), None)?; - Ok(format!("{}", c.display(db, self.krate(db).edition(db)))) - } - - /// Evaluate the static and return the result as a string, with more detailed information. - /// - /// This function is intended for user-facing display. - pub fn render_eval( - self, - db: &dyn HirDatabase, - edition: Edition, - ) -> Result<String, ConstEvalError> { - let c = db.const_eval(self.id.into(), Substitution::empty(Interner), None)?; - let data = &c.data(Interner); - if let TyKind::Scalar(s) = data.ty.kind(Interner) { - if matches!(s, Scalar::Int(_) | Scalar::Uint(_)) { - if let hir_ty::ConstValue::Concrete(c) = &data.value { - if let hir_ty::ConstScalar::Bytes(b, _) = &c.interned { - let value = u128::from_le_bytes(mir::pad16(b, false)); - let value_signed = - i128::from_le_bytes(mir::pad16(b, matches!(s, Scalar::Int(_)))); - let mut result = if let Scalar::Int(_) = s { - value_signed.to_string() - } else { - value.to_string() - }; - if value >= 10 { - format_to!(result, " ({value:#X})"); - return Ok(result); - } else { - return Ok(result); - } - } - } - } - } - if let Ok(s) = mir::render_const_using_debug_impl(db, self.id.into(), &c) { - Ok(s) - } else { - Ok(format!("{}", c.display(db, edition))) - } + /// Evaluate the static initializer. + pub fn eval(self, db: &dyn HirDatabase) -> Result<EvaluatedConst, ConstEvalError> { + db.const_eval(self.id.into(), Substitution::empty(Interner), None) + .map(|it| EvaluatedConst { const_: it, def: self.id.into() }) } } diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs index f9d3f9d07e6..b896cda9ddf 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs @@ -28,7 +28,7 @@ use hir_expand::{ hygiene::SyntaxContextExt as _, inert_attr_macro::find_builtin_attr_idx, name::AsName, - FileRange, InMacroFile, MacroCallId, MacroFileId, MacroFileIdExt, + ExpandResult, FileRange, InMacroFile, MacroCallId, MacroFileId, MacroFileIdExt, }; use intern::Symbol; use itertools::Itertools; @@ -381,7 +381,13 @@ impl<'db> SemanticsImpl<'db> { node } - pub fn expand(&self, macro_call: &ast::MacroCall) -> Option<SyntaxNode> { + pub fn expand(&self, file_id: MacroFileId) -> ExpandResult<SyntaxNode> { + let res = self.db.parse_macro_expansion(file_id).map(|it| it.0.syntax_node()); + self.cache(res.value.clone(), file_id.into()); + res + } + + pub fn expand_macro_call(&self, macro_call: &ast::MacroCall) -> Option<SyntaxNode> { let sa = self.analyze_no_infer(macro_call.syntax())?; let macro_call = InFile::new(sa.file_id, macro_call); @@ -412,7 +418,10 @@ impl<'db> SemanticsImpl<'db> { /// Expands the macro if it isn't one of the built-in ones that expand to custom syntax or dummy /// expansions. - pub fn expand_allowed_builtins(&self, macro_call: &ast::MacroCall) -> Option<SyntaxNode> { + pub fn expand_allowed_builtins( + &self, + macro_call: &ast::MacroCall, + ) -> Option<ExpandResult<SyntaxNode>> { let sa = self.analyze_no_infer(macro_call.syntax())?; let macro_call = InFile::new(sa.file_id, macro_call); @@ -434,6 +443,7 @@ impl<'db> SemanticsImpl<'db> { | BuiltinFnLikeExpander::ModulePath | BuiltinFnLikeExpander::Asm | BuiltinFnLikeExpander::GlobalAsm + | BuiltinFnLikeExpander::NakedAsm | BuiltinFnLikeExpander::LogSyntax | BuiltinFnLikeExpander::TraceMacros | BuiltinFnLikeExpander::FormatArgs @@ -447,15 +457,15 @@ impl<'db> SemanticsImpl<'db> { return None; } - let node = self.parse_or_expand(file_id.into()); + let node = self.expand(file_id); Some(node) } /// If `item` has an attribute macro attached to it, expands it. - pub fn expand_attr_macro(&self, item: &ast::Item) -> Option<SyntaxNode> { + pub fn expand_attr_macro(&self, item: &ast::Item) -> Option<ExpandResult<SyntaxNode>> { let src = self.wrap_node_infile(item.clone()); let macro_call_id = self.with_ctx(|ctx| ctx.item_to_macro_call(src.as_ref()))?; - Some(self.parse_or_expand(macro_call_id.as_file())) + Some(self.expand(macro_call_id.as_macro_file())) } pub fn expand_derive_as_pseudo_attr_macro(&self, attr: &ast::Attr) -> Option<SyntaxNode> { @@ -479,15 +489,16 @@ impl<'db> SemanticsImpl<'db> { }) } - pub fn expand_derive_macro(&self, attr: &ast::Attr) -> Option<Vec<SyntaxNode>> { + pub fn expand_derive_macro(&self, attr: &ast::Attr) -> Option<Vec<ExpandResult<SyntaxNode>>> { let res: Vec<_> = self .derive_macro_calls(attr)? .into_iter() .flat_map(|call| { - let file_id = call?.as_file(); - let node = self.db.parse_or_expand(file_id); - self.cache(node.clone(), file_id); - Some(node) + let file_id = call?.as_macro_file(); + let ExpandResult { value, err } = self.db.parse_macro_expansion(file_id); + let root_node = value.0.syntax_node(); + self.cache(root_node.clone(), file_id.into()); + Some(ExpandResult { value: root_node, err }) }) .collect(); Some(res) @@ -555,7 +566,7 @@ impl<'db> SemanticsImpl<'db> { /// Expand the macro call with a different token tree, mapping the `token_to_map` down into the /// expansion. `token_to_map` should be a token from the `speculative args` node. - pub fn speculative_expand( + pub fn speculative_expand_macro_call( &self, actual_macro_call: &ast::MacroCall, speculative_args: &ast::TokenTree, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs index 6937d33ebc1..438769a0a87 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs @@ -7,6 +7,7 @@ use hir::{ TypeInfo, TypeParam, }; use ide_db::{ + assists::GroupLabel, defs::{Definition, NameRefClass}, famous_defs::FamousDefs, helpers::mod_path_to_ast, @@ -104,7 +105,8 @@ pub(crate) fn extract_function(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op let scope = ImportScope::find_insert_use_container(&node, &ctx.sema)?; - acc.add( + acc.add_group( + &GroupLabel("Extract into...".to_owned()), AssistId("extract_function", crate::AssistKind::RefactorExtract), "Extract into function", target_range, @@ -5009,7 +5011,7 @@ fn $0fun_name(bar: &str) { } #[test] - fn unresolveable_types_default_to_placeholder() { + fn unresolvable_types_default_to_placeholder() { check_assist( extract_function, r#" diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs index 61dc72e0b33..a8d71ed7f4d 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs @@ -1,17 +1,15 @@ -use hir::TypeInfo; -use ide_db::syntax_helpers::suggest_name; +use hir::{HirDisplay, TypeInfo}; +use ide_db::{assists::GroupLabel, syntax_helpers::suggest_name}; use syntax::{ ast::{ self, edit::IndentLevel, edit_in_place::Indent, make, syntax_factory::SyntaxFactory, AstNode, }, syntax_editor::Position, - NodeOrToken, - SyntaxKind::{BLOCK_EXPR, BREAK_EXPR, COMMENT, LOOP_EXPR, MATCH_GUARD, PATH_EXPR, RETURN_EXPR}, - SyntaxNode, T, + NodeOrToken, SyntaxKind, SyntaxNode, T, }; -use crate::{AssistContext, AssistId, AssistKind, Assists}; +use crate::{utils::is_body_const, AssistContext, AssistId, AssistKind, Assists}; // Assist: extract_variable // @@ -29,6 +27,40 @@ use crate::{AssistContext, AssistId, AssistKind, Assists}; // var_name * 4; // } // ``` + +// Assist: extract_constant +// +// Extracts subexpression into a constant. +// +// ``` +// fn main() { +// $0(1 + 2)$0 * 4; +// } +// ``` +// -> +// ``` +// fn main() { +// const $0VAR_NAME: i32 = 1 + 2; +// VAR_NAME * 4; +// } +// ``` + +// Assist: extract_static +// +// Extracts subexpression into a static. +// +// ``` +// fn main() { +// $0(1 + 2)$0 * 4; +// } +// ``` +// -> +// ``` +// fn main() { +// static $0VAR_NAME: i32 = 1 + 2; +// VAR_NAME * 4; +// } +// ``` pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { let node = if ctx.has_empty_selection() { if let Some(t) = ctx.token_at_offset().find(|it| it.kind() == T![;]) { @@ -41,7 +73,7 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op } else { match ctx.covering_element() { NodeOrToken::Node(it) => it, - NodeOrToken::Token(it) if it.kind() == COMMENT => { + NodeOrToken::Token(it) if it.kind() == SyntaxKind::COMMENT => { cov_mark::hit!(extract_var_in_comment_is_not_applicable); return None; } @@ -87,116 +119,150 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op } _ => false, }; - - let anchor = Anchor::from(&to_extract)?; + let module = ctx.sema.scope(to_extract.syntax())?.module(); let target = to_extract.syntax().text_range(); - acc.add( - AssistId("extract_variable", AssistKind::RefactorExtract), - "Extract into variable", - target, - move |edit| { - let field_shorthand = to_extract - .syntax() - .parent() - .and_then(ast::RecordExprField::cast) - .filter(|field| field.name_ref().is_some()); - - let (var_name, expr_replace) = match field_shorthand { - Some(field) => (field.to_string(), field.syntax().clone()), - None => ( - suggest_name::for_variable(&to_extract, &ctx.sema), - to_extract.syntax().clone(), - ), - }; - - let make = SyntaxFactory::new(); - let mut editor = edit.make_editor(&expr_replace); - - let pat_name = make.name(&var_name); - let name_expr = make.expr_path(make::ext::ident_path(&var_name)); - - if let Some(cap) = ctx.config.snippet_cap { - let tabstop = edit.make_tabstop_before(cap); - editor.add_annotation(pat_name.syntax().clone(), tabstop); - } + let needs_mut = match &parent { + Some(ast::Expr::RefExpr(expr)) => expr.mut_token().is_some(), + _ => needs_adjust && !needs_ref && ty.as_ref().is_some_and(|ty| ty.is_mutable_reference()), + }; + for kind in ExtractionKind::ALL { + let Some(anchor) = Anchor::from(&to_extract, kind) else { + continue; + }; - let ident_pat = match parent { - Some(ast::Expr::RefExpr(expr)) if expr.mut_token().is_some() => { - make.ident_pat(false, true, pat_name) - } - _ if needs_adjust - && !needs_ref - && ty.as_ref().is_some_and(|ty| ty.is_mutable_reference()) => + let ty_string = match kind { + ExtractionKind::Constant | ExtractionKind::Static => { + let Some(ty) = ty.clone() else { + continue; + }; + + // We can't mutably reference a const, nor can we define + // one using a non-const expression or one of unknown type + if needs_mut + || !is_body_const(&ctx.sema, &to_extract_no_ref) + || ty.is_unknown() + || ty.is_mutable_reference() { - make.ident_pat(false, true, pat_name) + continue; } - _ => make.ident_pat(false, false, pat_name), - }; - let to_extract_no_ref = match ty.as_ref().filter(|_| needs_ref) { - Some(receiver_type) if receiver_type.is_mutable_reference() => { - make.expr_ref(to_extract_no_ref, true) - } - Some(receiver_type) if receiver_type.is_reference() => { - make.expr_ref(to_extract_no_ref, false) - } - _ => to_extract_no_ref, - }; - - let let_stmt = make.let_stmt(ident_pat.into(), None, Some(to_extract_no_ref)); - - match anchor { - Anchor::Before(place) => { - let prev_ws = place.prev_sibling_or_token().and_then(|it| it.into_token()); - let indent_to = IndentLevel::from_node(&place); - - // Adjust ws to insert depending on if this is all inline or on separate lines - let trailing_ws = if prev_ws.is_some_and(|it| it.text().starts_with('\n')) { - format!("\n{indent_to}") - } else { - " ".to_owned() - }; - - editor.insert_all( - Position::before(place), - vec![ - let_stmt.syntax().clone().into(), - make::tokens::whitespace(&trailing_ws).into(), - ], - ); - - editor.replace(expr_replace, name_expr.syntax()); - } - Anchor::Replace(stmt) => { - cov_mark::hit!(test_extract_var_expr_stmt); + let Ok(type_string) = ty.display_source_code(ctx.db(), module.into(), false) else { + continue; + }; + + type_string + } + _ => "".to_owned(), + }; + + acc.add_group( + &GroupLabel("Extract into...".to_owned()), + kind.assist_id(), + kind.label(), + target, + |edit| { + let (var_name, expr_replace) = kind.get_name_and_expr(ctx, &to_extract); + + let make = SyntaxFactory::new(); + let mut editor = edit.make_editor(&expr_replace); - editor.replace(stmt.syntax(), let_stmt.syntax()); + let pat_name = make.name(&var_name); + let name_expr = make.expr_path(make::ext::ident_path(&var_name)); + + if let Some(cap) = ctx.config.snippet_cap { + let tabstop = edit.make_tabstop_before(cap); + editor.add_annotation(pat_name.syntax().clone(), tabstop); } - Anchor::WrapInBlock(to_wrap) => { - let indent_to = to_wrap.indent_level(); - - let block = if to_wrap.syntax() == &expr_replace { - // Since `expr_replace` is the same that needs to be wrapped in a block, - // we can just directly replace it with a block - make.block_expr([let_stmt.into()], Some(name_expr)) - } else { - // `expr_replace` is a descendant of `to_wrap`, so we just replace it with `name_expr`. + + let initializer = match ty.as_ref().filter(|_| needs_ref) { + Some(receiver_type) if receiver_type.is_mutable_reference() => { + make.expr_ref(to_extract_no_ref.clone(), true) + } + Some(receiver_type) if receiver_type.is_reference() => { + make.expr_ref(to_extract_no_ref.clone(), false) + } + _ => to_extract_no_ref.clone(), + }; + + let new_stmt: ast::Stmt = match kind { + ExtractionKind::Variable => { + let ident_pat = make.ident_pat(false, needs_mut, pat_name); + make.let_stmt(ident_pat.into(), None, Some(initializer)).into() + } + ExtractionKind::Constant => { + let ast_ty = make.ty(&ty_string); + ast::Item::Const(make.item_const(None, pat_name, ast_ty, initializer)) + .into() + } + ExtractionKind::Static => { + let ast_ty = make.ty(&ty_string); + ast::Item::Static(make.item_static( + None, + false, + false, + pat_name, + ast_ty, + Some(initializer), + )) + .into() + } + }; + + match &anchor { + Anchor::Before(place) => { + let prev_ws = place.prev_sibling_or_token().and_then(|it| it.into_token()); + let indent_to = IndentLevel::from_node(place); + + // Adjust ws to insert depending on if this is all inline or on separate lines + let trailing_ws = if prev_ws.is_some_and(|it| it.text().starts_with('\n')) { + format!("\n{indent_to}") + } else { + " ".to_owned() + }; + + editor.insert_all( + Position::before(place), + vec![ + new_stmt.syntax().clone().into(), + make::tokens::whitespace(&trailing_ws).into(), + ], + ); + editor.replace(expr_replace, name_expr.syntax()); - make.block_expr([let_stmt.into()], Some(to_wrap.clone())) - }; + } + Anchor::Replace(stmt) => { + cov_mark::hit!(test_extract_var_expr_stmt); + + editor.replace(stmt.syntax(), new_stmt.syntax()); + } + Anchor::WrapInBlock(to_wrap) => { + let indent_to = to_wrap.indent_level(); + + let block = if to_wrap.syntax() == &expr_replace { + // Since `expr_replace` is the same that needs to be wrapped in a block, + // we can just directly replace it with a block + make.block_expr([new_stmt], Some(name_expr)) + } else { + // `expr_replace` is a descendant of `to_wrap`, so we just replace it with `name_expr`. + editor.replace(expr_replace, name_expr.syntax()); + make.block_expr([new_stmt], Some(to_wrap.clone())) + }; - editor.replace(to_wrap.syntax(), block.syntax()); + editor.replace(to_wrap.syntax(), block.syntax()); - // fixup indentation of block - block.indent(indent_to); + // fixup indentation of block + block.indent(indent_to); + } } - } - editor.add_mappings(make.finish_with_mappings()); - edit.add_file_edits(ctx.file_id(), editor); - edit.rename(); - }, - ) + editor.add_mappings(make.finish_with_mappings()); + edit.add_file_edits(ctx.file_id(), editor); + edit.rename(); + }, + ); + } + + Some(()) } fn peel_parens(mut expr: ast::Expr) -> ast::Expr { @@ -211,17 +277,71 @@ fn peel_parens(mut expr: ast::Expr) -> ast::Expr { /// In general that's true for any expression, but in some cases that would produce invalid code. fn valid_target_expr(node: SyntaxNode) -> Option<ast::Expr> { match node.kind() { - PATH_EXPR | LOOP_EXPR => None, - BREAK_EXPR => ast::BreakExpr::cast(node).and_then(|e| e.expr()), - RETURN_EXPR => ast::ReturnExpr::cast(node).and_then(|e| e.expr()), - BLOCK_EXPR => { + SyntaxKind::PATH_EXPR | SyntaxKind::LOOP_EXPR => None, + SyntaxKind::BREAK_EXPR => ast::BreakExpr::cast(node).and_then(|e| e.expr()), + SyntaxKind::RETURN_EXPR => ast::ReturnExpr::cast(node).and_then(|e| e.expr()), + SyntaxKind::BLOCK_EXPR => { ast::BlockExpr::cast(node).filter(|it| it.is_standalone()).map(ast::Expr::from) } _ => ast::Expr::cast(node), } } -#[derive(Debug)] +enum ExtractionKind { + Variable, + Constant, + Static, +} + +impl ExtractionKind { + const ALL: &'static [ExtractionKind] = + &[ExtractionKind::Variable, ExtractionKind::Constant, ExtractionKind::Static]; + + fn assist_id(&self) -> AssistId { + let s = match self { + ExtractionKind::Variable => "extract_variable", + ExtractionKind::Constant => "extract_constant", + ExtractionKind::Static => "extract_static", + }; + + AssistId(s, AssistKind::RefactorExtract) + } + + fn label(&self) -> &'static str { + match self { + ExtractionKind::Variable => "Extract into variable", + ExtractionKind::Constant => "Extract into constant", + ExtractionKind::Static => "Extract into static", + } + } + + fn get_name_and_expr( + &self, + ctx: &AssistContext<'_>, + to_extract: &ast::Expr, + ) -> (String, SyntaxNode) { + let field_shorthand = to_extract + .syntax() + .parent() + .and_then(ast::RecordExprField::cast) + .filter(|field| field.name_ref().is_some()); + let (var_name, expr_replace) = match field_shorthand { + Some(field) => (field.to_string(), field.syntax().clone()), + None => { + (suggest_name::for_variable(to_extract, &ctx.sema), to_extract.syntax().clone()) + } + }; + + let var_name = match self { + ExtractionKind::Variable => var_name, + ExtractionKind::Constant | ExtractionKind::Static => var_name.to_uppercase(), + }; + + (var_name, expr_replace) + } +} + +#[derive(Debug, Clone)] enum Anchor { Before(SyntaxNode), Replace(ast::ExprStmt), @@ -229,8 +349,8 @@ enum Anchor { } impl Anchor { - fn from(to_extract: &ast::Expr) -> Option<Anchor> { - to_extract + fn from(to_extract: &ast::Expr, kind: &ExtractionKind) -> Option<Anchor> { + let result = to_extract .syntax() .ancestors() .take_while(|it| !ast::Item::can_cast(it.kind()) || ast::MacroCall::can_cast(it.kind())) @@ -253,7 +373,7 @@ impl Anchor { return parent.body().map(Anchor::WrapInBlock); } if let Some(parent) = ast::MatchArm::cast(parent) { - if node.kind() == MATCH_GUARD { + if node.kind() == SyntaxKind::MATCH_GUARD { cov_mark::hit!(test_extract_var_in_match_guard); } else { cov_mark::hit!(test_extract_var_in_match_arm_no_block); @@ -271,19 +391,42 @@ impl Anchor { return Some(Anchor::Before(node)); } None - }) + }); + + match kind { + ExtractionKind::Constant | ExtractionKind::Static if result.is_none() => { + to_extract.syntax().ancestors().find_map(|node| { + let item = ast::Item::cast(node.clone())?; + let parent = item.syntax().parent()?; + match parent.kind() { + SyntaxKind::ITEM_LIST + | SyntaxKind::SOURCE_FILE + | SyntaxKind::ASSOC_ITEM_LIST + | SyntaxKind::STMT_LIST => Some(Anchor::Before(node)), + _ => None, + } + }) + } + _ => result, + } } } #[cfg(test)] mod tests { - use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target}; + // NOTE: We use check_assist_by_label, but not check_assist_not_applicable_by_label + // because all of our not-applicable tests should behave that way for both assists + // extract_variable offers, and check_assist_not_applicable ensures neither is offered + use crate::tests::{ + check_assist_by_label, check_assist_not_applicable, check_assist_not_applicable_by_label, + check_assist_target, + }; use super::*; #[test] - fn test_extract_var_simple_without_select() { - check_assist( + fn extract_var_simple_without_select() { + check_assist_by_label( extract_variable, r#" fn main() -> i32 { @@ -304,9 +447,10 @@ fn main() -> i32 { var_name } "#, + "Extract into variable", ); - check_assist( + check_assist_by_label( extract_variable, r#" fn foo() -> i32 { 1 } @@ -320,9 +464,10 @@ fn main() { let $0foo = foo(); } "#, + "Extract into variable", ); - check_assist( + check_assist_by_label( extract_variable, r#" fn main() { @@ -336,9 +481,10 @@ fn main() { let $0is_some = a.is_some(); } "#, + "Extract into variable", ); - check_assist( + check_assist_by_label( extract_variable, r#" fn main() { @@ -350,9 +496,10 @@ fn main() { let $0var_name = "hello"; } "#, + "Extract into variable", ); - check_assist( + check_assist_by_label( extract_variable, r#" fn main() { @@ -364,9 +511,10 @@ fn main() { let $0var_name = 1 + 2; } "#, + "Extract into variable", ); - check_assist( + check_assist_by_label( extract_variable, r#" fn main() { @@ -384,11 +532,202 @@ fn main() { }; } "#, + "Extract into variable", + ); + } + + #[test] + fn extract_const_simple_without_select() { + check_assist_by_label( + extract_variable, + r#" +fn main() -> i32 { + if true { + 1 + } else { + 2 + }$0 +} +"#, + r#" +fn main() -> i32 { + const $0VAR_NAME: i32 = if true { + 1 + } else { + 2 + }; + VAR_NAME +} +"#, + "Extract into constant", + ); + + check_assist_by_label( + extract_variable, + r#" +const fn foo() -> i32 { 1 } +fn main() { + foo();$0 +} +"#, + r#" +const fn foo() -> i32 { 1 } +fn main() { + const $0FOO: i32 = foo(); +} +"#, + "Extract into constant", + ); + + check_assist_by_label( + extract_variable, + r#" +fn main() { + "hello"$0; +} +"#, + r#" +fn main() { + const $0VAR_NAME: &str = "hello"; +} +"#, + "Extract into constant", + ); + + check_assist_by_label( + extract_variable, + r#" +fn main() { + 1 + 2$0; +} +"#, + r#" +fn main() { + const $0VAR_NAME: i32 = 1 + 2; +} +"#, + "Extract into constant", + ); + + check_assist_by_label( + extract_variable, + r#" +fn main() { + match () { + () if true => 1, + _ => 2, + };$0 +} +"#, + r#" +fn main() { + const $0VAR_NAME: i32 = match () { + () if true => 1, + _ => 2, + }; +} +"#, + "Extract into constant", + ); + } + + #[test] + fn extract_static_simple_without_select() { + check_assist_by_label( + extract_variable, + r#" +fn main() -> i32 { + if true { + 1 + } else { + 2 + }$0 +} +"#, + r#" +fn main() -> i32 { + static $0VAR_NAME: i32 = if true { + 1 + } else { + 2 + }; + VAR_NAME +} +"#, + "Extract into static", + ); + + check_assist_by_label( + extract_variable, + r#" +const fn foo() -> i32 { 1 } +fn main() { + foo();$0 +} +"#, + r#" +const fn foo() -> i32 { 1 } +fn main() { + static $0FOO: i32 = foo(); +} +"#, + "Extract into static", + ); + + check_assist_by_label( + extract_variable, + r#" +fn main() { + "hello"$0; +} +"#, + r#" +fn main() { + static $0VAR_NAME: &str = "hello"; +} +"#, + "Extract into static", + ); + + check_assist_by_label( + extract_variable, + r#" +fn main() { + 1 + 2$0; +} +"#, + r#" +fn main() { + static $0VAR_NAME: i32 = 1 + 2; +} +"#, + "Extract into static", + ); + + check_assist_by_label( + extract_variable, + r#" +fn main() { + match () { + () if true => 1, + _ => 2, + };$0 +} +"#, + r#" +fn main() { + static $0VAR_NAME: i32 = match () { + () if true => 1, + _ => 2, + }; +} +"#, + "Extract into static", ); } #[test] - fn test_extract_var_unit_expr_without_select_not_applicable() { + fn dont_extract_unit_expr_without_select() { check_assist_not_applicable( extract_variable, r#" @@ -414,8 +753,8 @@ fn foo() { } #[test] - fn test_extract_var_simple() { - check_assist( + fn extract_var_simple() { + check_assist_by_label( extract_variable, r#" fn foo() { @@ -426,19 +765,54 @@ fn foo() { let $0var_name = 1 + 1; foo(var_name); }"#, + "Extract into variable", + ); + } + + #[test] + fn extract_const_simple() { + check_assist_by_label( + extract_variable, + r#" +fn foo() { + foo($01 + 1$0); +}"#, + r#" +fn foo() { + const $0VAR_NAME: i32 = 1 + 1; + foo(VAR_NAME); +}"#, + "Extract into constant", ); } #[test] - fn extract_var_in_comment_is_not_applicable() { + fn extract_static_simple() { + check_assist_by_label( + extract_variable, + r#" +fn foo() { + foo($01 + 1$0); +}"#, + r#" +fn foo() { + static $0VAR_NAME: i32 = 1 + 1; + foo(VAR_NAME); +}"#, + "Extract into static", + ); + } + + #[test] + fn dont_extract_in_comment() { cov_mark::check!(extract_var_in_comment_is_not_applicable); - check_assist_not_applicable(extract_variable, "fn main() { 1 + /* $0comment$0 */ 1; }"); + check_assist_not_applicable(extract_variable, r#"fn main() { 1 + /* $0comment$0 */ 1; }"#); } #[test] - fn test_extract_var_expr_stmt() { + fn extract_var_expr_stmt() { cov_mark::check!(test_extract_var_expr_stmt); - check_assist( + check_assist_by_label( extract_variable, r#" fn foo() { @@ -448,42 +822,143 @@ fn foo() { fn foo() { let $0var_name = 1 + 1; }"#, + "Extract into variable", ); - check_assist( + check_assist_by_label( extract_variable, - r" + r#" fn foo() { $0{ let x = 0; x }$0; something_else(); -}", - r" +}"#, + r#" fn foo() { let $0var_name = { let x = 0; x }; something_else(); -}", +}"#, + "Extract into variable", ); } #[test] - fn test_extract_var_part_of_expr_stmt() { - check_assist( + fn extract_const_expr_stmt() { + cov_mark::check!(test_extract_var_expr_stmt); + check_assist_by_label( + extract_variable, + r#" +fn foo() { + $0 1 + 1$0; +}"#, + r#" +fn foo() { + const $0VAR_NAME: i32 = 1 + 1; +}"#, + "Extract into constant", + ); + // This is hilarious but as far as I know, it's valid + check_assist_by_label( extract_variable, - r" + r#" +fn foo() { + $0{ let x = 0; x }$0; + something_else(); +}"#, + r#" +fn foo() { + const $0VAR_NAME: i32 = { let x = 0; x }; + something_else(); +}"#, + "Extract into constant", + ); + } + + #[test] + fn extract_static_expr_stmt() { + cov_mark::check!(test_extract_var_expr_stmt); + check_assist_by_label( + extract_variable, + r#" +fn foo() { + $0 1 + 1$0; +}"#, + r#" +fn foo() { + static $0VAR_NAME: i32 = 1 + 1; +}"#, + "Extract into static", + ); + // This is hilarious but as far as I know, it's valid + check_assist_by_label( + extract_variable, + r#" +fn foo() { + $0{ let x = 0; x }$0; + something_else(); +}"#, + r#" +fn foo() { + static $0VAR_NAME: i32 = { let x = 0; x }; + something_else(); +}"#, + "Extract into static", + ); + } + + #[test] + fn extract_var_part_of_expr_stmt() { + check_assist_by_label( + extract_variable, + r#" fn foo() { $01$0 + 1; -}", - r" +}"#, + r#" fn foo() { let $0var_name = 1; var_name + 1; -}", +}"#, + "Extract into variable", + ); + } + + #[test] + fn extract_const_part_of_expr_stmt() { + check_assist_by_label( + extract_variable, + r#" +fn foo() { + $01$0 + 1; +}"#, + r#" +fn foo() { + const $0VAR_NAME: i32 = 1; + VAR_NAME + 1; +}"#, + "Extract into constant", ); } #[test] - fn test_extract_var_last_expr() { + fn extract_static_part_of_expr_stmt() { + check_assist_by_label( + extract_variable, + r#" +fn foo() { + $01$0 + 1; +}"#, + r#" +fn foo() { + static $0VAR_NAME: i32 = 1; + VAR_NAME + 1; +}"#, + "Extract into static", + ); + } + + #[test] + fn extract_var_last_expr() { cov_mark::check!(test_extract_var_last_expr); - check_assist( + check_assist_by_label( extract_variable, r#" fn foo() { @@ -496,8 +971,9 @@ fn foo() { bar(var_name) } "#, + "Extract into variable", ); - check_assist( + check_assist_by_label( extract_variable, r#" fn foo() -> i32 { @@ -518,13 +994,100 @@ fn bar(i: i32) -> i32 { i } "#, + "Extract into variable", + ) + } + + #[test] + fn extract_const_last_expr() { + cov_mark::check!(test_extract_var_last_expr); + check_assist_by_label( + extract_variable, + r#" +fn foo() { + bar($01 + 1$0) +} +"#, + r#" +fn foo() { + const $0VAR_NAME: i32 = 1 + 1; + bar(VAR_NAME) +} +"#, + "Extract into constant", + ); + check_assist_by_label( + extract_variable, + r#" +fn foo() -> i32 { + $0bar(1 + 1)$0 +} + +const fn bar(i: i32) -> i32 { + i +} +"#, + r#" +fn foo() -> i32 { + const $0BAR: i32 = bar(1 + 1); + BAR +} + +const fn bar(i: i32) -> i32 { + i +} +"#, + "Extract into constant", + ) + } + + #[test] + fn extract_static_last_expr() { + cov_mark::check!(test_extract_var_last_expr); + check_assist_by_label( + extract_variable, + r#" +fn foo() { + bar($01 + 1$0) +} +"#, + r#" +fn foo() { + static $0VAR_NAME: i32 = 1 + 1; + bar(VAR_NAME) +} +"#, + "Extract into static", + ); + check_assist_by_label( + extract_variable, + r#" +fn foo() -> i32 { + $0bar(1 + 1)$0 +} + +const fn bar(i: i32) -> i32 { + i +} +"#, + r#" +fn foo() -> i32 { + static $0BAR: i32 = bar(1 + 1); + BAR +} + +const fn bar(i: i32) -> i32 { + i +} +"#, + "Extract into static", ) } #[test] - fn test_extract_var_in_match_arm_no_block() { + fn extract_var_in_match_arm_no_block() { cov_mark::check!(test_extract_var_in_match_arm_no_block); - check_assist( + check_assist_by_label( extract_variable, r#" fn main() { @@ -547,12 +1110,13 @@ fn main() { }; } "#, + "Extract into variable", ); } #[test] - fn test_extract_var_in_match_arm_with_block() { - check_assist( + fn extract_var_in_match_arm_with_block() { + check_assist_by_label( extract_variable, r#" fn main() { @@ -579,13 +1143,14 @@ fn main() { }; } "#, + "Extract into variable", ); } #[test] - fn test_extract_var_in_match_guard() { + fn extract_var_in_match_guard() { cov_mark::check!(test_extract_var_in_match_guard); - check_assist( + check_assist_by_label( extract_variable, r#" fn main() { @@ -604,13 +1169,14 @@ fn main() { }; } "#, + "Extract into variable", ); } #[test] - fn test_extract_var_in_closure_no_block() { + fn extract_var_in_closure_no_block() { cov_mark::check!(test_extract_var_in_closure_no_block); - check_assist( + check_assist_by_label( extract_variable, r#" fn main() { @@ -625,12 +1191,13 @@ fn main() { }; } "#, + "Extract into variable", ); } #[test] - fn test_extract_var_in_closure_with_block() { - check_assist( + fn extract_var_in_closure_with_block() { + check_assist_by_label( extract_variable, r#" fn main() { @@ -642,104 +1209,110 @@ fn main() { let lambda = |x: u32| { let $0var_name = x * 2; var_name }; } "#, + "Extract into variable", ); } #[test] - fn test_extract_var_path_simple() { - check_assist( + fn extract_var_path_simple() { + check_assist_by_label( extract_variable, - " + r#" fn main() { let o = $0Some(true)$0; } -", - " +"#, + r#" fn main() { let $0var_name = Some(true); let o = var_name; } -", +"#, + "Extract into variable", ); } #[test] - fn test_extract_var_path_method() { - check_assist( + fn extract_var_path_method() { + check_assist_by_label( extract_variable, - " + r#" fn main() { let v = $0bar.foo()$0; } -", - " +"#, + r#" fn main() { let $0foo = bar.foo(); let v = foo; } -", +"#, + "Extract into variable", ); } #[test] - fn test_extract_var_return() { - check_assist( + fn extract_var_return() { + check_assist_by_label( extract_variable, - " + r#" fn foo() -> u32 { $0return 2 + 2$0; } -", - " +"#, + r#" fn foo() -> u32 { let $0var_name = 2 + 2; return var_name; } -", +"#, + "Extract into variable", ); } #[test] - fn test_extract_var_does_not_add_extra_whitespace() { - check_assist( + fn extract_var_does_not_add_extra_whitespace() { + check_assist_by_label( extract_variable, - " + r#" fn foo() -> u32 { $0return 2 + 2$0; } -", - " +"#, + r#" fn foo() -> u32 { let $0var_name = 2 + 2; return var_name; } -", +"#, + "Extract into variable", ); - check_assist( + check_assist_by_label( extract_variable, - " + r#" fn foo() -> u32 { $0return 2 + 2$0; } -", - " +"#, + r#" fn foo() -> u32 { let $0var_name = 2 + 2; return var_name; } -", +"#, + "Extract into variable", ); - check_assist( + check_assist_by_label( extract_variable, - " + r#" fn foo() -> u32 { let foo = 1; @@ -748,8 +1321,8 @@ fn foo() -> u32 { $0return 2 + 2$0; } -", - " +"#, + r#" fn foo() -> u32 { let foo = 1; @@ -759,53 +1332,56 @@ fn foo() -> u32 { let $0var_name = 2 + 2; return var_name; } -", +"#, + "Extract into variable", ); } #[test] - fn test_extract_var_break() { - check_assist( + fn extract_var_break() { + check_assist_by_label( extract_variable, - " + r#" fn main() { let result = loop { $0break 2 + 2$0; }; } -", - " +"#, + r#" fn main() { let result = loop { let $0var_name = 2 + 2; break var_name; }; } -", +"#, + "Extract into variable", ); } #[test] - fn test_extract_var_for_cast() { - check_assist( + fn extract_var_for_cast() { + check_assist_by_label( extract_variable, - " + r#" fn main() { let v = $00f32 as u32$0; } -", - " +"#, + r#" fn main() { let $0var_name = 0f32 as u32; let v = var_name; } -", +"#, + "Extract into variable", ); } #[test] fn extract_var_field_shorthand() { - check_assist( + check_assist_by_label( extract_variable, r#" struct S { @@ -826,12 +1402,13 @@ fn main() { S { foo } } "#, + "Extract into variable", ) } #[test] fn extract_var_name_from_type() { - check_assist( + check_assist_by_label( extract_variable, r#" struct Test(i32); @@ -848,12 +1425,13 @@ fn foo() -> Test { test } "#, + "Extract into variable", ) } #[test] fn extract_var_name_from_parameter() { - check_assist( + check_assist_by_label( extract_variable, r#" fn bar(test: u32, size: u32) @@ -870,12 +1448,13 @@ fn foo() { bar(1, size); } "#, + "Extract into variable", ) } #[test] fn extract_var_parameter_name_has_precedence_over_type() { - check_assist( + check_assist_by_label( extract_variable, r#" struct TextSize(u32); @@ -894,12 +1473,13 @@ fn foo() { bar(1, size); } "#, + "Extract into variable", ) } #[test] fn extract_var_name_from_function() { - check_assist( + check_assist_by_label( extract_variable, r#" fn is_required(test: u32, size: u32) -> bool @@ -916,12 +1496,13 @@ fn foo() -> bool { is_required } "#, + "Extract into variable", ) } #[test] fn extract_var_name_from_method() { - check_assist( + check_assist_by_label( extract_variable, r#" struct S; @@ -944,12 +1525,13 @@ fn foo() -> u32 { bar } "#, + "Extract into variable", ) } #[test] fn extract_var_name_from_method_param() { - check_assist( + check_assist_by_label( extract_variable, r#" struct S; @@ -972,12 +1554,13 @@ fn foo() { S.bar(n, 2) } "#, + "Extract into variable", ) } #[test] fn extract_var_name_from_ufcs_method_param() { - check_assist( + check_assist_by_label( extract_variable, r#" struct S; @@ -1000,12 +1583,13 @@ fn foo() { S::bar(&S, n, 2) } "#, + "Extract into variable", ) } #[test] fn extract_var_parameter_name_has_precedence_over_function() { - check_assist( + check_assist_by_label( extract_variable, r#" fn bar(test: u32, size: u32) @@ -1022,14 +1606,15 @@ fn foo() { bar(1, size); } "#, + "Extract into variable", ) } #[test] fn extract_macro_call() { - check_assist( + check_assist_by_label( extract_variable, - r" + r#" struct Vec; macro_rules! vec { () => {Vec} @@ -1037,8 +1622,8 @@ macro_rules! vec { fn main() { let _ = $0vec![]$0; } -", - r" +"#, + r#" struct Vec; macro_rules! vec { () => {Vec} @@ -1047,22 +1632,71 @@ fn main() { let $0vec = vec![]; let _ = vec; } -", +"#, + "Extract into variable", + ); + + check_assist_by_label( + extract_variable, + r#" +struct Vec; +macro_rules! vec { + () => {Vec} +} +fn main() { + let _ = $0vec![]$0; +} +"#, + r#" +struct Vec; +macro_rules! vec { + () => {Vec} +} +fn main() { + const $0VEC: Vec = vec![]; + let _ = VEC; +} +"#, + "Extract into constant", + ); + + check_assist_by_label( + extract_variable, + r#" +struct Vec; +macro_rules! vec { + () => {Vec} +} +fn main() { + let _ = $0vec![]$0; +} +"#, + r#" +struct Vec; +macro_rules! vec { + () => {Vec} +} +fn main() { + static $0VEC: Vec = vec![]; + let _ = VEC; +} +"#, + "Extract into static", ); } #[test] - fn test_extract_var_for_return_not_applicable() { + fn extract_var_for_return_not_applicable() { check_assist_not_applicable(extract_variable, "fn foo() { $0return$0; } "); } #[test] - fn test_extract_var_for_break_not_applicable() { + fn extract_var_for_break_not_applicable() { check_assist_not_applicable(extract_variable, "fn main() { loop { $0break$0; }; }"); } #[test] - fn test_extract_var_unit_expr_not_applicable() { + fn extract_var_unit_expr_not_applicable() { check_assist_not_applicable( extract_variable, r#" @@ -1080,11 +1714,11 @@ fn foo() { // FIXME: This is not quite correct, but good enough(tm) for the sorting heuristic #[test] fn extract_var_target() { - check_assist_target(extract_variable, "fn foo() -> u32 { $0return 2 + 2$0; }", "2 + 2"); + check_assist_target(extract_variable, r#"fn foo() -> u32 { $0return 2 + 2$0; }"#, "2 + 2"); check_assist_target( extract_variable, - " + r#" fn main() { let x = true; let tuple = match x { @@ -1092,24 +1726,231 @@ fn main() { _ => (0, false) }; } -", +"#, "2 + 2", ); } #[test] fn extract_var_no_block_body() { - check_assist_not_applicable( + check_assist_not_applicable_by_label( extract_variable, - r" + r#" const X: usize = $0100$0; -", +"#, + "Extract into variable", ); } #[test] - fn test_extract_var_mutable_reference_parameter() { - check_assist( + fn extract_const_no_block_body() { + check_assist_by_label( + extract_variable, + r#" +const fn foo(x: i32) -> i32 { + x +} + +const FOO: i32 = foo($0100$0); +"#, + r#" +const fn foo(x: i32) -> i32 { + x +} + +const $0X: i32 = 100; +const FOO: i32 = foo(X); +"#, + "Extract into constant", + ); + + check_assist_by_label( + extract_variable, + r#" +mod foo { + enum Foo { + Bar, + Baz = $042$0, + } +} +"#, + r#" +mod foo { + const $0VAR_NAME: isize = 42; + enum Foo { + Bar, + Baz = VAR_NAME, + } +} +"#, + "Extract into constant", + ); + + check_assist_by_label( + extract_variable, + r#" +const fn foo(x: i32) -> i32 { + x +} + +trait Hello { + const World: i32; +} + +struct Bar; +impl Hello for Bar { + const World = foo($042$0); +} +"#, + r#" +const fn foo(x: i32) -> i32 { + x +} + +trait Hello { + const World: i32; +} + +struct Bar; +impl Hello for Bar { + const $0X: i32 = 42; + const World = foo(X); +} +"#, + "Extract into constant", + ); + + check_assist_by_label( + extract_variable, + r#" +const fn foo(x: i32) -> i32 { + x +} + +fn bar() { + const BAZ: i32 = foo($042$0); +} +"#, + r#" +const fn foo(x: i32) -> i32 { + x +} + +fn bar() { + const $0X: i32 = 42; + const BAZ: i32 = foo(X); +} +"#, + "Extract into constant", + ); + } + + #[test] + fn extract_static_no_block_body() { + check_assist_by_label( + extract_variable, + r#" +const fn foo(x: i32) -> i32 { + x +} + +const FOO: i32 = foo($0100$0); +"#, + r#" +const fn foo(x: i32) -> i32 { + x +} + +static $0X: i32 = 100; +const FOO: i32 = foo(X); +"#, + "Extract into static", + ); + + check_assist_by_label( + extract_variable, + r#" +mod foo { + enum Foo { + Bar, + Baz = $042$0, + } +} +"#, + r#" +mod foo { + static $0VAR_NAME: isize = 42; + enum Foo { + Bar, + Baz = VAR_NAME, + } +} +"#, + "Extract into static", + ); + + check_assist_by_label( + extract_variable, + r#" +const fn foo(x: i32) -> i32 { + x +} + +trait Hello { + const World: i32; +} + +struct Bar; +impl Hello for Bar { + const World = foo($042$0); +} +"#, + r#" +const fn foo(x: i32) -> i32 { + x +} + +trait Hello { + const World: i32; +} + +struct Bar; +impl Hello for Bar { + static $0X: i32 = 42; + const World = foo(X); +} +"#, + "Extract into static", + ); + + check_assist_by_label( + extract_variable, + r#" +const fn foo(x: i32) -> i32 { + x +} + +fn bar() { + const BAZ: i32 = foo($042$0); +} +"#, + r#" +const fn foo(x: i32) -> i32 { + x +} + +fn bar() { + static $0X: i32 = 42; + const BAZ: i32 = foo(X); +} +"#, + "Extract into static", + ); + } + + #[test] + fn extract_var_mutable_reference_parameter() { + check_assist_by_label( extract_variable, r#" struct S { @@ -1138,12 +1979,55 @@ fn foo(s: &mut S) { let $0vec = &mut s.vec; vec.push(0); }"#, + "Extract into variable", ); } #[test] - fn test_extract_var_mutable_reference_parameter_deep_nesting() { - check_assist( + fn dont_extract_const_mutable_reference_parameter() { + check_assist_not_applicable_by_label( + extract_variable, + r#" +struct S { + vec: Vec<u8> +} + +struct Vec<T>; +impl<T> Vec<T> { + fn push(&mut self, _:usize) {} +} + +fn foo(s: &mut S) { + $0s.vec$0.push(0); +}"#, + "Extract into constant", + ); + } + + #[test] + fn dont_extract_static_mutable_reference_parameter() { + check_assist_not_applicable_by_label( + extract_variable, + r#" +struct S { + vec: Vec<u8> +} + +struct Vec<T>; +impl<T> Vec<T> { + fn push(&mut self, _:usize) {} +} + +fn foo(s: &mut S) { + $0s.vec$0.push(0); +}"#, + "Extract into static", + ); + } + + #[test] + fn extract_var_mutable_reference_parameter_deep_nesting() { + check_assist_by_label( extract_variable, r#" struct Y { @@ -1182,12 +2066,13 @@ fn foo(f: &mut Y) { let $0vec = &mut f.field.field.vec; vec.push(0); }"#, + "Extract into variable", ); } #[test] - fn test_extract_var_reference_parameter() { - check_assist( + fn extract_var_reference_parameter() { + check_assist_by_label( extract_variable, r#" struct X; @@ -1222,12 +2107,13 @@ fn foo(s: &S) { let $0x = &s.sub; x.do_thing(); }"#, + "Extract into variable", ); } #[test] - fn test_extract_var_index_deref() { - check_assist( + fn extract_var_index_deref() { + check_assist_by_label( extract_variable, r#" //- minicore: index @@ -1261,12 +2147,13 @@ fn foo(s: &S) { let $0sub = &s.sub; sub[0]; }"#, + "Extract into variable", ); } #[test] - fn test_extract_var_reference_parameter_deep_nesting() { - check_assist( + fn extract_var_reference_parameter_deep_nesting() { + check_assist_by_label( extract_variable, r#" struct Z; @@ -1315,12 +2202,13 @@ fn foo(s: &S) { let $0z = &s.sub.field.field; z.do_thing(); }"#, + "Extract into variable", ); } #[test] - fn test_extract_var_regular_parameter() { - check_assist( + fn extract_var_regular_parameter() { + check_assist_by_label( extract_variable, r#" struct X; @@ -1355,12 +2243,13 @@ fn foo(s: S) { let $0x = &s.sub; x.do_thing(); }"#, + "Extract into variable", ); } #[test] - fn test_extract_var_mutable_reference_local() { - check_assist( + fn extract_var_mutable_reference_local() { + check_assist_by_label( extract_variable, r#" struct X; @@ -1421,12 +2310,13 @@ fn foo() { let $0x = &local.sub; x.do_thing(); }"#, + "Extract into variable", ); } #[test] - fn test_extract_var_reference_local() { - check_assist( + fn extract_var_reference_local() { + check_assist_by_label( extract_variable, r#" struct X; @@ -1487,12 +2377,13 @@ fn foo() { let $0x = &local.sub; x.do_thing(); }"#, + "Extract into variable", ); } #[test] - fn test_extract_var_for_mutable_borrow() { - check_assist( + fn extract_var_for_mutable_borrow() { + check_assist_by_label( extract_variable, r#" fn foo() { @@ -1503,12 +2394,37 @@ fn foo() { let mut $0var_name = 0; let v = &mut var_name; }"#, + "Extract into variable", + ); + } + + #[test] + fn dont_extract_const_for_mutable_borrow() { + check_assist_not_applicable_by_label( + extract_variable, + r#" +fn foo() { + let v = &mut $00$0; +}"#, + "Extract into constant", + ); + } + + #[test] + fn dont_extract_static_for_mutable_borrow() { + check_assist_not_applicable_by_label( + extract_variable, + r#" +fn foo() { + let v = &mut $00$0; +}"#, + "Extract into static", ); } #[test] fn generates_no_ref_on_calls() { - check_assist( + check_assist_by_label( extract_variable, r#" struct S; @@ -1529,12 +2445,13 @@ fn foo() { let mut $0bar = bar(); bar.do_work(); }"#, + "Extract into variable", ); } #[test] fn generates_no_ref_for_deref() { - check_assist( + check_assist_by_label( extract_variable, r#" struct S; @@ -1559,6 +2476,7 @@ fn foo() { s.do_work(); } "#, + "Extract into variable", ); } } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs index 76a647807cb..7b95c124e62 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs @@ -2055,7 +2055,7 @@ fn bar(closure: impl Fn(i64) -> i64) { } #[test] - fn unresolveable_types_default_to_placeholder() { + fn unresolvable_types_default_to_placeholder() { check_assist( generate_function, r" diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_const_as_literal.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_const_as_literal.rs index 2bd4c4da1e2..c92c22378f8 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_const_as_literal.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_const_as_literal.rs @@ -1,3 +1,4 @@ +use hir::HasCrate; use syntax::{ast, AstNode}; use crate::{AssistContext, AssistId, AssistKind, Assists}; @@ -51,7 +52,10 @@ pub(crate) fn inline_const_as_literal(acc: &mut Assists, ctx: &AssistContext<'_> | ast::Expr::MatchExpr(_) | ast::Expr::MacroExpr(_) | ast::Expr::BinExpr(_) - | ast::Expr::CallExpr(_) => konst.eval(ctx.sema.db).ok()?, + | ast::Expr::CallExpr(_) => konst + .eval(ctx.sema.db) + .ok()? + .render(ctx.sema.db, konst.krate(ctx.sema.db).edition(ctx.sema.db)), _ => return None, }; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs index ec3281619cc..f0c96fe3cb8 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs @@ -36,7 +36,7 @@ pub(crate) fn move_guard_to_arm_body(acc: &mut Assists, ctx: &AssistContext<'_>) let match_arm = ctx.find_node_at_offset::<MatchArm>()?; let guard = match_arm.guard()?; if ctx.offset() > guard.syntax().text_range().end() { - cov_mark::hit!(move_guard_unapplicable_in_arm_body); + cov_mark::hit!(move_guard_inapplicable_in_arm_body); return None; } let space_before_guard = guard.syntax().prev_sibling_or_token(); @@ -219,7 +219,7 @@ mod tests { #[test] fn move_guard_to_arm_body_range() { - cov_mark::check!(move_guard_unapplicable_in_arm_body); + cov_mark::check!(move_guard_inapplicable_in_arm_body); check_assist_not_applicable( move_guard_to_arm_body, r#" diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/promote_local_to_const.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/promote_local_to_const.rs index 7c2dc0e0c10..0cc771ff397 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/promote_local_to_const.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/promote_local_to_const.rs @@ -1,19 +1,17 @@ -use hir::{HirDisplay, ModuleDef, PathResolution, Semantics}; +use hir::HirDisplay; use ide_db::{ assists::{AssistId, AssistKind}, defs::Definition, - syntax_helpers::node_ext::preorder_expr, - RootDatabase, }; use stdx::to_upper_snake_case; use syntax::{ ast::{self, make, HasName}, - ted, AstNode, WalkEvent, + ted, AstNode, }; use crate::{ assist_context::{AssistContext, Assists}, - utils, + utils::{self}, }; // Assist: promote_local_to_const @@ -63,7 +61,7 @@ pub(crate) fn promote_local_to_const(acc: &mut Assists, ctx: &AssistContext<'_>) }; let initializer = let_stmt.initializer()?; - if !is_body_const(&ctx.sema, &initializer) { + if !utils::is_body_const(&ctx.sema, &initializer) { cov_mark::hit!(promote_local_non_const); return None; } @@ -103,40 +101,6 @@ pub(crate) fn promote_local_to_const(acc: &mut Assists, ctx: &AssistContext<'_>) ) } -fn is_body_const(sema: &Semantics<'_, RootDatabase>, expr: &ast::Expr) -> bool { - let mut is_const = true; - preorder_expr(expr, &mut |ev| { - let expr = match ev { - WalkEvent::Enter(_) if !is_const => return true, - WalkEvent::Enter(expr) => expr, - WalkEvent::Leave(_) => return false, - }; - match expr { - ast::Expr::CallExpr(call) => { - if let Some(ast::Expr::PathExpr(path_expr)) = call.expr() { - if let Some(PathResolution::Def(ModuleDef::Function(func))) = - path_expr.path().and_then(|path| sema.resolve_path(&path)) - { - is_const &= func.is_const(sema.db); - } - } - } - ast::Expr::MethodCallExpr(call) => { - is_const &= - sema.resolve_method_call(&call).map(|it| it.is_const(sema.db)).unwrap_or(true) - } - ast::Expr::ForExpr(_) - | ast::Expr::ReturnExpr(_) - | ast::Expr::TryExpr(_) - | ast::Expr::YieldExpr(_) - | ast::Expr::AwaitExpr(_) => is_const = false, - _ => (), - } - !is_const - }); - is_const -} - #[cfg(test)] mod tests { use crate::tests::{check_assist, check_assist_not_applicable}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs index 248f18789ce..2dec876215c 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs @@ -139,7 +139,7 @@ fn add_assist( let trait_path = make::ty_path(replace_trait_path.clone()); match (ctx.config.snippet_cap, impl_def_with_items) { - (None, _) => { + (None, None) => { let impl_def = generate_trait_impl(adt, trait_path); ted::insert_all( @@ -147,6 +147,12 @@ fn add_assist( vec![make::tokens::blank_line().into(), impl_def.syntax().clone().into()], ); } + (None, Some((impl_def, _))) => { + ted::insert_all( + insert_after, + vec![make::tokens::blank_line().into(), impl_def.syntax().clone().into()], + ); + } (Some(cap), None) => { let impl_def = generate_trait_impl(adt, trait_path); @@ -272,7 +278,7 @@ fn update_attribute( #[cfg(test)] mod tests { - use crate::tests::{check_assist, check_assist_not_applicable}; + use crate::tests::{check_assist, check_assist_no_snippet_cap, check_assist_not_applicable}; use super::*; @@ -301,6 +307,30 @@ impl core::fmt::Debug for Foo { ) } #[test] + fn add_custom_impl_without_snippet() { + check_assist_no_snippet_cap( + replace_derive_with_manual_impl, + r#" +//- minicore: fmt, derive +#[derive(Debu$0g)] +struct Foo { + bar: String, +} +"#, + r#" +struct Foo { + bar: String, +} + +impl core::fmt::Debug for Foo { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("Foo").field("bar", &self.bar).finish() + } +} +"#, + ) + } + #[test] fn add_custom_impl_debug_tuple_struct() { check_assist( replace_derive_with_manual_impl, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_if_let_with_match.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_if_let_with_match.rs index f13b0b0713d..56dd6cf29ae 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_if_let_with_match.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_if_let_with_match.rs @@ -360,7 +360,7 @@ mod tests { use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target}; #[test] - fn test_if_let_with_match_unapplicable_for_simple_ifs() { + fn test_if_let_with_match_inapplicable_for_simple_ifs() { check_assist_not_applicable( replace_if_let_with_match, r#" diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_async_sugar.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_async_sugar.rs index 9ab36bf7757..8f937a04122 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_async_sugar.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_async_sugar.rs @@ -127,7 +127,7 @@ pub(crate) fn desugar_async_into_impl_future( let rparen = function.param_list()?.r_paren_token()?; let return_type = match function.ret_type() { - // unable to get a `ty` makes the action unapplicable + // unable to get a `ty` makes the action inapplicable Some(ret_type) => Some(ret_type.ty()?), // No type means `-> ()` None => None, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs b/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs index 6469957fe16..0b1ff87c5c2 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs @@ -362,8 +362,7 @@ pub fn test_some_range(a: int) -> bool { expect![[r#" Convert integer base - Extract into variable - Extract into function + Extract into... Replace if let with match "#]] .assert_eq(&expected); @@ -391,8 +390,7 @@ pub fn test_some_range(a: int) -> bool { expect![[r#" Convert integer base - Extract into variable - Extract into function + Extract into... Replace if let with match "#]] .assert_eq(&expected); @@ -405,8 +403,7 @@ pub fn test_some_range(a: int) -> bool { let expected = labels(&assists); expect![[r#" - Extract into variable - Extract into function + Extract into... "#]] .assert_eq(&expected); } @@ -440,7 +437,7 @@ pub fn test_some_range(a: int) -> bool { { let assists = assists(&db, &cfg, AssistResolveStrategy::None, frange.into()); - assert_eq!(2, assists.len()); + assert_eq!(4, assists.len()); let mut assists = assists.into_iter(); let extract_into_variable_assist = assists.next().unwrap(); @@ -451,7 +448,11 @@ pub fn test_some_range(a: int) -> bool { RefactorExtract, ), label: "Extract into variable", - group: None, + group: Some( + GroupLabel( + "Extract into...", + ), + ), target: 59..60, source_change: None, command: None, @@ -459,6 +460,46 @@ pub fn test_some_range(a: int) -> bool { "#]] .assert_debug_eq(&extract_into_variable_assist); + let extract_into_constant_assist = assists.next().unwrap(); + expect![[r#" + Assist { + id: AssistId( + "extract_constant", + RefactorExtract, + ), + label: "Extract into constant", + group: Some( + GroupLabel( + "Extract into...", + ), + ), + target: 59..60, + source_change: None, + command: None, + } + "#]] + .assert_debug_eq(&extract_into_constant_assist); + + let extract_into_static_assist = assists.next().unwrap(); + expect![[r#" + Assist { + id: AssistId( + "extract_static", + RefactorExtract, + ), + label: "Extract into static", + group: Some( + GroupLabel( + "Extract into...", + ), + ), + target: 59..60, + source_change: None, + command: None, + } + "#]] + .assert_debug_eq(&extract_into_static_assist); + let extract_into_function_assist = assists.next().unwrap(); expect![[r#" Assist { @@ -467,7 +508,11 @@ pub fn test_some_range(a: int) -> bool { RefactorExtract, ), label: "Extract into function", - group: None, + group: Some( + GroupLabel( + "Extract into...", + ), + ), target: 59..60, source_change: None, command: None, @@ -486,7 +531,7 @@ pub fn test_some_range(a: int) -> bool { }), frange.into(), ); - assert_eq!(2, assists.len()); + assert_eq!(4, assists.len()); let mut assists = assists.into_iter(); let extract_into_variable_assist = assists.next().unwrap(); @@ -497,7 +542,11 @@ pub fn test_some_range(a: int) -> bool { RefactorExtract, ), label: "Extract into variable", - group: None, + group: Some( + GroupLabel( + "Extract into...", + ), + ), target: 59..60, source_change: None, command: None, @@ -505,6 +554,46 @@ pub fn test_some_range(a: int) -> bool { "#]] .assert_debug_eq(&extract_into_variable_assist); + let extract_into_constant_assist = assists.next().unwrap(); + expect![[r#" + Assist { + id: AssistId( + "extract_constant", + RefactorExtract, + ), + label: "Extract into constant", + group: Some( + GroupLabel( + "Extract into...", + ), + ), + target: 59..60, + source_change: None, + command: None, + } + "#]] + .assert_debug_eq(&extract_into_constant_assist); + + let extract_into_static_assist = assists.next().unwrap(); + expect![[r#" + Assist { + id: AssistId( + "extract_static", + RefactorExtract, + ), + label: "Extract into static", + group: Some( + GroupLabel( + "Extract into...", + ), + ), + target: 59..60, + source_change: None, + command: None, + } + "#]] + .assert_debug_eq(&extract_into_static_assist); + let extract_into_function_assist = assists.next().unwrap(); expect![[r#" Assist { @@ -513,7 +602,11 @@ pub fn test_some_range(a: int) -> bool { RefactorExtract, ), label: "Extract into function", - group: None, + group: Some( + GroupLabel( + "Extract into...", + ), + ), target: 59..60, source_change: None, command: None, @@ -532,7 +625,7 @@ pub fn test_some_range(a: int) -> bool { }), frange.into(), ); - assert_eq!(2, assists.len()); + assert_eq!(4, assists.len()); let mut assists = assists.into_iter(); let extract_into_variable_assist = assists.next().unwrap(); @@ -543,7 +636,11 @@ pub fn test_some_range(a: int) -> bool { RefactorExtract, ), label: "Extract into variable", - group: None, + group: Some( + GroupLabel( + "Extract into...", + ), + ), target: 59..60, source_change: Some( SourceChange { @@ -594,6 +691,46 @@ pub fn test_some_range(a: int) -> bool { "#]] .assert_debug_eq(&extract_into_variable_assist); + let extract_into_constant_assist = assists.next().unwrap(); + expect![[r#" + Assist { + id: AssistId( + "extract_constant", + RefactorExtract, + ), + label: "Extract into constant", + group: Some( + GroupLabel( + "Extract into...", + ), + ), + target: 59..60, + source_change: None, + command: None, + } + "#]] + .assert_debug_eq(&extract_into_constant_assist); + + let extract_into_static_assist = assists.next().unwrap(); + expect![[r#" + Assist { + id: AssistId( + "extract_static", + RefactorExtract, + ), + label: "Extract into static", + group: Some( + GroupLabel( + "Extract into...", + ), + ), + target: 59..60, + source_change: None, + command: None, + } + "#]] + .assert_debug_eq(&extract_into_static_assist); + let extract_into_function_assist = assists.next().unwrap(); expect![[r#" Assist { @@ -602,7 +739,11 @@ pub fn test_some_range(a: int) -> bool { RefactorExtract, ), label: "Extract into function", - group: None, + group: Some( + GroupLabel( + "Extract into...", + ), + ), target: 59..60, source_change: None, command: None, @@ -613,7 +754,7 @@ pub fn test_some_range(a: int) -> bool { { let assists = assists(&db, &cfg, AssistResolveStrategy::All, frange.into()); - assert_eq!(2, assists.len()); + assert_eq!(4, assists.len()); let mut assists = assists.into_iter(); let extract_into_variable_assist = assists.next().unwrap(); @@ -624,7 +765,11 @@ pub fn test_some_range(a: int) -> bool { RefactorExtract, ), label: "Extract into variable", - group: None, + group: Some( + GroupLabel( + "Extract into...", + ), + ), target: 59..60, source_change: Some( SourceChange { @@ -675,6 +820,140 @@ pub fn test_some_range(a: int) -> bool { "#]] .assert_debug_eq(&extract_into_variable_assist); + let extract_into_constant_assist = assists.next().unwrap(); + expect![[r#" + Assist { + id: AssistId( + "extract_constant", + RefactorExtract, + ), + label: "Extract into constant", + group: Some( + GroupLabel( + "Extract into...", + ), + ), + target: 59..60, + source_change: Some( + SourceChange { + source_file_edits: { + FileId( + 0, + ): ( + TextEdit { + indels: [ + Indel { + insert: "const", + delete: 45..47, + }, + Indel { + insert: "VAR_NAME:", + delete: 48..60, + }, + Indel { + insert: "i32", + delete: 61..81, + }, + Indel { + insert: "=", + delete: 82..86, + }, + Indel { + insert: "5;\n if let 2..6 = VAR_NAME {\n true\n } else {\n false\n }", + delete: 87..108, + }, + ], + }, + Some( + SnippetEdit( + [ + ( + 0, + 51..51, + ), + ], + ), + ), + ), + }, + file_system_edits: [], + is_snippet: true, + }, + ), + command: Some( + Rename, + ), + } + "#]] + .assert_debug_eq(&extract_into_constant_assist); + + let extract_into_static_assist = assists.next().unwrap(); + expect![[r#" + Assist { + id: AssistId( + "extract_static", + RefactorExtract, + ), + label: "Extract into static", + group: Some( + GroupLabel( + "Extract into...", + ), + ), + target: 59..60, + source_change: Some( + SourceChange { + source_file_edits: { + FileId( + 0, + ): ( + TextEdit { + indels: [ + Indel { + insert: "static", + delete: 45..47, + }, + Indel { + insert: "VAR_NAME:", + delete: 48..60, + }, + Indel { + insert: "i32", + delete: 61..81, + }, + Indel { + insert: "=", + delete: 82..86, + }, + Indel { + insert: "5;\n if let 2..6 = VAR_NAME {\n true\n } else {\n false\n }", + delete: 87..108, + }, + ], + }, + Some( + SnippetEdit( + [ + ( + 0, + 52..52, + ), + ], + ), + ), + ), + }, + file_system_edits: [], + is_snippet: true, + }, + ), + command: Some( + Rename, + ), + } + "#]] + .assert_debug_eq(&extract_into_static_assist); + let extract_into_function_assist = assists.next().unwrap(); expect![[r#" Assist { @@ -683,7 +962,11 @@ pub fn test_some_range(a: int) -> bool { RefactorExtract, ), label: "Extract into function", - group: None, + group: Some( + GroupLabel( + "Extract into...", + ), + ), target: 59..60, source_change: Some( SourceChange { diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs index 69ea200db16..87c3d166ee6 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs @@ -933,6 +933,24 @@ enum TheEnum { } #[test] +fn doctest_extract_constant() { + check_doc_test( + "extract_constant", + r#####" +fn main() { + $0(1 + 2)$0 * 4; +} +"#####, + r#####" +fn main() { + const $0VAR_NAME: i32 = 1 + 2; + VAR_NAME * 4; +} +"#####, + ) +} + +#[test] fn doctest_extract_expressions_from_format_string() { check_doc_test( "extract_expressions_from_format_string", @@ -1007,6 +1025,24 @@ fn bar(name: i32) -> i32 { } #[test] +fn doctest_extract_static() { + check_doc_test( + "extract_static", + r#####" +fn main() { + $0(1 + 2)$0 * 4; +} +"#####, + r#####" +fn main() { + static $0VAR_NAME: i32 = 1 + 2; + VAR_NAME * 4; +} +"#####, + ) +} + +#[test] fn doctest_extract_struct_from_enum_variant() { check_doc_test( "extract_struct_from_enum_variant", diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs index 0830017bd0f..3c26b043597 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs @@ -3,11 +3,13 @@ pub(crate) use gen_trait_fn_body::gen_trait_fn_body; use hir::{ db::{ExpandDatabase, HirDatabase}, - HasAttrs as HirHasAttrs, HirDisplay, InFile, Semantics, + HasAttrs as HirHasAttrs, HirDisplay, InFile, ModuleDef, PathResolution, Semantics, }; use ide_db::{ - famous_defs::FamousDefs, path_transform::PathTransform, - syntax_helpers::prettify_macro_expansion, RootDatabase, + famous_defs::FamousDefs, + path_transform::PathTransform, + syntax_helpers::{node_ext::preorder_expr, prettify_macro_expansion}, + RootDatabase, }; use stdx::format_to; use syntax::{ @@ -19,7 +21,7 @@ use syntax::{ }, ted, AstNode, AstToken, Direction, Edition, NodeOrToken, SourceFile, SyntaxKind::*, - SyntaxNode, SyntaxToken, TextRange, TextSize, T, + SyntaxNode, SyntaxToken, TextRange, TextSize, WalkEvent, T, }; use crate::assist_context::{AssistContext, SourceChangeBuilder}; @@ -966,3 +968,37 @@ pub(crate) fn tt_from_syntax(node: SyntaxNode) -> Vec<NodeOrToken<ast::TokenTree tt_stack.pop().expect("parent token tree was closed before it was completed").1 } + +pub fn is_body_const(sema: &Semantics<'_, RootDatabase>, expr: &ast::Expr) -> bool { + let mut is_const = true; + preorder_expr(expr, &mut |ev| { + let expr = match ev { + WalkEvent::Enter(_) if !is_const => return true, + WalkEvent::Enter(expr) => expr, + WalkEvent::Leave(_) => return false, + }; + match expr { + ast::Expr::CallExpr(call) => { + if let Some(ast::Expr::PathExpr(path_expr)) = call.expr() { + if let Some(PathResolution::Def(ModuleDef::Function(func))) = + path_expr.path().and_then(|path| sema.resolve_path(&path)) + { + is_const &= func.is_const(sema.db); + } + } + } + ast::Expr::MethodCallExpr(call) => { + is_const &= + sema.resolve_method_call(&call).map(|it| it.is_const(sema.db)).unwrap_or(true) + } + ast::Expr::ForExpr(_) + | ast::Expr::ReturnExpr(_) + | ast::Expr::TryExpr(_) + | ast::Expr::YieldExpr(_) + | ast::Expr::AwaitExpr(_) => is_const = false, + _ => (), + } + !is_const + }); + is_const +} diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/lint.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/lint.rs index d5f9cd5fc76..04f40e805ad 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/lint.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/lint.rs @@ -11,7 +11,7 @@ pub(super) fn complete_lint( existing_lints: &[ast::Path], lints_completions: &[Lint], ) { - for &Lint { label, description } in lints_completions { + for &Lint { label, description, .. } in lints_completions { let (qual, name) = { // FIXME: change `Lint`'s label to not store a path in it but split the prefix off instead? let mut parts = label.split("::"); diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs index 4a678963b93..3b7898b9e86 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs @@ -1,7 +1,7 @@ //! Module responsible for analyzing the code surrounding the cursor for completion. use std::iter; -use hir::{Semantics, Type, TypeInfo, Variant}; +use hir::{ExpandResult, Semantics, Type, TypeInfo, Variant}; use ide_db::{active_parameter::ActiveParameter, RootDatabase}; use itertools::Either; use syntax::{ @@ -104,7 +104,10 @@ fn expand( // maybe parent items have attributes, so continue walking the ancestors (None, None) => continue 'ancestors, // successful expansions - (Some(actual_expansion), Some((fake_expansion, fake_mapped_token))) => { + ( + Some(ExpandResult { value: actual_expansion, err: _ }), + Some((fake_expansion, fake_mapped_token)), + ) => { let new_offset = fake_mapped_token.text_range().start(); if new_offset + relative_offset > actual_expansion.text_range().end() { // offset outside of bounds from the original expansion, @@ -239,8 +242,8 @@ fn expand( }; match ( - sema.expand(&actual_macro_call), - sema.speculative_expand( + sema.expand_macro_call(&actual_macro_call), + sema.speculative_expand_macro_call( &actual_macro_call, &speculative_args, fake_ident_token.clone(), 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 b97dfb3b8ef..14af22c3193 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 @@ -1,9 +1,16 @@ //! Generated by `cargo codegen lint-definitions`, do not edit by hand. +use span::Edition; + +use crate::Severity; + #[derive(Clone)] pub struct Lint { pub label: &'static str, pub description: &'static str, + pub default_severity: Severity, + pub warn_since: Option<Edition>, + pub deny_since: Option<Edition>, } pub struct LintGroup { @@ -13,802 +20,1631 @@ pub struct LintGroup { pub const DEFAULT_LINTS: &[Lint] = &[ Lint { + label: "abi_unsupported_vector_types", + description: r##"this function call or definition uses a vector type which is not enabled"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { label: "absolute_paths_not_starting_with_crate", description: r##"fully qualified paths that start with a module name instead of `crate`, `self`, or an extern crate name"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "ambiguous_associated_items", + description: r##"ambiguous associated items"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, - Lint { label: "ambiguous_associated_items", description: r##"ambiguous associated items"## }, Lint { label: "ambiguous_glob_imports", description: r##"detects certain glob imports that require reporting an ambiguity error"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "ambiguous_glob_reexports", + description: r##"ambiguous glob re-exports"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "ambiguous_negative_literals", + description: r##"ambiguous negative literals operations"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "ambiguous_glob_reexports", description: r##"ambiguous glob re-exports"## }, Lint { label: "ambiguous_wide_pointer_comparisons", description: r##"detects ambiguous wide pointer comparisons"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "anonymous_parameters", + description: r##"detects anonymous parameters"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "arithmetic_overflow", + description: r##"arithmetic operation overflows"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, - Lint { label: "anonymous_parameters", description: r##"detects anonymous parameters"## }, - Lint { label: "arithmetic_overflow", description: r##"arithmetic operation overflows"## }, Lint { label: "array_into_iter", description: r##"detects calling `into_iter` on arrays in Rust 2015 and 2018"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "asm_sub_register", description: r##"using only a subset of a register for inline asm inputs"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "async_fn_in_trait", description: r##"use of `async fn` in definition of a publicly-reachable trait"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "bad_asm_style", + description: r##"incorrect use of inline assembly"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, - Lint { label: "bad_asm_style", description: r##"incorrect use of inline assembly"## }, Lint { label: "bare_trait_objects", description: r##"suggest using `dyn Trait` for trait objects"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "binary_asm_labels", + description: r##"labels in inline assembly containing only 0 or 1 digits"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "bindings_with_variant_name", description: r##"detects pattern bindings with the same name as one of the matched variants"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "boxed_slice_into_iter", description: r##"detects calling `into_iter` on boxed slices in Rust 2015, 2018, and 2021"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "break_with_label_and_loop", description: r##"`break` expression with label and unlabeled loop as value expression"##, - }, - Lint { - label: "byte_slice_in_packed_struct_with_derive", - description: r##"`[u8]` or `str` used in a packed struct with `derive`"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "cenum_impl_drop_cast", description: r##"a C-like enum implementing Drop is cast"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "clashing_extern_declarations", description: r##"detects when an extern fn has been declared with the same name but different types"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "closure_returning_async_block", + description: r##"closure that returns `async {}` could be rewritten as an async closure"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "coherence_leak_check", description: r##"distinct impls distinguished only by the leak-check code"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "conflicting_repr_hints", description: r##"conflicts between `#[repr(..)]` hints that were previously accepted and used in practice"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "confusable_idents", description: r##"detects visually confusable pairs between identifiers"##, - }, - Lint { - label: "const_eval_mutable_ptr_in_final_value", - description: r##"detects a mutable pointer that has leaked into final value of a const expression"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "const_evaluatable_unchecked", description: r##"detects a generic constant is used in a type without a emitting a warning"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "const_item_mutation", description: r##"detects attempts to mutate a `const` item"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "dangling_pointers_from_temporaries", + description: r##"detects getting a pointer from a temporary"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "dead_code", + description: r##"detect unused, unexported items"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, - Lint { label: "dead_code", description: r##"detect unused, unexported items"## }, Lint { label: "dependency_on_unit_never_type_fallback", description: r##"never type fallback affecting unsafe function calls"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, - Lint { label: "deprecated", description: r##"detects use of deprecated items"## }, Lint { - label: "deprecated_cfg_attr_crate_type_name", - description: r##"detects usage of `#![cfg_attr(..., crate_type/crate_name = "...")]`"##, + label: "deprecated", + description: r##"detects use of deprecated items"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "deprecated_in_future", description: r##"detects use of items that will be deprecated in a future version"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "deprecated_safe", + label: "deprecated_safe_2024", description: r##"detects unsafe functions being used as safe functions"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "deprecated_where_clause_location", description: r##"deprecated where clause location"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "deref_into_dyn_supertrait", description: r##"`Deref` implementation usage with a supertrait trait object for output might be shadowed in the future"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "deref_nullptr", description: r##"detects when an null pointer is dereferenced"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "drop_bounds", description: r##"bounds of the form `T: Drop` are most likely incorrect"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "dropping_copy_types", description: r##"calls to `std::mem::drop` with a value that implements Copy"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "dropping_references", description: r##"calls to `std::mem::drop` with a reference instead of an owned value"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "duplicate_macro_attributes", + description: r##"duplicated attribute"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, - Lint { label: "duplicate_macro_attributes", description: r##"duplicated attribute"## }, Lint { label: "dyn_drop", description: r##"trait objects of the form `dyn Drop` are useless"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "edition_2024_expr_fragment_specifier", + description: r##"The `expr` fragment specifier will accept more expressions in the 2024 edition. To keep the existing behavior, use the `expr_2021` fragment specifier."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "elided_lifetimes_in_associated_constant", description: r##"elided lifetimes cannot be used in associated constants in impls"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "elided_lifetimes_in_paths", description: r##"hidden lifetime parameters in types are deprecated"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "elided_named_lifetimes", + description: r##"detects when an elided lifetime gets resolved to be `'static` or some named parameter"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "ellipsis_inclusive_range_patterns", description: r##"`...` range patterns are deprecated"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "enum_intrinsics_non_enums", description: r##"detects calls to `core::mem::discriminant` and `core::mem::variant_count` with non-enum types"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, + }, + Lint { + label: "explicit_builtin_cfgs_in_flags", + description: r##"detects builtin cfgs set via the `--cfg`"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "explicit_outlives_requirements", description: r##"outlives requirements can be inferred"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "exported_private_dependencies", description: r##"public interface leaks type from a private dependency"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "ffi_unwind_calls", description: r##"call to foreign functions or function pointers with FFI-unwind ABI"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "for_loops_over_fallibles", description: r##"for-looping over an `Option` or a `Result`, which is more clearly expressed as an `if let`"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "forbidden_lint_groups", + description: r##"applying forbid to lint-groups"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, - Lint { label: "forbidden_lint_groups", description: r##"applying forbid to lint-groups"## }, Lint { label: "forgetting_copy_types", description: r##"calls to `std::mem::forget` with a value that implements Copy"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "forgetting_references", description: r##"calls to `std::mem::forget` with a reference instead of an owned value"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "function_item_references", description: r##"suggest casting to a function pointer when attempting to take references to function items"##, - }, - Lint { - label: "future_incompatible", - description: r##"lint group for: deref-into-dyn-supertrait, ambiguous-associated-items, ambiguous-glob-imports, byte-slice-in-packed-struct-with-derive, cenum-impl-drop-cast, coherence-leak-check, conflicting-repr-hints, const-eval-mutable-ptr-in-final-value, const-evaluatable-unchecked, dependency-on-unit-never-type-fallback, deprecated-cfg-attr-crate-type-name, elided-lifetimes-in-associated-constant, forbidden-lint-groups, ill-formed-attribute-input, invalid-type-param-default, late-bound-lifetime-arguments, legacy-derive-helpers, macro-expanded-macro-exports-accessed-by-absolute-paths, missing-fragment-specifier, never-type-fallback-flowing-into-unsafe, order-dependent-trait-objects, out-of-scope-macro-calls, patterns-in-fns-without-body, proc-macro-derive-resolution-fallback, pub-use-of-private-extern-crate, repr-transparent-external-private-fields, self-constructor-from-outer-item, semicolon-in-expressions-from-macros, soft-unstable, uncovered-param-in-projection, uninhabited-static, unstable-name-collisions, unstable-syntax-pre-expansion, unsupported-calling-conventions, wasm-c-abi, writes-through-immutable-pointer"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "fuzzy_provenance_casts", description: r##"a fuzzy integer to pointer cast is used"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "hidden_glob_reexports", description: r##"name introduced by a private item shadows a name introduced by a public glob re-export"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "if_let_rescope", + description: r##"`if let` assigns a shorter lifetime to temporary values being pattern-matched against in Edition 2024 and rewriting in `match` is an option to preserve the semantics up to Edition 2021"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "ill_formed_attribute_input", description: r##"ill-formed attribute inputs that were previously accepted and used in practice"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "impl_trait_overcaptures", description: r##"`impl Trait` will capture more lifetimes than possibly intended in edition 2024"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "impl_trait_redundant_captures", description: r##"redundant precise-capturing `use<...>` syntax on an `impl Trait`"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "improper_ctypes", description: r##"proper use of libc types in foreign modules"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "improper_ctypes_definitions", description: r##"proper use of libc types in foreign item definitions"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "incomplete_features", description: r##"incomplete features that may function improperly in some or all cases"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "incomplete_include", + description: r##"trailing content in included file"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, - Lint { label: "incomplete_include", description: r##"trailing content in included file"## }, Lint { label: "ineffective_unstable_trait_impl", description: r##"detects `#[unstable]` on stable trait implementations for stable types"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "inline_no_sanitize", description: r##"detects incompatible use of `#[inline(always)]` and `#[no_sanitize(...)]`"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "internal_features", description: r##"internal features are not supposed to be used"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "invalid_atomic_ordering", description: r##"usage of invalid atomic ordering in atomic operations and memory fences"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "invalid_doc_attributes", description: r##"detects invalid `#[doc(...)]` attributes"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "invalid_from_utf8", description: r##"using a non UTF-8 literal in `std::str::from_utf8`"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "invalid_from_utf8_unchecked", description: r##"using a non UTF-8 literal in `std::str::from_utf8_unchecked`"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "invalid_macro_export_arguments", description: r##""invalid_parameter" isn't a valid argument for `#[macro_export]`"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "invalid_nan_comparisons", description: r##"detects invalid floating point NaN comparisons"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "invalid_reference_casting", description: r##"casts of `&T` to `&mut T` without interior mutability"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "invalid_type_param_default", description: r##"type parameter default erroneously allowed in invalid location"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "invalid_value", description: r##"an invalid value is being created (such as a null reference)"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "irrefutable_let_patterns", description: r##"detects irrefutable patterns in `if let` and `while let` statements"##, - }, - Lint { - label: "keyword_idents", - description: r##"lint group for: keyword-idents-2018, keyword-idents-2024"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "keyword_idents_2018", description: r##"detects edition keywords being used as an identifier"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "keyword_idents_2024", description: r##"detects edition keywords being used as an identifier"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "large_assignments", + description: r##"detects large moves or copies"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, - Lint { label: "large_assignments", description: r##"detects large moves or copies"## }, Lint { label: "late_bound_lifetime_arguments", description: r##"detects generic lifetime arguments in path segments with late bound lifetime parameters"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "legacy_derive_helpers", description: r##"detects derive helper attributes that are used before they are introduced"##, - }, - Lint { - label: "let_underscore", - description: r##"lint group for: let-underscore-drop, let-underscore-lock"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "let_underscore_drop", - description: r##"non-binding let on a type that implements `Drop`"##, + description: r##"non-binding let on a type that has a destructor"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "let_underscore_lock", description: r##"non-binding let on a synchronization lock"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "long_running_const_eval", description: r##"detects long const eval operations"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "lossy_provenance_casts", description: r##"a lossy pointer to integer cast is used"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "macro_expanded_macro_exports_accessed_by_absolute_paths", description: r##"macro-expanded `macro_export` macros from the current crate cannot be referred to by absolute paths"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "macro_use_extern_crate", description: r##"the `#[macro_use]` attribute is now deprecated in favor of using macros via the module system"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "map_unit_fn", description: r##"`Iterator::map` call that discard the iterator's values"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "meta_variable_misuse", description: r##"possible meta-variable misuse at macro definition"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "missing_abi", + description: r##"No declared ABI for extern declaration"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "missing_abi", description: r##"No declared ABI for extern declaration"## }, Lint { label: "missing_copy_implementations", description: r##"detects potentially-forgotten implementations of `Copy`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "missing_debug_implementations", description: r##"detects missing implementations of Debug"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "missing_docs", description: r##"detects missing documentation for public members"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "missing_fragment_specifier", description: r##"detects missing fragment specifiers in unused `macro_rules!` patterns"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "missing_unsafe_on_extern", description: r##"detects missing unsafe keyword on extern declarations"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "mixed_script_confusables", description: r##"detects Unicode scripts whose mixed script confusables codepoints are solely used"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "multiple_supertrait_upcastable", - description: r##"detect when an object-safe trait has multiple supertraits"##, + description: r##"detect when a dyn-compatible trait has multiple supertraits"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "must_not_suspend", description: r##"use of a `#[must_not_suspend]` value across a yield point"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "mutable_transmutes", description: r##"transmuting &T to &mut T is undefined behavior, even if the reference is unused"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "named_arguments_used_positionally", description: r##"named arguments in format used positionally"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "named_asm_labels", + description: r##"named labels in inline assembly"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, - Lint { label: "named_asm_labels", description: r##"named labels in inline assembly"## }, Lint { label: "never_type_fallback_flowing_into_unsafe", description: r##"never type fallback affecting unsafe function calls"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: Some(Edition::Edition2024), }, Lint { label: "no_mangle_const_items", description: r##"const items will not have their symbols exported"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, + }, + Lint { + label: "no_mangle_generic_items", + description: r##"generic items must be mangled"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "non_ascii_idents", + description: r##"detects non-ASCII identifiers"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "no_mangle_generic_items", description: r##"generic items must be mangled"## }, - Lint { label: "non_ascii_idents", description: r##"detects non-ASCII identifiers"## }, Lint { label: "non_camel_case_types", description: r##"types, variants, traits and type parameters should have camel case names"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "non_contiguous_range_endpoints", description: r##"detects off-by-one errors with exclusive range patterns"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "non_exhaustive_omitted_patterns", description: r##"detect when patterns of types marked `non_exhaustive` are missed"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "non_fmt_panics", description: r##"detect single-argument panic!() invocations in which the argument is not a format string"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "non_local_definitions", + description: r##"checks for non-local definitions"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, - Lint { label: "non_local_definitions", description: r##"checks for non-local definitions"## }, Lint { label: "non_shorthand_field_patterns", description: r##"using `Struct { x: x }` instead of `Struct { x }` in a pattern"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "non_snake_case", description: r##"variables, methods, functions, lifetime parameters and modules should have snake case names"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "non_upper_case_globals", description: r##"static constants should have uppercase identifiers"##, - }, - Lint { - label: "nonstandard_style", - description: r##"lint group for: non-camel-case-types, non-snake-case, non-upper-case-globals"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "noop_method_call", description: r##"detects the use of well-known noop methods"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "opaque_hidden_inferred_bound", description: r##"detects the use of nested `impl Trait` types in associated type bounds that are not general enough"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "order_dependent_trait_objects", description: r##"trait-object types were treated as different depending on marker-trait order"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "out_of_scope_macro_calls", description: r##"detects out of scope calls to `macro_rules` in key-value attributes"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "overflowing_literals", + description: r##"literal out of range for its type"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, - Lint { label: "overflowing_literals", description: r##"literal out of range for its type"## }, Lint { label: "overlapping_range_endpoints", description: r##"detects range patterns with overlapping endpoints"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "path_statements", + description: r##"path statements with no effect"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, - Lint { label: "path_statements", description: r##"path statements with no effect"## }, Lint { label: "patterns_in_fns_without_body", description: r##"patterns in functions without body were erroneously allowed"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "private_bounds", description: r##"private type in secondary interface of an item"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "private_interfaces", description: r##"private type in primary interface of an item"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "proc_macro_derive_resolution_fallback", description: r##"detects proc macro derives using inaccessible names from parent modules"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, + }, + Lint { + label: "ptr_cast_add_auto_to_object", + description: r##"detects `as` casts from pointers to `dyn Trait` to pointers to `dyn Trait + Auto`"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "ptr_to_integer_transmute_in_consts", + description: r##"detects pointer to integer transmutes in const functions and associated constants"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "pub_use_of_private_extern_crate", description: r##"detect public re-exports of private extern crates"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, + }, + Lint { + label: "redundant_imports", + description: r##"imports that are redundant due to being imported already"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "redundant_lifetimes", description: r##"detects lifetime parameters that are redundant because they are equal to some other named lifetime"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "redundant_semicolons", description: r##"detects unnecessary trailing semicolons"##, - }, - Lint { - label: "refining_impl_trait", - description: r##"lint group for: refining-impl-trait-reachable, refining-impl-trait-internal"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "refining_impl_trait_internal", description: r##"impl trait in impl method signature does not match trait method signature"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "refining_impl_trait_reachable", description: r##"impl trait in impl method signature does not match trait method signature"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "renamed_and_removed_lints", description: r##"lints that have been renamed or removed"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "repr_transparent_external_private_fields", description: r##"transparent type contains an external ZST that is marked #[non_exhaustive] or contains private fields"##, - }, - Lint { - label: "rust_2018_compatibility", - description: r##"lint group for: keyword-idents-2018, anonymous-parameters, absolute-paths-not-starting-with-crate, tyvar-behind-raw-pointer"##, - }, - Lint { - label: "rust_2018_idioms", - description: r##"lint group for: bare-trait-objects, unused-extern-crates, ellipsis-inclusive-range-patterns, elided-lifetimes-in-paths, explicit-outlives-requirements"##, - }, - Lint { - label: "rust_2021_compatibility", - description: r##"lint group for: ellipsis-inclusive-range-patterns, bare-trait-objects, rust-2021-incompatible-closure-captures, rust-2021-incompatible-or-patterns, rust-2021-prefixes-incompatible-syntax, rust-2021-prelude-collisions, array-into-iter, non-fmt-panics"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "rust_2021_incompatible_closure_captures", description: r##"detects closures affected by Rust 2021 changes"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "rust_2021_incompatible_or_patterns", description: r##"detects usage of old versions of or-patterns"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "rust_2021_prefixes_incompatible_syntax", description: r##"identifiers that will be parsed as a prefix in Rust 2021"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "rust_2021_prelude_collisions", description: r##"detects the usage of trait methods which are ambiguous with traits added to the prelude in future editions"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "rust_2024_compatibility", - description: r##"lint group for: keyword-idents-2024, deprecated-safe, missing-unsafe-on-extern, static-mut-refs, unsafe-attr-outside-unsafe, unsafe-op-in-unsafe-fn, boxed-slice-into-iter"##, + label: "rust_2024_guarded_string_incompatible_syntax", + description: r##"will be parsed as a guarded string in Rust 2024"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "rust_2024_incompatible_pat", description: r##"detects patterns whose meaning will change in Rust 2024"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "rust_2024_prelude_collisions", + description: r##"detects the usage of trait methods which are ambiguous with traits added to the prelude in future editions"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "self_constructor_from_outer_item", description: r##"detect unsupported use of `Self` from outer item"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "semicolon_in_expressions_from_macros", description: r##"trailing semicolon in macro body used as expression"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "single_use_lifetimes", description: r##"detects lifetime parameters that are only used once"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "soft_unstable", description: r##"a feature gate that doesn't break dependent crates"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "special_module_name", description: r##"module declarations for files with a special meaning"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "stable_features", description: r##"stable features found in `#[feature]` directive"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "static_mut_refs", description: r##"shared references or mutable references of mutable static is discouraged"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: Some(Edition::Edition2024), }, Lint { label: "suspicious_double_ref_op", description: r##"suspicious call of trait method on `&&T`"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { - label: "temporary_cstring_as_ptr", - description: r##"detects getting the inner pointer of a temporary `CString`"##, + label: "tail_expr_drop_order", + description: r##"Detect and warn on significant change in drop order in tail expression location"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "test_unstable_lint", description: r##"this unstable lint is only for testing"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "text_direction_codepoint_in_comment", description: r##"invisible directionality-changing codepoints in comment"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "text_direction_codepoint_in_literal", description: r##"detect special Unicode codepoints that affect the visual representation of text on screen, changing the direction in which text flows"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "trivial_bounds", description: r##"these bounds don't depend on an type parameters"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "trivial_casts", description: r##"detects trivial casts which could be removed"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "trivial_numeric_casts", description: r##"detects trivial casts of numeric types which could be removed"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "type_alias_bounds", description: r##"bounds in type aliases are not enforced"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "tyvar_behind_raw_pointer", description: r##"raw pointer to an inference variable"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "uncommon_codepoints", description: r##"detects uncommon Unicode codepoints in identifiers"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "unconditional_panic", description: r##"operation will cause a panic at runtime"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "unconditional_recursion", description: r##"functions that cannot return without calling themselves"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "uncovered_param_in_projection", description: r##"impl contains type parameters that are not covered"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "undefined_naked_function_abi", description: r##"undefined naked function ABI"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "undropped_manually_drops", description: r##"calls to `std::mem::drop` with `std::mem::ManuallyDrop` instead of it's inner value"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "unexpected_cfgs", description: r##"detects unexpected names and values in `#[cfg]` conditions"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "unfulfilled_lint_expectations", description: r##"unfulfilled lint expectation"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "ungated_async_fn_track_caller", description: r##"enabling track_caller on an async fn is a no-op unless the async_fn_track_caller feature is enabled"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "uninhabited_static", + description: r##"uninhabited static"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, - Lint { label: "uninhabited_static", description: r##"uninhabited static"## }, Lint { label: "unit_bindings", description: r##"binding is useless because it has the unit `()` type"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "unknown_crate_types", description: r##"unknown crate type found in `#[crate_type]` directive"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, + }, + Lint { + label: "unknown_lints", + description: r##"unrecognized lint attribute"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, - Lint { label: "unknown_lints", description: r##"unrecognized lint attribute"## }, Lint { label: "unknown_or_malformed_diagnostic_attributes", description: r##"unrecognized or malformed diagnostic attribute"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "unnameable_test_items", description: r##"detects an item that cannot be named being marked as `#[test_case]`"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "unnameable_types", description: r##"effective visibility of a type is larger than the area in which it can be named"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "unqualified_local_imports", + description: r##"`use` of a local item without leading `self::`, `super::`, or `crate::`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "unreachable_code", + description: r##"detects unreachable code paths"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "unreachable_patterns", + description: r##"detects unreachable patterns"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, - Lint { label: "unreachable_code", description: r##"detects unreachable code paths"## }, - Lint { label: "unreachable_patterns", description: r##"detects unreachable patterns"## }, Lint { label: "unreachable_pub", description: r##"`pub` items not reachable from crate root"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "unsafe_attr_outside_unsafe", description: r##"detects unsafe attributes outside of unsafe"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "unsafe_code", description: r##"usage of `unsafe` code and other potentially unsound constructs"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "unsafe_op_in_unsafe_fn", description: r##"unsafe operations in unsafe functions without an explicit unsafe block are deprecated"##, + default_severity: Severity::Allow, + warn_since: Some(Edition::Edition2024), + deny_since: None, + }, + Lint { + label: "unstable_features", + description: r##"enabling unstable features"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "unstable_features", description: r##"enabling unstable features"## }, Lint { label: "unstable_name_collisions", description: r##"detects name collision with an existing but unstable method"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "unstable_syntax_pre_expansion", description: r##"unstable syntax can change at any point in the future, causing a hard error!"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { - label: "unsupported_calling_conventions", - description: r##"use of unsupported calling convention"##, - }, - Lint { - label: "unused", - description: r##"lint group for: unused-imports, unused-variables, unused-assignments, dead-code, unused-mut, unreachable-code, unreachable-patterns, unused-must-use, unused-unsafe, path-statements, unused-attributes, unused-macros, unused-macro-rules, unused-allocation, unused-doc-comments, unused-extern-crates, unused-features, unused-labels, unused-parens, unused-braces, redundant-semicolons, map-unit-fn"##, + label: "unsupported_fn_ptr_calling_conventions", + description: r##"use of unsupported calling convention for function pointer"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "unused_allocation", description: r##"detects unnecessary allocations that can be eliminated"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "unused_assignments", description: r##"detect assignments that will never be read"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "unused_associated_type_bounds", description: r##"detects unused `Foo = Bar` bounds in `dyn Trait<Foo = Bar>`"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "unused_attributes", description: r##"detects attributes that were not used by the compiler"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "unused_braces", + description: r##"unnecessary braces around an expression"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, - Lint { label: "unused_braces", description: r##"unnecessary braces around an expression"## }, Lint { label: "unused_comparisons", description: r##"comparisons made useless by limits of the types involved"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "unused_crate_dependencies", description: r##"crate dependencies that are never used"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "unused_doc_comments", description: r##"detects doc comments that aren't used by rustdoc"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "unused_extern_crates", + description: r##"extern crates that are never used"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "unused_extern_crates", description: r##"extern crates that are never used"## }, Lint { label: "unused_features", description: r##"unused features found in crate-level `#[feature]` directives"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "unused_import_braces", description: r##"unnecessary braces around an imported item"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "unused_imports", + description: r##"imports that are never used"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "unused_labels", + description: r##"detects labels that are never used"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, - Lint { label: "unused_imports", description: r##"imports that are never used"## }, - Lint { label: "unused_labels", description: r##"detects labels that are never used"## }, Lint { label: "unused_lifetimes", description: r##"detects lifetime parameters that are never used"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "unused_macro_rules", description: r##"detects macro rules that were not used"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "unused_macros", + description: r##"detects macros that were not used"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, - Lint { label: "unused_macros", description: r##"detects macros that were not used"## }, Lint { label: "unused_must_use", description: r##"unused result of a type flagged as `#[must_use]`"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "unused_mut", description: r##"detect mut variables which don't need to be mutable"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "unused_parens", description: r##"`if`, `match`, `while` and `return` do not need parentheses"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "unused_qualifications", description: r##"detects unnecessarily qualified names"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "unused_results", description: r##"unused result of an expression in a statement"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "unused_unsafe", + description: r##"unnecessary use of an `unsafe` block"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, - Lint { label: "unused_unsafe", description: r##"unnecessary use of an `unsafe` block"## }, Lint { label: "unused_variables", description: r##"detect variables which are not used in any way"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "useless_deprecated", description: r##"detects deprecation attributes with no effect"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "useless_ptr_null_checks", description: r##"useless checking of non-null-typed pointer"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "variant_size_differences", description: r##"detects enums with widely varying variant sizes"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "warnings", description: r##"mass-change the level for lints which produce warnings"##, - }, - Lint { - label: "warnings", - description: r##"lint group for: all lints that are set to issue warnings"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "wasm_c_abi", description: r##"detects dependencies that are incompatible with the Wasm C ABI"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "while_true", description: r##"suggest using `loop { }` instead of `while true { }`"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "deprecated_safe", + description: r##"lint group for: deprecated-safe-2024"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "future_incompatible", + description: r##"lint group for: deref-into-dyn-supertrait, abi-unsupported-vector-types, ambiguous-associated-items, ambiguous-glob-imports, cenum-impl-drop-cast, coherence-leak-check, conflicting-repr-hints, const-evaluatable-unchecked, elided-lifetimes-in-associated-constant, forbidden-lint-groups, ill-formed-attribute-input, invalid-type-param-default, late-bound-lifetime-arguments, legacy-derive-helpers, macro-expanded-macro-exports-accessed-by-absolute-paths, missing-fragment-specifier, order-dependent-trait-objects, out-of-scope-macro-calls, patterns-in-fns-without-body, proc-macro-derive-resolution-fallback, ptr-cast-add-auto-to-object, pub-use-of-private-extern-crate, repr-transparent-external-private-fields, self-constructor-from-outer-item, semicolon-in-expressions-from-macros, soft-unstable, uncovered-param-in-projection, uninhabited-static, unstable-name-collisions, unstable-syntax-pre-expansion, unsupported-fn-ptr-calling-conventions, wasm-c-abi"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "keyword_idents", + description: r##"lint group for: keyword-idents-2018, keyword-idents-2024"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "let_underscore", + description: r##"lint group for: let-underscore-drop, let-underscore-lock"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "nonstandard_style", + description: r##"lint group for: non-camel-case-types, non-snake-case, non-upper-case-globals"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "writes_through_immutable_pointer", - description: r##"shared references are immutable, and pointers derived from them must not be written to"##, + label: "refining_impl_trait", + description: r##"lint group for: refining-impl-trait-reachable, refining-impl-trait-internal"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "rust_2018_compatibility", + description: r##"lint group for: keyword-idents-2018, anonymous-parameters, absolute-paths-not-starting-with-crate, tyvar-behind-raw-pointer"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "rust_2018_idioms", + description: r##"lint group for: bare-trait-objects, unused-extern-crates, ellipsis-inclusive-range-patterns, elided-lifetimes-in-paths, explicit-outlives-requirements"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "rust_2021_compatibility", + description: r##"lint group for: ellipsis-inclusive-range-patterns, array-into-iter, non-fmt-panics, bare-trait-objects, rust-2021-incompatible-closure-captures, rust-2021-incompatible-or-patterns, rust-2021-prefixes-incompatible-syntax, rust-2021-prelude-collisions"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "rust_2024_compatibility", + description: r##"lint group for: keyword-idents-2024, edition-2024-expr-fragment-specifier, boxed-slice-into-iter, impl-trait-overcaptures, if-let-rescope, static-mut-refs, dependency-on-unit-never-type-fallback, deprecated-safe-2024, missing-unsafe-on-extern, never-type-fallback-flowing-into-unsafe, rust-2024-guarded-string-incompatible-syntax, rust-2024-incompatible-pat, rust-2024-prelude-collisions, tail-expr-drop-order, unsafe-attr-outside-unsafe, unsafe-op-in-unsafe-fn"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "unused", + description: r##"lint group for: unused-imports, unused-variables, unused-assignments, dead-code, unused-mut, unreachable-code, unreachable-patterns, unused-must-use, unused-unsafe, path-statements, unused-attributes, unused-macros, unused-macro-rules, unused-allocation, unused-doc-comments, unused-extern-crates, unused-features, unused-labels, unused-parens, unused-braces, redundant-semicolons, map-unit-fn"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "warnings", + description: r##"lint group for: all lints that are set to issue warnings"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, ]; pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &[ LintGroup { lint: Lint { + label: "deprecated_safe", + description: r##"lint group for: deprecated-safe-2024"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + children: &["deprecated_safe_2024"], + }, + LintGroup { + lint: Lint { label: "future_incompatible", - description: r##"lint group for: deref-into-dyn-supertrait, ambiguous-associated-items, ambiguous-glob-imports, byte-slice-in-packed-struct-with-derive, cenum-impl-drop-cast, coherence-leak-check, conflicting-repr-hints, const-eval-mutable-ptr-in-final-value, const-evaluatable-unchecked, dependency-on-unit-never-type-fallback, deprecated-cfg-attr-crate-type-name, elided-lifetimes-in-associated-constant, forbidden-lint-groups, ill-formed-attribute-input, invalid-type-param-default, late-bound-lifetime-arguments, legacy-derive-helpers, macro-expanded-macro-exports-accessed-by-absolute-paths, missing-fragment-specifier, never-type-fallback-flowing-into-unsafe, order-dependent-trait-objects, out-of-scope-macro-calls, patterns-in-fns-without-body, proc-macro-derive-resolution-fallback, pub-use-of-private-extern-crate, repr-transparent-external-private-fields, self-constructor-from-outer-item, semicolon-in-expressions-from-macros, soft-unstable, uncovered-param-in-projection, uninhabited-static, unstable-name-collisions, unstable-syntax-pre-expansion, unsupported-calling-conventions, wasm-c-abi, writes-through-immutable-pointer"##, + description: r##"lint group for: deref-into-dyn-supertrait, abi-unsupported-vector-types, ambiguous-associated-items, ambiguous-glob-imports, cenum-impl-drop-cast, coherence-leak-check, conflicting-repr-hints, const-evaluatable-unchecked, elided-lifetimes-in-associated-constant, forbidden-lint-groups, ill-formed-attribute-input, invalid-type-param-default, late-bound-lifetime-arguments, legacy-derive-helpers, macro-expanded-macro-exports-accessed-by-absolute-paths, missing-fragment-specifier, order-dependent-trait-objects, out-of-scope-macro-calls, patterns-in-fns-without-body, proc-macro-derive-resolution-fallback, ptr-cast-add-auto-to-object, pub-use-of-private-extern-crate, repr-transparent-external-private-fields, self-constructor-from-outer-item, semicolon-in-expressions-from-macros, soft-unstable, uncovered-param-in-projection, uninhabited-static, unstable-name-collisions, unstable-syntax-pre-expansion, unsupported-fn-ptr-calling-conventions, wasm-c-abi"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, children: &[ "deref_into_dyn_supertrait", + "abi_unsupported_vector_types", "ambiguous_associated_items", "ambiguous_glob_imports", - "byte_slice_in_packed_struct_with_derive", "cenum_impl_drop_cast", "coherence_leak_check", "conflicting_repr_hints", - "const_eval_mutable_ptr_in_final_value", "const_evaluatable_unchecked", - "dependency_on_unit_never_type_fallback", - "deprecated_cfg_attr_crate_type_name", "elided_lifetimes_in_associated_constant", "forbidden_lint_groups", "ill_formed_attribute_input", @@ -817,11 +1653,11 @@ pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &[ "legacy_derive_helpers", "macro_expanded_macro_exports_accessed_by_absolute_paths", "missing_fragment_specifier", - "never_type_fallback_flowing_into_unsafe", "order_dependent_trait_objects", "out_of_scope_macro_calls", "patterns_in_fns_without_body", "proc_macro_derive_resolution_fallback", + "ptr_cast_add_auto_to_object", "pub_use_of_private_extern_crate", "repr_transparent_external_private_fields", "self_constructor_from_outer_item", @@ -831,15 +1667,17 @@ pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &[ "uninhabited_static", "unstable_name_collisions", "unstable_syntax_pre_expansion", - "unsupported_calling_conventions", + "unsupported_fn_ptr_calling_conventions", "wasm_c_abi", - "writes_through_immutable_pointer", ], }, LintGroup { lint: Lint { label: "keyword_idents", description: r##"lint group for: keyword-idents-2018, keyword-idents-2024"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, children: &["keyword_idents_2018", "keyword_idents_2024"], }, @@ -847,6 +1685,9 @@ pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &[ lint: Lint { label: "let_underscore", description: r##"lint group for: let-underscore-drop, let-underscore-lock"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, children: &["let_underscore_drop", "let_underscore_lock"], }, @@ -854,6 +1695,9 @@ pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &[ lint: Lint { label: "nonstandard_style", description: r##"lint group for: non-camel-case-types, non-snake-case, non-upper-case-globals"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, children: &["non_camel_case_types", "non_snake_case", "non_upper_case_globals"], }, @@ -861,6 +1705,9 @@ pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &[ lint: Lint { label: "refining_impl_trait", description: r##"lint group for: refining-impl-trait-reachable, refining-impl-trait-internal"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, children: &["refining_impl_trait_reachable", "refining_impl_trait_internal"], }, @@ -868,6 +1715,9 @@ pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &[ lint: Lint { label: "rust_2018_compatibility", description: r##"lint group for: keyword-idents-2018, anonymous-parameters, absolute-paths-not-starting-with-crate, tyvar-behind-raw-pointer"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, children: &[ "keyword_idents_2018", @@ -880,6 +1730,9 @@ pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &[ lint: Lint { label: "rust_2018_idioms", description: r##"lint group for: bare-trait-objects, unused-extern-crates, ellipsis-inclusive-range-patterns, elided-lifetimes-in-paths, explicit-outlives-requirements"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, children: &[ "bare_trait_objects", @@ -892,38 +1745,56 @@ pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &[ LintGroup { lint: Lint { label: "rust_2021_compatibility", - description: r##"lint group for: ellipsis-inclusive-range-patterns, bare-trait-objects, rust-2021-incompatible-closure-captures, rust-2021-incompatible-or-patterns, rust-2021-prefixes-incompatible-syntax, rust-2021-prelude-collisions, array-into-iter, non-fmt-panics"##, + description: r##"lint group for: ellipsis-inclusive-range-patterns, array-into-iter, non-fmt-panics, bare-trait-objects, rust-2021-incompatible-closure-captures, rust-2021-incompatible-or-patterns, rust-2021-prefixes-incompatible-syntax, rust-2021-prelude-collisions"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, children: &[ "ellipsis_inclusive_range_patterns", + "array_into_iter", + "non_fmt_panics", "bare_trait_objects", "rust_2021_incompatible_closure_captures", "rust_2021_incompatible_or_patterns", "rust_2021_prefixes_incompatible_syntax", "rust_2021_prelude_collisions", - "array_into_iter", - "non_fmt_panics", ], }, LintGroup { lint: Lint { label: "rust_2024_compatibility", - description: r##"lint group for: keyword-idents-2024, deprecated-safe, missing-unsafe-on-extern, static-mut-refs, unsafe-attr-outside-unsafe, unsafe-op-in-unsafe-fn, boxed-slice-into-iter"##, + description: r##"lint group for: keyword-idents-2024, edition-2024-expr-fragment-specifier, boxed-slice-into-iter, impl-trait-overcaptures, if-let-rescope, static-mut-refs, dependency-on-unit-never-type-fallback, deprecated-safe-2024, missing-unsafe-on-extern, never-type-fallback-flowing-into-unsafe, rust-2024-guarded-string-incompatible-syntax, rust-2024-incompatible-pat, rust-2024-prelude-collisions, tail-expr-drop-order, unsafe-attr-outside-unsafe, unsafe-op-in-unsafe-fn"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, children: &[ "keyword_idents_2024", - "deprecated_safe", - "missing_unsafe_on_extern", + "edition_2024_expr_fragment_specifier", + "boxed_slice_into_iter", + "impl_trait_overcaptures", + "if_let_rescope", "static_mut_refs", + "dependency_on_unit_never_type_fallback", + "deprecated_safe_2024", + "missing_unsafe_on_extern", + "never_type_fallback_flowing_into_unsafe", + "rust_2024_guarded_string_incompatible_syntax", + "rust_2024_incompatible_pat", + "rust_2024_prelude_collisions", + "tail_expr_drop_order", "unsafe_attr_outside_unsafe", "unsafe_op_in_unsafe_fn", - "boxed_slice_into_iter", ], }, LintGroup { lint: Lint { label: "unused", description: r##"lint group for: unused-imports, unused-variables, unused-assignments, dead-code, unused-mut, unreachable-code, unreachable-patterns, unused-must-use, unused-unsafe, path-statements, unused-attributes, unused-macros, unused-macro-rules, unused-allocation, unused-doc-comments, unused-extern-crates, unused-features, unused-labels, unused-parens, unused-braces, redundant-semicolons, map-unit-fn"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, children: &[ "unused_imports", @@ -950,64 +1821,99 @@ pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &[ "map_unit_fn", ], }, - LintGroup { - lint: Lint { - label: "warnings", - description: r##"lint group for: all lints that are set to issue warnings"##, - }, - children: &[], - }, ]; pub const RUSTDOC_LINTS: &[Lint] = &[ Lint { - label: "rustdoc::all", - description: r##"lint group for: rustdoc::broken-intra-doc-links, rustdoc::private-intra-doc-links, rustdoc::private-doc-tests, rustdoc::invalid-codeblock-attributes, rustdoc::invalid-rust-codeblocks, rustdoc::invalid-html-tags, rustdoc::bare-urls, rustdoc::missing-crate-level-docs, rustdoc::unescaped-backticks, rustdoc::redundant-explicit-links, rustdoc::unportable-markdown"##, + label: "rustdoc::bare_urls", + description: r##"detects URLs that are not hyperlinks"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, - Lint { label: "rustdoc::bare_urls", description: r##"detects URLs that are not hyperlinks"## }, Lint { label: "rustdoc::broken_intra_doc_links", description: r##"failures in resolving intra-doc link targets"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "rustdoc::invalid_codeblock_attributes", description: r##"codeblock attribute looks a lot like a known one"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "rustdoc::invalid_html_tags", description: r##"detects invalid HTML tags in doc comments"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "rustdoc::invalid_rust_codeblocks", description: r##"codeblock could not be parsed as valid Rust or is empty"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "rustdoc::missing_crate_level_docs", description: r##"detects crates with no crate-level documentation"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "rustdoc::missing_doc_code_examples", description: r##"detects publicly-exported items without code samples in their documentation"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "rustdoc::private_doc_tests", description: r##"detects code samples in docs of private items not documented by rustdoc"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "rustdoc::private_intra_doc_links", description: r##"linking from a public item to a private one"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "rustdoc::redundant_explicit_links", description: r##"detects redundant explicit links in doc comments"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "rustdoc::unescaped_backticks", description: r##"detects unescaped backticks in doc comments"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "rustdoc::unportable_markdown", description: r##"detects markdown that is interpreted differently in different parser"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "rustdoc::all", + description: r##"lint group for: rustdoc::broken-intra-doc-links, rustdoc::private-intra-doc-links, rustdoc::private-doc-tests, rustdoc::invalid-codeblock-attributes, rustdoc::invalid-rust-codeblocks, rustdoc::invalid-html-tags, rustdoc::bare-urls, rustdoc::missing-crate-level-docs, rustdoc::unescaped-backticks, rustdoc::redundant-explicit-links, rustdoc::unportable-markdown"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, ]; @@ -1015,6 +1921,9 @@ pub const RUSTDOC_LINT_GROUPS: &[LintGroup] = &[LintGroup { lint: Lint { label: "rustdoc::all", description: r##"lint group for: rustdoc::broken-intra-doc-links, rustdoc::private-intra-doc-links, rustdoc::private-doc-tests, rustdoc::invalid-codeblock-attributes, rustdoc::invalid-rust-codeblocks, rustdoc::invalid-html-tags, rustdoc::bare-urls, rustdoc::missing-crate-level-docs, rustdoc::unescaped-backticks, rustdoc::redundant-explicit-links, rustdoc::unportable-markdown"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, children: &[ "rustdoc::broken_intra_doc_links", @@ -1033,6 +1942,20 @@ pub const RUSTDOC_LINT_GROUPS: &[LintGroup] = &[LintGroup { pub const FEATURES: &[Lint] = &[ Lint { + label: "aarch64_unstable_target_feature", + description: r##"# `aarch64_unstable_target_feature` + +The tracking issue for this feature is: [#44839] + +[#44839]: https://github.com/rust-lang/rust/issues/44839 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "aarch64_ver_target_feature", description: r##"# `aarch64_ver_target_feature` @@ -1042,6 +1965,9 @@ The tracking issue for this feature is: [#44839] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "abi_avr_interrupt", @@ -1053,6 +1979,9 @@ The tracking issue for this feature is: [#69664] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "abi_c_cmse_nonsecure_call", @@ -1145,6 +2074,9 @@ call_nonsecure_function: pop {r7, pc} ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "abi_msp430_interrupt", @@ -1191,6 +2123,9 @@ Disassembly of section .text: c000: 00 13 reti ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "abi_ptx", @@ -1255,6 +2190,9 @@ $ cat $(find -name '*.s') } ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "abi_riscv_interrupt", @@ -1266,6 +2204,9 @@ The tracking issue for this feature is: [#111889] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "abi_unadjusted", @@ -1275,6 +2216,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "abi_vectorcall", @@ -1298,6 +2242,9 @@ fn main() { } ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "abi_x86_interrupt", @@ -1309,6 +2256,23 @@ The tracking issue for this feature is: [#40180] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "abort_unwind", + description: r##"# `abort_unwind` + +The tracking issue for this feature is: [#130338] + +[#130338]: https://github.com/rust-lang/rust/issues/130338 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "acceptfilter", @@ -1320,6 +2284,9 @@ The tracking issue for this feature is: [#121891] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "addr_parse_ascii", @@ -1331,6 +2298,9 @@ The tracking issue for this feature is: [#101035] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "adt_const_params", @@ -1370,6 +2340,9 @@ fn is_foo_a_and_bar_true<const F: Foo, const B: Bar>() -> bool { } ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "alloc_error_handler", @@ -1381,6 +2354,9 @@ The tracking issue for this feature is: [#51540] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "alloc_error_hook", @@ -1392,6 +2368,9 @@ The tracking issue for this feature is: [#51245] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "alloc_internals", @@ -1401,6 +2380,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "alloc_layout_extra", @@ -1412,6 +2394,9 @@ The tracking issue for this feature is: [#55724] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "allocator_api", @@ -1431,6 +2416,9 @@ for which you want a custom allocator. TBD "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "allocator_internals", @@ -1442,6 +2430,9 @@ compiler. ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "allow_internal_unsafe", @@ -1451,6 +2442,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "allow_internal_unstable", @@ -1460,6 +2454,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "anonymous_lifetime_in_impl_trait", @@ -1469,6 +2466,23 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "anonymous_pipe", + description: r##"# `anonymous_pipe` + +The tracking issue for this feature is: [#127154] + +[#127154]: https://github.com/rust-lang/rust/issues/127154 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "arbitrary_self_types", @@ -1480,6 +2494,23 @@ The tracking issue for this feature is: [#44874] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "arbitrary_self_types_pointers", + description: r##"# `arbitrary_self_types_pointers` + +The tracking issue for this feature is: [#44874] + +[#44874]: https://github.com/rust-lang/rust/issues/44874 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "arm_target_feature", @@ -1491,6 +2522,9 @@ The tracking issue for this feature is: [#44839] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "array_chunks", @@ -1502,6 +2536,9 @@ The tracking issue for this feature is: [#74985] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "array_into_iter_constructors", @@ -1513,6 +2550,9 @@ The tracking issue for this feature is: [#91583] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "array_ptr_get", @@ -1524,6 +2564,9 @@ The tracking issue for this feature is: [#119834] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "array_repeat", @@ -1535,6 +2578,9 @@ The tracking issue for this feature is: [#126695] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "array_try_from_fn", @@ -1546,6 +2592,9 @@ The tracking issue for this feature is: [#89379] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "array_try_map", @@ -1557,6 +2606,9 @@ The tracking issue for this feature is: [#79711] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "array_windows", @@ -1568,6 +2620,9 @@ The tracking issue for this feature is: [#75027] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "as_array_of_cells", @@ -1579,6 +2634,9 @@ The tracking issue for this feature is: [#88248] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "ascii_char", @@ -1590,6 +2648,9 @@ The tracking issue for this feature is: [#110998] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "ascii_char_variants", @@ -1601,21 +2662,9 @@ The tracking issue for this feature is: [#110998] ------------------------ "##, - }, - Lint { - label: "asm_const", - description: r##"# `asm_const` - -The tracking issue for this feature is: [#93332] - -[#93332]: https://github.com/rust-lang/rust/issues/93332 - ------------------------- - -This feature adds a `const <expr>` operand type to `asm!` and `global_asm!`. -- `<expr>` must be an integer constant expression. -- The value of the expression is formatted as a string and substituted directly into the asm template string. -"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "asm_experimental_arch", @@ -1639,8 +2688,7 @@ This feature tracks `asm!` and `global_asm!` support for the following architect - MSP430 - M68k - CSKY -- s390x -- Arm64EC +- SPARC ## Register classes @@ -1652,9 +2700,11 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | NVPTX | `reg32` | None\* | `r` | | NVPTX | `reg64` | None\* | `l` | | Hexagon | `reg` | `r[0-28]` | `r` | -| PowerPC | `reg` | `r[0-31]` | `r` | -| PowerPC | `reg_nonzero` | `r[1-31]` | `b` | +| Hexagon | `preg` | `p[0-3]` | Only clobbers | +| PowerPC | `reg` | `r0`, `r[3-12]`, `r[14-28]` | `r` | +| PowerPC | `reg_nonzero` | `r[3-12]`, `r[14-28]` | `b` | | PowerPC | `freg` | `f[0-31]` | `f` | +| PowerPC | `vreg` | `v[0-31]` | `v` | | PowerPC | `cr` | `cr[0-7]`, `cr` | Only clobbers | | PowerPC | `xer` | `xer` | Only clobbers | | wasm32 | `local` | None\* | `r` | @@ -1671,11 +2721,8 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | M68k | `reg_addr` | `a[0-3]` | `a` | | CSKY | `reg` | `r[0-31]` | `r` | | CSKY | `freg` | `f[0-31]` | `f` | -| s390x | `reg` | `r[0-10]`, `r[12-14]` | `r` | -| s390x | `freg` | `f[0-15]` | `f` | -| Arm64EC | `reg` | `x[0-12]`, `x[15-22]`, `x[25-27]`, `x30` | `r` | -| Arm64EC | `vreg` | `v[0-15]` | `w` | -| Arm64EC | `vreg_low16` | `v[0-15]` | `x` | +| SPARC | `reg` | `r[2-29]` | `r` | +| SPARC | `yreg` | `y` | Only clobbers | > **Notes**: > - NVPTX doesn't have a fixed register set, so named registers are not supported. @@ -1694,9 +2741,12 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | NVPTX | `reg32` | None | `i8`, `i16`, `i32`, `f32` | | NVPTX | `reg64` | None | `i8`, `i16`, `i32`, `f32`, `i64`, `f64` | | Hexagon | `reg` | None | `i8`, `i16`, `i32`, `f32` | -| PowerPC | `reg` | None | `i8`, `i16`, `i32` | -| PowerPC | `reg_nonzero` | None | `i8`, `i16`, `i32` | +| Hexagon | `preg` | N/A | Only clobbers | +| PowerPC | `reg` | None | `i8`, `i16`, `i32`, `i64` (powerpc64 only) | +| PowerPC | `reg_nonzero` | None | `i8`, `i16`, `i32`, `i64` (powerpc64 only) | | PowerPC | `freg` | None | `f32`, `f64` | +| PowerPC | `vreg` | `altivec` | `i8x16`, `i16x8`, `i32x4`, `f32x4` | +| PowerPC | `vreg` | `vsx` | `f32`, `f64`, `i64x2`, `f64x2` | | PowerPC | `cr` | N/A | Only clobbers | | PowerPC | `xer` | N/A | Only clobbers | | wasm32 | `local` | None | `i8` `i16` `i32` `i64` `f32` `f64` | @@ -1709,10 +2759,8 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | M68k | `reg_data` | None | `i8`, `i16`, `i32` | | CSKY | `reg` | None | `i8`, `i16`, `i32` | | CSKY | `freg` | None | `f32`, | -| s390x | `reg`, `reg_addr` | None | `i8`, `i16`, `i32`, `i64` | -| s390x | `freg` | None | `f32`, `f64` | -| Arm64EC | `reg` | None | `i8`, `i16`, `i32`, `f32`, `i64`, `f64` | -| Arm64EC | `vreg` | None | `i8`, `i16`, `i32`, `f32`, `i64`, `f64`, <br> `i8x8`, `i16x4`, `i32x2`, `i64x1`, `f32x2`, `f64x1`, <br> `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` | +| SPARC | `reg` | None | `i8`, `i16`, `i32`, `i64` (SPARC64 only) | +| SPARC | `yreg` | N/A | Only clobbers | ## Register aliases @@ -1721,6 +2769,10 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | Hexagon | `r29` | `sp` | | Hexagon | `r30` | `fr` | | Hexagon | `r31` | `lr` | +| PowerPC | `r1` | `sp` | +| PowerPC | `r31` | `fp` | +| PowerPC | `r[0-31]` | `[0-31]` | +| PowerPC | `f[0-31]` | `fr[0-31]`| | BPF | `r[0-10]` | `w[0-10]` | | AVR | `XH` | `r27` | | AVR | `XL` | `r26` | @@ -1745,12 +2797,10 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | CSKY | `r29` | `rtb` | | CSKY | `r30` | `svbr` | | CSKY | `r31` | `tls` | -| Arm64EC | `x[0-30]` | `w[0-30]` | -| Arm64EC | `x29` | `fp` | -| Arm64EC | `x30` | `lr` | -| Arm64EC | `sp` | `wsp` | -| Arm64EC | `xzr` | `wzr` | -| Arm64EC | `v[0-15]` | `b[0-15]`, `h[0-15]`, `s[0-15]`, `d[0-15]`, `q[0-15]` | +| SPARC | `r[0-7]` | `g[0-7]` | +| SPARC | `r[8-15]` | `o[0-7]` | +| SPARC | `r[16-23]` | `l[0-7]` | +| SPARC | `r[24-31]` | `i[0-7]` | > **Notes**: > - TI does not mandate a frame pointer for MSP430, but toolchains are allowed @@ -1760,15 +2810,19 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | Architecture | Unsupported register | Reason | | ------------ | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| All | `sp`, `r15` (s390x) | The stack pointer must be restored to its original value at the end of an asm code block. | -| All | `fr` (Hexagon), `$fp` (MIPS), `Y` (AVR), `r4` (MSP430), `a6` (M68k), `r11` (s390x), `x29` (Arm64EC) | The frame pointer cannot be used as an input or output. | -| All | `r19` (Hexagon), `x19` (Arm64EC) | This is used internally by LLVM as a "base pointer" for functions with complex stack frames. | +| All | `sp`, `r14`/`o6` (SPARC) | The stack pointer must be restored to its original value at the end of an asm code block. | +| All | `fr` (Hexagon), `fp` (PowerPC), `$fp` (MIPS), `Y` (AVR), `r4` (MSP430), `a6` (M68k), `r30`/`i6` (SPARC) | The frame pointer cannot be used as an input or output. | +| All | `r19` (Hexagon), `r29` (PowerPC), `r30` (PowerPC) | These are used internally by LLVM as "base pointer" for functions with complex stack frames. | | MIPS | `$0` or `$zero` | This is a constant zero register which can't be modified. | | MIPS | `$1` or `$at` | Reserved for assembler. | | MIPS | `$26`/`$k0`, `$27`/`$k1` | OS-reserved registers. | | MIPS | `$28`/`$gp` | Global pointer cannot be used as inputs or outputs. | | MIPS | `$ra` | Return address cannot be used as inputs or outputs. | | Hexagon | `lr` | This is the link register which cannot be used as an input or output. | +| PowerPC | `r2`, `r13` | These are system reserved registers. | +| PowerPC | `lr` | The link register cannot be used as an input or output. | +| PowerPC | `ctr` | The counter register cannot be used as an input or output. | +| PowerPC | `vrsave` | The vrsave register cannot be used as an input or output. | | AVR | `r0`, `r1`, `r1r0` | Due to an issue in LLVM, the `r0` and `r1` registers cannot be used as inputs or outputs. If modified, they must be restored to their original values before the end of the block. | |MSP430 | `r0`, `r2`, `r3` | These are the program counter, status register, and constant generator respectively. Neither the status register nor constant generator can be written to. | | M68k | `a4`, `a5` | Used internally by LLVM for the base pointer and global base pointer. | @@ -1778,9 +2832,11 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | CSKY | `r15` | This is the link register. | | CSKY | `r[26-30]` | Reserved by its ABI. | | CSKY | `r31` | This is the TLS register. | -| Arm64EC | `xzr` | This is a constant zero register which can't be modified. | -| Arm64EC | `x18` | This is an OS-reserved register. | -| Arm64EC | `x13`, `x14`, `x23`, `x24`, `x28`, `v[16-31]` | These are AArch64 registers that are not supported for Arm64EC. | +| SPARC | `r0`/`g0` | This is always zero and cannot be used as inputs or outputs. | +| SPARC | `r1`/`g1` | Used internally by LLVM. | +| SPARC | `r5`/`g5` | Reserved for system. (SPARC32 only) | +| SPARC | `r6`/`g6`, `r7`/`g7` | Reserved for system. | +| SPARC | `r31`/`i7` | Return address cannot be used as inputs or outputs. | ## Template modifiers @@ -1796,21 +2852,10 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | PowerPC | `reg` | None | `0` | None | | PowerPC | `reg_nonzero` | None | `3` | None | | PowerPC | `freg` | None | `0` | None | -| s390x | `reg` | None | `%r0` | None | -| s390x | `reg_addr` | None | `%r1` | None | -| s390x | `freg` | None | `%f0` | None | +| PowerPC | `vreg` | None | `0` | None | +| SPARC | `reg` | None | `%o0` | None | | CSKY | `reg` | None | `r0` | None | | CSKY | `freg` | None | `f0` | None | -| Arm64EC | `reg` | None | `x0` | `x` | -| Arm64EC | `reg` | `w` | `w0` | `w` | -| Arm64EC | `reg` | `x` | `x0` | `x` | -| Arm64EC | `vreg` | None | `v0` | None | -| Arm64EC | `vreg` | `v` | `v0` | None | -| Arm64EC | `vreg` | `b` | `b0` | `b` | -| Arm64EC | `vreg` | `h` | `h0` | `h` | -| Arm64EC | `vreg` | `s` | `s0` | `s` | -| Arm64EC | `vreg` | `d` | `d0` | `d` | -| Arm64EC | `vreg` | `q` | `q0` | `q` | # Flags covered by `preserves_flags` @@ -1821,12 +2866,60 @@ These flags registers must be restored upon exiting the asm block if the `preser - The status register `r2`. - M68k - The condition code register `ccr`. -- s390x - - The condition code register `cc`. -- Arm64EC - - Condition flags (`NZCV` register). - - Floating-point status (`FPSR` register). +- SPARC + - Integer condition codes (`icc` and `xcc`) + - Floating-point condition codes (`fcc[0-3]`) +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "asm_experimental_reg", + description: r##"# `asm_experimental_arch` + +The tracking issue for this feature is: [#133416] + +[#133416]: https://github.com/rust-lang/rust/issues/133416 + +------------------------ + +This tracks support for additional registers in architectures where inline assembly is already stable. + +## Register classes + +| Architecture | Register class | Registers | LLVM constraint code | +| ------------ | -------------- | --------- | -------------------- | +| s390x | `vreg` | `v[0-31]` | `v` | + +> **Notes**: +> - s390x `vreg` is clobber-only in stable. + +## Register class supported types + +| Architecture | Register class | Target feature | Allowed types | +| ------------ | -------------- | -------------- | ------------- | +| s390x | `vreg` | `vector` | `i32`, `f32`, `i64`, `f64`, `i128`, `f128`, `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` | + +## Register aliases + +| Architecture | Base register | Aliases | +| ------------ | ------------- | ------- | + +## Unsupported registers + +| Architecture | Unsupported register | Reason | +| ------------ | -------------------- | ------ | + +## Template modifiers + +| Architecture | Register class | Modifier | Example output | LLVM modifier | +| ------------ | -------------- | -------- | -------------- | ------------- | +| s390x | `vreg` | None | `%v0` | None | "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "asm_goto", @@ -1853,7 +2946,9 @@ unsafe { } ``` -The block must have unit type or diverge. +The block must have unit type or diverge. The block starts a new safety context, +so despite outer `unsafe`, you need extra unsafe to perform unsafe operations +within `label <block>`. When `label <block>` is used together with `noreturn` option, it means that the assembly will not fallthrough. It's allowed to jump to a label within the @@ -1861,6 +2956,23 @@ assembly. In this case, the entire `asm!` expression will have an unit type as opposed to diverging, if not all label blocks diverge. The `asm!` expression still diverges if `noreturn` option is used and all label blocks diverge. "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "asm_goto_with_outputs", + description: r##"# `asm_goto_with_outputs` + +The tracking issue for this feature is: [#119364] + +[#119364]: https://github.com/rust-lang/rust/issues/119364 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "asm_unwind", @@ -1874,6 +2986,9 @@ The tracking issue for this feature is: [#93334] This feature adds a `may_unwind` option to `asm!` which allows an `asm` block to unwind stack and be part of the stack unwinding process. This option is only supported by the LLVM backend right now. "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "assert_matches", @@ -1885,6 +3000,9 @@ The tracking issue for this feature is: [#82775] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "associated_const_equality", @@ -1896,6 +3014,9 @@ The tracking issue for this feature is: [#92827] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "associated_type_defaults", @@ -1907,6 +3028,9 @@ The tracking issue for this feature is: [#29661] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "async_closure", @@ -1918,6 +3042,9 @@ The tracking issue for this feature is: [#62290] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "async_drop", @@ -1929,6 +3056,9 @@ The tracking issue for this feature is: [#126482] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "async_fn_track_caller", @@ -1940,6 +3070,9 @@ The tracking issue for this feature is: [#110011] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "async_fn_traits", @@ -1957,6 +3090,9 @@ for creating custom closure-like types that return futures. The main difference to the `Fn*` family of traits is that `AsyncFn` can return a future that borrows from itself (`FnOnce::Output` has no lifetime parameters, while `AsyncFnMut::CallRefFuture` does). "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "async_for_loop", @@ -1968,6 +3104,9 @@ The tracking issue for this feature is: [#118898] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "async_gen_internals", @@ -1977,6 +3116,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "async_iter_from_iter", @@ -1988,6 +3130,9 @@ The tracking issue for this feature is: [#81798] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "async_iterator", @@ -1999,6 +3144,23 @@ The tracking issue for this feature is: [#79024] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "async_trait_bounds", + description: r##"# `async_trait_bounds` + +The tracking issue for this feature is: [#62290] + +[#62290]: https://github.com/rust-lang/rust/issues/62290 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "atomic_from_mut", @@ -2010,6 +3172,9 @@ The tracking issue for this feature is: [#76314] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "auto_traits", @@ -2120,6 +3285,23 @@ Auto traits cannot have any trait items, such as methods or associated types. Th Auto traits cannot have supertraits. This is for soundness reasons, as the interaction of coinduction with implied bounds is difficult to reconcile. "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "autodiff", + description: r##"# `autodiff` + +The tracking issue for this feature is: [#124509] + +[#124509]: https://github.com/rust-lang/rust/issues/124509 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "avx512_target_feature", @@ -2131,6 +3313,9 @@ The tracking issue for this feature is: [#44839] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "backtrace_frames", @@ -2142,6 +3327,9 @@ The tracking issue for this feature is: [#79676] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "bigint_helper_methods", @@ -2153,6 +3341,9 @@ The tracking issue for this feature is: [#85532] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "binary_heap_drain_sorted", @@ -2164,6 +3355,9 @@ The tracking issue for this feature is: [#59278] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "binary_heap_into_iter_sorted", @@ -2175,6 +3369,9 @@ The tracking issue for this feature is: [#59278] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "bound_as_ref", @@ -2186,6 +3383,23 @@ The tracking issue for this feature is: [#80996] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "box_as_ptr", + description: r##"# `box_as_ptr` + +The tracking issue for this feature is: [#129090] + +[#129090]: https://github.com/rust-lang/rust/issues/129090 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "box_into_boxed_slice", @@ -2197,6 +3411,9 @@ The tracking issue for this feature is: [#71582] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "box_into_inner", @@ -2208,6 +3425,9 @@ The tracking issue for this feature is: [#80437] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "box_patterns", @@ -2242,6 +3462,37 @@ fn main() { } ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "box_uninit_write", + description: r##"# `box_uninit_write` + +The tracking issue for this feature is: [#129397] + +[#129397]: https://github.com/rust-lang/rust/issues/129397 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "box_vec_non_null", + description: r##"# `box_vec_non_null` + +The tracking issue for this feature is: [#130364] + +[#130364]: https://github.com/rust-lang/rust/issues/130364 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "bpf_target_feature", @@ -2253,6 +3504,23 @@ The tracking issue for this feature is: [#44839] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "breakpoint", + description: r##"# `breakpoint` + +The tracking issue for this feature is: [#133724] + +[#133724]: https://github.com/rust-lang/rust/issues/133724 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "btree_cursors", @@ -2264,6 +3532,23 @@ The tracking issue for this feature is: [#107540] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "btree_entry_insert", + description: r##"# `btree_entry_insert` + +The tracking issue for this feature is: [#65225] + +[#65225]: https://github.com/rust-lang/rust/issues/65225 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "btree_extract_if", @@ -2275,6 +3560,23 @@ The tracking issue for this feature is: [#70530] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "btree_set_entry", + description: r##"# `btree_set_entry` + +The tracking issue for this feature is: [#133549] + +[#133549]: https://github.com/rust-lang/rust/issues/133549 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "btreemap_alloc", @@ -2286,6 +3588,9 @@ The tracking issue for this feature is: [#32838] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "buf_read_has_data_left", @@ -2297,28 +3602,23 @@ The tracking issue for this feature is: [#86423] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "bufread_skip_until", - description: r##"# `bufread_skip_until` + label: "bufreader_peek", + description: r##"# `bufreader_peek` -The tracking issue for this feature is: [#111735] +The tracking issue for this feature is: [#128405] -[#111735]: https://github.com/rust-lang/rust/issues/111735 - ------------------------- -"##, - }, - Lint { - label: "build_hasher_default_const_new", - description: r##"# `build_hasher_default_const_new` - -The tracking issue for this feature is: [#123197] - -[#123197]: https://github.com/rust-lang/rust/issues/123197 +[#128405]: https://github.com/rust-lang/rust/issues/128405 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "builtin_syntax", @@ -2330,6 +3630,9 @@ The tracking issue for this feature is: [#110680] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "c_size_t", @@ -2341,6 +3644,9 @@ The tracking issue for this feature is: [#88345] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "c_str_module", @@ -2352,6 +3658,9 @@ The tracking issue for this feature is: [#112134] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "c_variadic", @@ -2380,6 +3689,9 @@ pub unsafe extern "C" fn add(n: usize, mut args: ...) -> usize { } ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "c_variadic", @@ -2410,6 +3722,9 @@ pub unsafe extern "C" fn vadd(n: usize, mut args: VaList) -> usize { } ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "c_void_variant", @@ -2419,6 +3734,9 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "can_vector", @@ -2430,6 +3748,9 @@ The tracking issue for this feature is: [#69941] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "cell_leak", @@ -2441,6 +3762,9 @@ The tracking issue for this feature is: [#69099] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "cell_update", @@ -2452,6 +3776,9 @@ The tracking issue for this feature is: [#50186] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "cfg_accessible", @@ -2463,6 +3790,38 @@ The tracking issue for this feature is: [#64797] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "cfg_boolean_literals", + description: r##"# `cfg_boolean_literals` + +The tracking issue for this feature is: [#131204] + +[#131204]: https://github.com/rust-lang/rust/issues/131204 + +------------------------ + +The `cfg_boolean_literals` feature makes it possible to use the `true`/`false` +literal as cfg predicate. They always evaluate to true/false respectively. + +## Examples + +```rust +#![feature(cfg_boolean_literals)] + +#[cfg(true)] +const A: i32 = 5; + +#[cfg(all(false))] +const A: i32 = 58 * 89; +``` +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "cfg_eval", @@ -2474,6 +3833,9 @@ The tracking issue for this feature is: [#82679] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "cfg_match", @@ -2485,6 +3847,9 @@ The tracking issue for this feature is: [#115585] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "cfg_overflow_checks", @@ -2496,6 +3861,9 @@ The tracking issue for this feature is: [#111466] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "cfg_relocation_model", @@ -2507,6 +3875,9 @@ The tracking issue for this feature is: [#114929] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "cfg_sanitize", @@ -2545,6 +3916,9 @@ fn b() { } ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "cfg_sanitizer_cfi", @@ -2556,6 +3930,9 @@ The tracking issue for this feature is: [#89653] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "cfg_target_compact", @@ -2567,6 +3944,9 @@ The tracking issue for this feature is: [#96901] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "cfg_target_has_atomic", @@ -2578,6 +3958,9 @@ The tracking issue for this feature is: [#94039] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "cfg_target_has_atomic_equal_alignment", @@ -2589,6 +3972,9 @@ The tracking issue for this feature is: [#93822] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "cfg_target_thread_local", @@ -2600,6 +3986,9 @@ The tracking issue for this feature is: [#29594] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "cfg_ub_checks", @@ -2611,6 +4000,9 @@ The tracking issue for this feature is: [#123499] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "cfg_version", @@ -2650,6 +4042,9 @@ fn b() { } ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "cfi_encoding", @@ -2679,17 +4074,9 @@ extern { } ``` "##, - }, - Lint { - label: "char_indices_offset", - description: r##"# `char_indices_offset` - -The tracking issue for this feature is: [#83871] - -[#83871]: https://github.com/rust-lang/rust/issues/83871 - ------------------------- -"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "char_internals", @@ -2699,17 +4086,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, - }, - Lint { - label: "char_min", - description: r##"# `char_min` - -The tracking issue for this feature is: [#114298] - -[#114298]: https://github.com/rust-lang/rust/issues/114298 - ------------------------- -"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clone_to_uninit", @@ -2721,6 +4100,9 @@ The tracking issue for this feature is: [#126799] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "closure_lifetime_binder", @@ -2732,6 +4114,9 @@ The tracking issue for this feature is: [#97362] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "closure_track_caller", @@ -2748,6 +4133,9 @@ Calls made to the closure or coroutine will have caller information available through `std::panic::Location::caller()`, just like using `#[track_caller]` on a function. "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "cmp_minmax", @@ -2759,6 +4147,9 @@ The tracking issue for this feature is: [#115939] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "cmse_nonsecure_entry", @@ -2779,10 +4170,10 @@ LLVM, the Rust compiler and the linker are providing TrustZone-M feature. One of the things provided, with this unstable feature, is the -`cmse_nonsecure_entry` attribute. This attribute marks a Secure function as an +`C-cmse-nonsecure-entry` ABI. This ABI marks a Secure function as an entry function (see [section 5.4](https://developer.arm.com/documentation/ecm0359818/latest/) for details). -With this attribute, the compiler will do the following: +With this ABI, the compiler will do the following: * add a special symbol on the function which is the `__acle_se_` prefix and the standard function name * constrain the number of parameters to avoid using the Non-Secure stack @@ -2802,11 +4193,11 @@ gateway veneer. <!-- NOTE(ignore) this example is specific to thumbv8m targets --> ``` rust,ignore +#![no_std] #![feature(cmse_nonsecure_entry)] #[no_mangle] -#[cmse_nonsecure_entry] -pub extern "C" fn entry_function(input: u32) -> u32 { +pub extern "C-cmse-nonsecure-entry" fn entry_function(input: u32) -> u32 { input + 6 } ``` @@ -2844,6 +4235,9 @@ $ arm-none-eabi-objdump -D function.o 40: defe udf #254 ; 0xfe ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "coerce_unsized", @@ -2855,6 +4249,9 @@ The tracking issue for this feature is: [#18598] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "compiler_builtins", @@ -2864,6 +4261,9 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "concat_bytes", @@ -2875,6 +4275,9 @@ The tracking issue for this feature is: [#87555] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "concat_idents", @@ -2901,39 +4304,9 @@ fn main() { } ``` "##, - }, - Lint { - label: "const_align_of_val", - description: r##"# `const_align_of_val` - -The tracking issue for this feature is: [#46571] - -[#46571]: https://github.com/rust-lang/rust/issues/46571 - ------------------------- -"##, - }, - Lint { - label: "const_align_of_val_raw", - description: r##"# `const_align_of_val_raw` - -The tracking issue for this feature is: [#46571] - -[#46571]: https://github.com/rust-lang/rust/issues/46571 - ------------------------- -"##, - }, - Lint { - label: "const_align_offset", - description: r##"# `const_align_offset` - -The tracking issue for this feature is: [#90962] - -[#90962]: https://github.com/rust-lang/rust/issues/90962 - ------------------------- -"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "const_alloc_error", @@ -2945,6 +4318,9 @@ The tracking issue for this feature is: [#92523] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "const_alloc_layout", @@ -2956,39 +4332,37 @@ The tracking issue for this feature is: [#67521] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "const_arguments_as_str", - description: r##"# `const_arguments_as_str` - -The tracking issue for this feature is: [#103900] - -[#103900]: https://github.com/rust-lang/rust/issues/103900 - ------------------------- -"##, - }, - Lint { - label: "const_array_from_ref", - description: r##"# `const_array_from_ref` + label: "const_array_as_mut_slice", + description: r##"# `const_array_as_mut_slice` -The tracking issue for this feature is: [#90206] +The tracking issue for this feature is: [#133333] -[#90206]: https://github.com/rust-lang/rust/issues/90206 +[#133333]: https://github.com/rust-lang/rust/issues/133333 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "const_array_into_iter_constructors", - description: r##"# `const_array_into_iter_constructors` + label: "const_array_each_ref", + description: r##"# `const_array_each_ref` -The tracking issue for this feature is: [#91583] +The tracking issue for this feature is: [#133289] -[#91583]: https://github.com/rust-lang/rust/issues/91583 +[#133289]: https://github.com/rust-lang/rust/issues/133289 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "const_async_blocks", @@ -3000,39 +4374,9 @@ The tracking issue for this feature is: [#85368] ------------------------ "##, - }, - Lint { - label: "const_atomic_from_ptr", - description: r##"# `const_atomic_from_ptr` - -The tracking issue for this feature is: [#108652] - -[#108652]: https://github.com/rust-lang/rust/issues/108652 - ------------------------- -"##, - }, - Lint { - label: "const_bigint_helper_methods", - description: r##"# `const_bigint_helper_methods` - -The tracking issue for this feature is: [#85532] - -[#85532]: https://github.com/rust-lang/rust/issues/85532 - ------------------------- -"##, - }, - Lint { - label: "const_binary_heap_new_in", - description: r##"# `const_binary_heap_new_in` - -The tracking issue for this feature is: [#112353] - -[#112353]: https://github.com/rust-lang/rust/issues/112353 - ------------------------- -"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "const_black_box", @@ -3042,6 +4386,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "const_box", @@ -3053,6 +4400,9 @@ The tracking issue for this feature is: [#92521] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "const_btree_len", @@ -3062,123 +4412,107 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "const_cell_into_inner", - description: r##"# `const_cell_into_inner` - -The tracking issue for this feature is: [#78729] - -[#78729]: https://github.com/rust-lang/rust/issues/78729 - ------------------------- -"##, - }, - Lint { - label: "const_closures", - description: r##"# `const_closures` - -The tracking issue for this feature is: [#106003] - -[#106003]: https://github.com/rust-lang/rust/issues/106003 - ------------------------- -"##, - }, - Lint { - label: "const_collections_with_hasher", - description: r##"# `const_collections_with_hasher` + label: "const_cell", + description: r##"# `const_cell` -The tracking issue for this feature is: [#102575] +The tracking issue for this feature is: [#131283] -[#102575]: https://github.com/rust-lang/rust/issues/102575 +[#131283]: https://github.com/rust-lang/rust/issues/131283 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "const_cow_is_borrowed", - description: r##"# `const_cow_is_borrowed` + label: "const_char_classify", + description: r##"# `const_char_classify` -The tracking issue for this feature is: [#65143] +The tracking issue for this feature is: [#132241] -[#65143]: https://github.com/rust-lang/rust/issues/65143 +[#132241]: https://github.com/rust-lang/rust/issues/132241 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "const_eval_select", - description: r##"# `const_eval_select` - -The tracking issue for this feature is: [#124625] - -[#124625]: https://github.com/rust-lang/rust/issues/124625 + label: "const_closures", + description: r##"# `const_closures` ------------------------- -"##, - }, - Lint { - label: "const_exact_div", - description: r##"# `const_exact_div` +The tracking issue for this feature is: [#106003] -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. +[#106003]: https://github.com/rust-lang/rust/issues/106003 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "const_extern_fn", - description: r##"# `const_extern_fn` + label: "const_copy_from_slice", + description: r##"# `const_copy_from_slice` -The tracking issue for this feature is: [#64926] +The tracking issue for this feature is: [#131415] -[#64926]: https://github.com/rust-lang/rust/issues/64926 +[#131415]: https://github.com/rust-lang/rust/issues/131415 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "const_float_bits_conv", - description: r##"# `const_float_bits_conv` + label: "const_destruct", + description: r##"# `const_destruct` -The tracking issue for this feature is: [#72447] +The tracking issue for this feature is: [#133214] -[#72447]: https://github.com/rust-lang/rust/issues/72447 +[#133214]: https://github.com/rust-lang/rust/issues/133214 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "const_float_classify", - description: r##"# `const_float_classify` - -The tracking issue for this feature is: [#72505] - -[#72505]: https://github.com/rust-lang/rust/issues/72505 + label: "const_eq_ignore_ascii_case", + description: r##"# `const_eq_ignore_ascii_case` ------------------------- -"##, - }, - Lint { - label: "const_fmt_arguments_new", - description: r##"# `const_fmt_arguments_new` +The tracking issue for this feature is: [#131719] -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. +[#131719]: https://github.com/rust-lang/rust/issues/131719 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "const_fn_floating_point_arithmetic", - description: r##"# `const_fn_floating_point_arithmetic` + label: "const_eval_select", + description: r##"# `const_eval_select` -The tracking issue for this feature is: [#57241] +The tracking issue for this feature is: [#124625] -[#57241]: https://github.com/rust-lang/rust/issues/57241 +[#124625]: https://github.com/rust-lang/rust/issues/124625 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "const_for", @@ -3190,6 +4524,9 @@ The tracking issue for this feature is: [#87575] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "const_format_args", @@ -3199,17 +4536,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, - }, - Lint { - label: "const_hash", - description: r##"# `const_hash` - -The tracking issue for this feature is: [#104061] - -[#104061]: https://github.com/rust-lang/rust/issues/104061 - ------------------------- -"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "const_heap", @@ -3221,247 +4550,37 @@ The tracking issue for this feature is: [#79597] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "const_index_range_slice_index", - description: r##"# `const_index_range_slice_index` - -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. - ------------------------- -"##, - }, - Lint { - label: "const_int_from_str", - description: r##"# `const_int_from_str` - -The tracking issue for this feature is: [#59133] - -[#59133]: https://github.com/rust-lang/rust/issues/59133 - ------------------------- -"##, - }, - Lint { - label: "const_intoiterator_identity", - description: r##"# `const_intoiterator_identity` - -The tracking issue for this feature is: [#90603] - -[#90603]: https://github.com/rust-lang/rust/issues/90603 - ------------------------- -"##, - }, - Lint { - label: "const_intrinsic_compare_bytes", - description: r##"# `const_intrinsic_compare_bytes` - -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. - ------------------------- -"##, - }, - Lint { - label: "const_intrinsic_copy", - description: r##"# `const_intrinsic_copy` - -The tracking issue for this feature is: [#80697] - -[#80697]: https://github.com/rust-lang/rust/issues/80697 - ------------------------- -"##, - }, - Lint { - label: "const_intrinsic_forget", - description: r##"# `const_intrinsic_forget` - -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. - ------------------------- -"##, - }, - Lint { - label: "const_intrinsic_raw_eq", - description: r##"# `const_intrinsic_raw_eq` - -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. - ------------------------- -"##, - }, - Lint { - label: "const_ip", - description: r##"# `const_ip` - -The tracking issue for this feature is: [#76205] - -[#76205]: https://github.com/rust-lang/rust/issues/76205 - ------------------------- -"##, - }, - Lint { - label: "const_ipv4", - description: r##"# `const_ipv4` - -The tracking issue for this feature is: [#76205] - -[#76205]: https://github.com/rust-lang/rust/issues/76205 - ------------------------- -"##, - }, - Lint { - label: "const_ipv6", - description: r##"# `const_ipv6` - -The tracking issue for this feature is: [#76205] - -[#76205]: https://github.com/rust-lang/rust/issues/76205 - ------------------------- -"##, - }, - Lint { - label: "const_likely", - description: r##"# `const_likely` - -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. - ------------------------- -"##, - }, - Lint { - label: "const_maybe_uninit_array_assume_init", - description: r##"# `const_maybe_uninit_array_assume_init` - -The tracking issue for this feature is: [#96097] - -[#96097]: https://github.com/rust-lang/rust/issues/96097 - ------------------------- -"##, - }, - Lint { - label: "const_maybe_uninit_as_mut_ptr", - description: r##"# `const_maybe_uninit_as_mut_ptr` - -The tracking issue for this feature is: [#75251] - -[#75251]: https://github.com/rust-lang/rust/issues/75251 - ------------------------- -"##, - }, - Lint { - label: "const_maybe_uninit_assume_init", - description: r##"# `const_maybe_uninit_assume_init` - -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. - ------------------------- -"##, - }, - Lint { - label: "const_maybe_uninit_uninit_array", - description: r##"# `const_maybe_uninit_uninit_array` - -The tracking issue for this feature is: [#96097] - -[#96097]: https://github.com/rust-lang/rust/issues/96097 - ------------------------- -"##, - }, - Lint { - label: "const_maybe_uninit_write", - description: r##"# `const_maybe_uninit_write` - -The tracking issue for this feature is: [#63567] - -[#63567]: https://github.com/rust-lang/rust/issues/63567 - ------------------------- -"##, - }, - Lint { - label: "const_mut_refs", - description: r##"# `const_mut_refs` - -The tracking issue for this feature is: [#57349] - -[#57349]: https://github.com/rust-lang/rust/issues/57349 - ------------------------- -"##, - }, - Lint { - label: "const_nonnull_new", - description: r##"# `const_nonnull_new` - -The tracking issue for this feature is: [#93235] - -[#93235]: https://github.com/rust-lang/rust/issues/93235 - ------------------------- -"##, - }, - Lint { - label: "const_num_midpoint", - description: r##"# `const_num_midpoint` - -The tracking issue for this feature is: [#110840] - -[#110840]: https://github.com/rust-lang/rust/issues/110840 - ------------------------- -"##, - }, - Lint { - label: "const_option", - description: r##"# `const_option` - -The tracking issue for this feature is: [#67441] - -[#67441]: https://github.com/rust-lang/rust/issues/67441 - ------------------------- -"##, - }, - Lint { - label: "const_option_ext", - description: r##"# `const_option_ext` - -The tracking issue for this feature is: [#91930] - -[#91930]: https://github.com/rust-lang/rust/issues/91930 - ------------------------- -"##, - }, - Lint { - label: "const_pin", - description: r##"# `const_pin` + label: "const_is_char_boundary", + description: r##"# `const_is_char_boundary` -The tracking issue for this feature is: [#76654] +The tracking issue for this feature is: [#131516] -[#76654]: https://github.com/rust-lang/rust/issues/76654 +[#131516]: https://github.com/rust-lang/rust/issues/131516 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "const_pointer_is_aligned", - description: r##"# `const_pointer_is_aligned` + label: "const_mut_cursor", + description: r##"# `const_mut_cursor` -The tracking issue for this feature is: [#104203] +The tracking issue for this feature is: [#130801] -[#104203]: https://github.com/rust-lang/rust/issues/104203 +[#130801]: https://github.com/rust-lang/rust/issues/130801 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "const_precise_live_drops", @@ -3473,39 +4592,9 @@ The tracking issue for this feature is: [#73255] ------------------------ "##, - }, - Lint { - label: "const_pref_align_of", - description: r##"# `const_pref_align_of` - -The tracking issue for this feature is: [#91971] - -[#91971]: https://github.com/rust-lang/rust/issues/91971 - ------------------------- -"##, - }, - Lint { - label: "const_ptr_as_ref", - description: r##"# `const_ptr_as_ref` - -The tracking issue for this feature is: [#91822] - -[#91822]: https://github.com/rust-lang/rust/issues/91822 - ------------------------- -"##, - }, - Lint { - label: "const_ptr_is_null", - description: r##"# `const_ptr_is_null` - -The tracking issue for this feature is: [#74939] - -[#74939]: https://github.com/rust-lang/rust/issues/74939 - ------------------------- -"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "const_ptr_sub_ptr", @@ -3517,17 +4606,9 @@ The tracking issue for this feature is: [#95892] ------------------------ "##, - }, - Lint { - label: "const_ptr_write", - description: r##"# `const_ptr_write` - -The tracking issue for this feature is: [#86302] - -[#86302]: https://github.com/rust-lang/rust/issues/86302 - ------------------------- -"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "const_range_bounds", @@ -3539,6 +4620,9 @@ The tracking issue for this feature is: [#108082] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "const_raw_ptr_comparison", @@ -3550,94 +4634,9 @@ The tracking issue for this feature is: [#53020] ------------------------ "##, - }, - Lint { - label: "const_refs_to_cell", - description: r##"# `const_refs_to_cell` - -The tracking issue for this feature is: [#80384] - -[#80384]: https://github.com/rust-lang/rust/issues/80384 - ------------------------- -"##, - }, - Lint { - label: "const_refs_to_static", - description: r##"# `const_refs_to_static` - -The tracking issue for this feature is: [#119618] - -[#119618]: https://github.com/rust-lang/rust/issues/119618 - ------------------------- -"##, - }, - Lint { - label: "const_replace", - description: r##"# `const_replace` - -The tracking issue for this feature is: [#83164] - -[#83164]: https://github.com/rust-lang/rust/issues/83164 - ------------------------- -"##, - }, - Lint { - label: "const_result", - description: r##"# `const_result` - -The tracking issue for this feature is: [#82814] - -[#82814]: https://github.com/rust-lang/rust/issues/82814 - ------------------------- -"##, - }, - Lint { - label: "const_size_of_val", - description: r##"# `const_size_of_val` - -The tracking issue for this feature is: [#46571] - -[#46571]: https://github.com/rust-lang/rust/issues/46571 - ------------------------- -"##, - }, - Lint { - label: "const_size_of_val_raw", - description: r##"# `const_size_of_val_raw` - -The tracking issue for this feature is: [#46571] - -[#46571]: https://github.com/rust-lang/rust/issues/46571 - ------------------------- -"##, - }, - Lint { - label: "const_slice_first_last", - description: r##"# `const_slice_first_last` - -The tracking issue for this feature is: [#83570] - -[#83570]: https://github.com/rust-lang/rust/issues/83570 - ------------------------- -"##, - }, - Lint { - label: "const_slice_first_last_chunk", - description: r##"# `const_slice_first_last_chunk` - -The tracking issue for this feature is: [#111774] - -[#111774]: https://github.com/rust-lang/rust/issues/111774 - ------------------------- -"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "const_slice_flatten", @@ -3649,6 +4648,9 @@ The tracking issue for this feature is: [#95629] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "const_slice_from_mut_ptr_range", @@ -3660,6 +4662,9 @@ The tracking issue for this feature is: [#89792] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "const_slice_from_ptr_range", @@ -3671,59 +4676,23 @@ The tracking issue for this feature is: [#89792] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "const_slice_from_raw_parts_mut", - description: r##"# `const_slice_from_raw_parts_mut` + label: "const_sockaddr_setters", + description: r##"# `const_sockaddr_setters` -The tracking issue for this feature is: [#67456] +The tracking issue for this feature is: [#131714] -[#67456]: https://github.com/rust-lang/rust/issues/67456 - ------------------------- -"##, - }, - Lint { - label: "const_slice_from_ref", - description: r##"# `const_slice_from_ref` - -The tracking issue for this feature is: [#90206] - -[#90206]: https://github.com/rust-lang/rust/issues/90206 - ------------------------- -"##, - }, - Lint { - label: "const_slice_index", - description: r##"# `const_slice_index` - -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. - ------------------------- -"##, - }, - Lint { - label: "const_slice_split_at_mut", - description: r##"# `const_slice_split_at_mut` - -The tracking issue for this feature is: [#101804] - -[#101804]: https://github.com/rust-lang/rust/issues/101804 - ------------------------- -"##, - }, - Lint { - label: "const_str_from_raw_parts_mut", - description: r##"# `const_str_from_raw_parts_mut` - -The tracking issue for this feature is: [#119206] - -[#119206]: https://github.com/rust-lang/rust/issues/119206 +[#131714]: https://github.com/rust-lang/rust/issues/131714 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "const_str_from_utf8", @@ -3735,28 +4704,23 @@ The tracking issue for this feature is: [#91006] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "const_str_from_utf8_unchecked_mut", - description: r##"# `const_str_from_utf8_unchecked_mut` + label: "const_str_split_at", + description: r##"# `const_str_split_at` -The tracking issue for this feature is: [#91005] +The tracking issue for this feature is: [#131518] -[#91005]: https://github.com/rust-lang/rust/issues/91005 - ------------------------- -"##, - }, - Lint { - label: "const_strict_overflow_ops", - description: r##"# `const_strict_overflow_ops` - -The tracking issue for this feature is: [#118260] - -[#118260]: https://github.com/rust-lang/rust/issues/118260 +[#131518]: https://github.com/rust-lang/rust/issues/131518 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "const_swap", @@ -3768,15 +4732,23 @@ The tracking issue for this feature is: [#83163] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "const_three_way_compare", - description: r##"# `const_three_way_compare` + label: "const_swap_nonoverlapping", + description: r##"# `const_swap_nonoverlapping` -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. +The tracking issue for this feature is: [#133668] + +[#133668]: https://github.com/rust-lang/rust/issues/133668 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "const_trait_impl", @@ -3788,6 +4760,9 @@ The tracking issue for this feature is: [#67792] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "const_try", @@ -3799,6 +4774,9 @@ The tracking issue for this feature is: [#74935] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "const_type_id", @@ -3810,6 +4788,9 @@ The tracking issue for this feature is: [#77125] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "const_type_name", @@ -3821,6 +4802,9 @@ The tracking issue for this feature is: [#63084] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "const_typed_swap", @@ -3830,48 +4814,23 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "const_ub_checks", - description: r##"# `const_ub_checks` + label: "const_vec_string_slice", + description: r##"# `const_vec_string_slice` -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. +The tracking issue for this feature is: [#129041] ------------------------- -"##, - }, - Lint { - label: "const_unicode_case_lookup", - description: r##"# `const_unicode_case_lookup` - -The tracking issue for this feature is: [#101400] - -[#101400]: https://github.com/rust-lang/rust/issues/101400 - ------------------------- -"##, - }, - Lint { - label: "const_unsafecell_get_mut", - description: r##"# `const_unsafecell_get_mut` - -The tracking issue for this feature is: [#88836] - -[#88836]: https://github.com/rust-lang/rust/issues/88836 - ------------------------- -"##, - }, - Lint { - label: "const_waker", - description: r##"# `const_waker` - -The tracking issue for this feature is: [#102012] - -[#102012]: https://github.com/rust-lang/rust/issues/102012 +[#129041]: https://github.com/rust-lang/rust/issues/129041 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "container_error_extra", @@ -3881,6 +4840,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "context_ext", @@ -3892,17 +4854,9 @@ The tracking issue for this feature is: [#123392] ------------------------ "##, - }, - Lint { - label: "control_flow_enum", - description: r##"# `control_flow_enum` - -The tracking issue for this feature is: [#75744] - -[#75744]: https://github.com/rust-lang/rust/issues/75744 - ------------------------- -"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "convert_float_to_int", @@ -3914,6 +4868,9 @@ The tracking issue for this feature is: [#67057] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "core_intrinsics", @@ -3923,6 +4880,9 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "core_io_borrowed_buf", @@ -3934,15 +4894,9 @@ The tracking issue for this feature is: [#117693] ------------------------ "##, - }, - Lint { - label: "pattern_type_macro", - description: r##"# `pattern_type_macro` - -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. - ------------------------- -"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "core_private_bignum", @@ -3952,6 +4906,9 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "core_private_diy_float", @@ -3961,6 +4918,9 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "coroutine_clone", @@ -3972,6 +4932,9 @@ The tracking issue for this feature is: [#95360] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "coroutine_trait", @@ -3983,6 +4946,9 @@ The tracking issue for this feature is: [#43122] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "coroutines", @@ -4234,6 +5200,9 @@ it's invalid to resume a completed coroutine. It's also worth noting that this is just a rough desugaring, not a normative specification for what the compiler does. "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "coverage_attribute", @@ -4268,6 +5237,9 @@ fn bar() { } ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "cow_is_borrowed", @@ -4279,6 +5251,9 @@ The tracking issue for this feature is: [#65143] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "csky_target_feature", @@ -4290,6 +5265,9 @@ The tracking issue for this feature is: [#44839] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "cstr_bytes", @@ -4301,6 +5279,9 @@ The tracking issue for this feature is: [#112115] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "cstr_internals", @@ -4310,10 +5291,13 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "cursor_remaining", - description: r##"# `cursor_remaining` + label: "cursor_split", + description: r##"# `cursor_split` The tracking issue for this feature is: [#86369] @@ -4321,6 +5305,9 @@ The tracking issue for this feature is: [#86369] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "custom_inner_attributes", @@ -4332,6 +5319,9 @@ The tracking issue for this feature is: [#54726] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "custom_mir", @@ -4341,6 +5331,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "custom_test_frameworks", @@ -4377,6 +5370,9 @@ const WILL_PASS: i32 = 0; const WILL_FAIL: i32 = 4; ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "deadline_api", @@ -4388,6 +5384,9 @@ The tracking issue for this feature is: [#46316] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "debug_closure_helpers", @@ -4399,6 +5398,9 @@ The tracking issue for this feature is: [#117729] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "dec2flt", @@ -4408,6 +5410,9 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "decl_macro", @@ -4419,17 +5424,23 @@ The tracking issue for this feature is: [#39412] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "default_type_parameter_fallback", - description: r##"# `default_type_parameter_fallback` + label: "default_field_values", + description: r##"# `default_field_values` -The tracking issue for this feature is: [#27336] +The tracking issue for this feature is: [#132162] -[#27336]: https://github.com/rust-lang/rust/issues/27336 +[#132162]: https://github.com/rust-lang/rust/issues/132162 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "deprecated_safe", @@ -4441,6 +5452,9 @@ The tracking issue for this feature is: [#94978] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "deprecated_suggestion", @@ -4452,6 +5466,9 @@ The tracking issue for this feature is: [#94785] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "deref_patterns", @@ -4463,6 +5480,9 @@ The tracking issue for this feature is: [#87121] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "deref_pure_trait", @@ -4474,6 +5494,9 @@ The tracking issue for this feature is: [#87121] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "derive_clone_copy", @@ -4483,35 +5506,47 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "derive_const", - description: r##"# `derive_const` + label: "derive_coerce_pointee", + description: r##"# `derive_coerce_pointee` -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. +The tracking issue for this feature is: [#123430] + +[#123430]: https://github.com/rust-lang/rust/issues/123430 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "derive_eq", - description: r##"# `derive_eq` + label: "derive_const", + description: r##"# `derive_const` -This feature is internal to the Rust compiler and is not intended for general use. +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "derive_smart_pointer", - description: r##"# `derive_smart_pointer` - -The tracking issue for this feature is: [#123430] + label: "derive_eq", + description: r##"# `derive_eq` -[#123430]: https://github.com/rust-lang/rust/issues/123430 +This feature is internal to the Rust compiler and is not intended for general use. ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "dir_entry_ext2", @@ -4523,6 +5558,9 @@ The tracking issue for this feature is: [#85573] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "discriminant_kind", @@ -4532,6 +5570,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "dispatch_from_dyn", @@ -4541,6 +5582,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "do_not_recommend", @@ -4552,6 +5596,9 @@ The tracking issue for this feature is: [#51992] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "doc_auto_cfg", @@ -4563,6 +5610,9 @@ The tracking issue for this feature is: [#43781] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "doc_cfg", @@ -4613,6 +5663,9 @@ pub struct Icon { [#43781]: https://github.com/rust-lang/rust/issues/43781 [#43348]: https://github.com/rust-lang/rust/issues/43348 "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "doc_cfg_hide", @@ -4624,6 +5677,9 @@ The tracking issue for this feature is: [#43781] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "doc_masked", @@ -4652,6 +5708,9 @@ Such types would introduce broken links into the documentation. [#44026]: https://github.com/rust-lang/rust/pull/44026 [#44027]: https://github.com/rust-lang/rust/pull/44027 "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "doc_notable_trait", @@ -4689,6 +5748,9 @@ See also its documentation in [the rustdoc book][rustdoc-book-notable_trait]. [#45039]: https://github.com/rust-lang/rust/pull/45039 [rustdoc-book-notable_trait]: ../../rustdoc/unstable-features.html#adding-your-trait-to-the-notable-traits-dialog "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "downcast_unchecked", @@ -4700,6 +5762,9 @@ The tracking issue for this feature is: [#90850] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "drain_keep_rest", @@ -4711,6 +5776,9 @@ The tracking issue for this feature is: [#101122] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "dropck_eyepatch", @@ -4722,6 +5790,9 @@ The tracking issue for this feature is: [#34761] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "duration_constants", @@ -4733,6 +5804,9 @@ The tracking issue for this feature is: [#57391] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "duration_constructors", @@ -4746,17 +5820,9 @@ The tracking issue for this feature is: [#120301] Add the methods `from_mins`, `from_hours` and `from_days` to `Duration`. "##, - }, - Lint { - label: "duration_consts_float", - description: r##"# `duration_consts_float` - -The tracking issue for this feature is: [#72440] - -[#72440]: https://github.com/rust-lang/rust/issues/72440 - ------------------------- -"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "duration_millis_float", @@ -4768,6 +5834,9 @@ The tracking issue for this feature is: [#122451] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "duration_units", @@ -4779,57 +5848,49 @@ The tracking issue for this feature is: [#120301] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "dyn_star", - description: r##"# `dyn_star` - -The tracking issue for this feature is: [#102425] - -[#102425]: https://github.com/rust-lang/rust/issues/102425 - ------------------------- -"##, - }, - Lint { - label: "edition_panic", - description: r##"# `edition_panic` - -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. + label: "dyn_compatible_for_dispatch", + description: r##"# `dyn_compatible_for_dispatch` ------------------------- -"##, - }, - Lint { - label: "effect_types", - description: r##"# `effect_types` +The tracking issue for this feature is: [#43561] -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. +[#43561]: https://github.com/rust-lang/rust/issues/43561 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "effects", - description: r##"# `effects` + label: "dyn_star", + description: r##"# `dyn_star` -The tracking issue for this feature is: [#102090] +The tracking issue for this feature is: [#102425] -[#102090]: https://github.com/rust-lang/rust/issues/102090 +[#102425]: https://github.com/rust-lang/rust/issues/102425 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "entry_insert", - description: r##"# `entry_insert` - -The tracking issue for this feature is: [#65225] + label: "edition_panic", + description: r##"# `edition_panic` -[#65225]: https://github.com/rust-lang/rust/issues/65225 +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "ermsb_target_feature", @@ -4841,6 +5902,9 @@ The tracking issue for this feature is: [#44839] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "error_generic_member_access", @@ -4852,6 +5916,9 @@ The tracking issue for this feature is: [#99301] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "error_iter", @@ -4863,6 +5930,9 @@ The tracking issue for this feature is: [#58520] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "error_reporter", @@ -4874,6 +5944,9 @@ The tracking issue for this feature is: [#90172] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "error_type_id", @@ -4885,6 +5958,9 @@ The tracking issue for this feature is: [#60784] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "exact_size_is_empty", @@ -4896,6 +5972,9 @@ The tracking issue for this feature is: [#35428] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "exclusive_wrapper", @@ -4907,6 +5986,9 @@ The tracking issue for this feature is: [#98407] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "exhaustive_patterns", @@ -4918,6 +6000,9 @@ The tracking issue for this feature is: [#51085] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "exit_status_error", @@ -4929,6 +6014,9 @@ The tracking issue for this feature is: [#84908] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "exitcode_exit_method", @@ -4940,6 +6028,9 @@ The tracking issue for this feature is: [#97100] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "explicit_tail_calls", @@ -4951,28 +6042,9 @@ The tracking issue for this feature is: [#112788] ------------------------ "##, - }, - Lint { - label: "exposed_provenance", - description: r##"# `exposed_provenance` - -The tracking issue for this feature is: [#95228] - -[#95228]: https://github.com/rust-lang/rust/issues/95228 - ------------------------- -"##, - }, - Lint { - label: "expr_fragment_specifier_2024", - description: r##"# `expr_fragment_specifier_2024` - -The tracking issue for this feature is: [#123742] - -[#123742]: https://github.com/rust-lang/rust/issues/123742 - ------------------------- -"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "extend_one", @@ -4984,6 +6056,9 @@ The tracking issue for this feature is: [#72631] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "extend_one_unchecked", @@ -4993,20 +6068,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, - }, - Lint { - label: "extended_varargs_abi_support", - description: r##"# `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. -"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "extern_types", @@ -5018,6 +6082,9 @@ The tracking issue for this feature is: [#43467] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "extract_if", @@ -5029,6 +6096,9 @@ The tracking issue for this feature is: [#43244] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "f128", @@ -5042,6 +6112,9 @@ The tracking issue for this feature is: [#116909] Enable the `f128` type for IEEE 128-bit floating numbers (quad precision). "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "f16", @@ -5055,6 +6128,9 @@ The tracking issue for this feature is: [#116909] Enable the `f16` type for IEEE 16-bit floating numbers (half precision). "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "fd", @@ -5064,6 +6140,9 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "fd_read", @@ -5073,6 +6152,9 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "ffi_const", @@ -5129,6 +6211,9 @@ against are compatible with those of the `#[ffi_const]`. [GCC]: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-const-function-attribute [IBM ILE C/C++]: https://www.ibm.com/support/knowledgecenter/fr/ssw_ibm_i_71/rzarg/fn_attrib_const.htm "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "ffi_pure", @@ -5189,6 +6274,37 @@ against are compatible with those of the `#[ffi_pure]`. [GCC]: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-pure-function-attribute [IBM ILE C/C++]: https://www.ibm.com/support/knowledgecenter/fr/ssw_ibm_i_71/rzarg/fn_attrib_pure.htm "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "file_buffered", + description: r##"# `file_buffered` + +The tracking issue for this feature is: [#130804] + +[#130804]: https://github.com/rust-lang/rust/issues/130804 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "file_lock", + description: r##"# `file_lock` + +The tracking issue for this feature is: [#130994] + +[#130994]: https://github.com/rust-lang/rust/issues/130994 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "float_gamma", @@ -5200,6 +6316,9 @@ The tracking issue for this feature is: [#99842] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "float_minimum_maximum", @@ -5211,6 +6330,9 @@ The tracking issue for this feature is: [#91079] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "float_next_up_down", @@ -5222,6 +6344,9 @@ The tracking issue for this feature is: [#91399] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "flt2dec", @@ -5231,6 +6356,23 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "fmt_debug", + description: r##"# `fmt_debug` + +The tracking issue for this feature is: [#129709] + +[#129709]: https://github.com/rust-lang/rust/issues/129709 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "fmt_helpers_for_derive", @@ -5240,6 +6382,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "fmt_internals", @@ -5249,6 +6394,9 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "fn_align", @@ -5260,6 +6408,9 @@ The tracking issue for this feature is: [#82232] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "fn_delegation", @@ -5271,6 +6422,9 @@ The tracking issue for this feature is: [#118212] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "fn_ptr_trait", @@ -5280,6 +6434,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "fn_traits", @@ -5319,6 +6476,9 @@ fn main() { } ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "forget_unsized", @@ -5328,6 +6488,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "format_args_nl", @@ -5337,6 +6500,23 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "formatting_options", + description: r##"# `formatting_options` + +The tracking issue for this feature is: [#118117] + +[#118117]: https://github.com/rust-lang/rust/issues/118117 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "freeze", @@ -5348,6 +6528,9 @@ The tracking issue for this feature is: [#121675] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "freeze_impls", @@ -5359,6 +6542,9 @@ The tracking issue for this feature is: [#121675] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "fundamental", @@ -5370,6 +6556,9 @@ The tracking issue for this feature is: [#29635] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "future_join", @@ -5381,6 +6570,9 @@ The tracking issue for this feature is: [#91642] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "gen_blocks", @@ -5392,6 +6584,9 @@ The tracking issue for this feature is: [#117078] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "gen_future", @@ -5403,6 +6598,9 @@ The tracking issue for this feature is: [#50547] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "generic_arg_infer", @@ -5414,6 +6612,9 @@ The tracking issue for this feature is: [#85077] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "generic_assert", @@ -5423,6 +6624,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "generic_assert_internals", @@ -5434,17 +6638,9 @@ The tracking issue for this feature is: [#44838] ------------------------ "##, - }, - Lint { - label: "generic_associated_types_extended", - description: r##"# `generic_associated_types_extended` - -The tracking issue for this feature is: [#95451] - -[#95451]: https://github.com/rust-lang/rust/issues/95451 - ------------------------- -"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "generic_const_exprs", @@ -5456,6 +6652,9 @@ The tracking issue for this feature is: [#76560] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "generic_const_items", @@ -5467,6 +6666,9 @@ The tracking issue for this feature is: [#113521] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "get_many_mut", @@ -5478,6 +6680,21 @@ The tracking issue for this feature is: [#104642] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "get_many_mut_helpers", + description: r##"# `get_many_mut_helpers` + +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "get_mut_unchecked", @@ -5489,6 +6706,9 @@ The tracking issue for this feature is: [#63292] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "global_registration", @@ -5500,6 +6720,23 @@ The tracking issue for this feature is: [#125119] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "guard_patterns", + description: r##"# `guard_patterns` + +The tracking issue for this feature is: [#129967] + +[#129967]: https://github.com/rust-lang/rust/issues/129967 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "half_open_range_patterns_in_slices", @@ -5533,6 +6770,9 @@ fn main() { } ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "hash_extract_if", @@ -5544,6 +6784,9 @@ The tracking issue for this feature is: [#59618] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "hash_raw_entry", @@ -5555,6 +6798,9 @@ The tracking issue for this feature is: [#56167] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "hash_set_entry", @@ -5566,6 +6812,9 @@ The tracking issue for this feature is: [#60896] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "hasher_prefixfree_extras", @@ -5577,6 +6826,9 @@ The tracking issue for this feature is: [#96762] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "hashmap_internals", @@ -5586,6 +6838,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "hexagon_target_feature", @@ -5597,6 +6852,9 @@ The tracking issue for this feature is: [#44839] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "hint_must_use", @@ -5608,6 +6866,9 @@ The tracking issue for this feature is: [#94745] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "if_let_guard", @@ -5619,6 +6880,9 @@ The tracking issue for this feature is: [#51114] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "impl_trait_in_assoc_type", @@ -5630,6 +6894,9 @@ The tracking issue for this feature is: [#63063] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "impl_trait_in_fn_trait_return", @@ -5641,6 +6908,9 @@ The tracking issue for this feature is: [#99697] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "inherent_associated_types", @@ -5652,6 +6922,9 @@ The tracking issue for this feature is: [#8995] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "inline_const_pat", @@ -5678,6 +6951,9 @@ match some_int { [#76001]: https://github.com/rust-lang/rust/issues/76001 "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "inplace_iteration", @@ -5687,6 +6963,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "int_roundings", @@ -5698,6 +6977,9 @@ The tracking issue for this feature is: [#88581] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "integer_atomics", @@ -5709,6 +6991,9 @@ The tracking issue for this feature is: [#99069] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "integer_sign_cast", @@ -5720,6 +7005,9 @@ The tracking issue for this feature is: [#125882] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "internal_impls_macro", @@ -5729,6 +7017,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "internal_output_capture", @@ -5738,6 +7029,9 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "intra_doc_pointers", @@ -5757,6 +7051,9 @@ raw pointers in intra-doc links are unstable until it does. //! [pointer::add] ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "intrinsics", @@ -5780,7 +7077,7 @@ All intrinsic fallback bodies are automatically made cross-crate inlineable (lik by the codegen backend, but not the MIR inliner. ```rust -#![feature(rustc_attrs)] +#![feature(intrinsics)] #![allow(internal_features)] #[rustc_intrinsic] @@ -5790,7 +7087,7 @@ const unsafe fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) {} Since these are just regular functions, it is perfectly ok to create the intrinsic twice: ```rust -#![feature(rustc_attrs)] +#![feature(intrinsics)] #![allow(internal_features)] #[rustc_intrinsic] @@ -5852,105 +7149,159 @@ extern "rust-intrinsic" { As with any other FFI functions, these are by default always `unsafe` to call. You can add `#[rustc_safe_intrinsic]` to the intrinsic to make it safe to call. "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "io_error_more", - description: r##"# `io_error_more` + label: "io_const_error", + description: r##"# `io_const_error` -The tracking issue for this feature is: [#86442] +The tracking issue for this feature is: [#133448] -[#86442]: https://github.com/rust-lang/rust/issues/86442 +[#133448]: https://github.com/rust-lang/rust/issues/133448 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "io_error_uncategorized", - description: r##"# `io_error_uncategorized` + label: "io_const_error_internals", + description: r##"# `io_const_error_internals` This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "ip", - description: r##"# `ip` + label: "io_error_inprogress", + description: r##"# `io_error_inprogress` -The tracking issue for this feature is: [#27709] +The tracking issue for this feature is: [#130840] -[#27709]: https://github.com/rust-lang/rust/issues/27709 +[#130840]: https://github.com/rust-lang/rust/issues/130840 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "is_ascii_octdigit", - description: r##"# `is_ascii_octdigit` + label: "io_error_more", + description: r##"# `io_error_more` -The tracking issue for this feature is: [#101288] +The tracking issue for this feature is: [#86442] -[#101288]: https://github.com/rust-lang/rust/issues/101288 +[#86442]: https://github.com/rust-lang/rust/issues/86442 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "is_none_or", - description: r##"# `is_none_or` + label: "io_error_uncategorized", + description: r##"# `io_error_uncategorized` -The tracking issue for this feature is: [#126383] +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. -[#126383]: https://github.com/rust-lang/rust/issues/126383 +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "io_slice_as_bytes", + description: r##"# `io_slice_as_bytes` + +The tracking issue for this feature is: [#132818] + +[#132818]: https://github.com/rust-lang/rust/issues/132818 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "is_riscv_feature_detected", - description: r##"# `is_riscv_feature_detected` + label: "ip", + description: r##"# `ip` -The tracking issue for this feature is: [#111192] +The tracking issue for this feature is: [#27709] -[#111192]: https://github.com/rust-lang/rust/issues/111192 +[#27709]: https://github.com/rust-lang/rust/issues/27709 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "is_sorted", - description: r##"# `is_sorted` + label: "ip_from", + description: r##"# `ip_from` -The tracking issue for this feature is: [#53485] +The tracking issue for this feature is: [#131360] -[#53485]: https://github.com/rust-lang/rust/issues/53485 +[#131360]: https://github.com/rust-lang/rust/issues/131360 ------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "is_ascii_octdigit", + description: r##"# `is_ascii_octdigit` + +The tracking issue for this feature is: [#101288] + +[#101288]: https://github.com/rust-lang/rust/issues/101288 -Add the methods `is_sorted`, `is_sorted_by` and `is_sorted_by_key` to `[T]`; -add the methods `is_sorted`, `is_sorted_by` and `is_sorted_by_key` to -`Iterator`. +------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "is_val_statically_known", - description: r##"# `is_val_statically_known` + label: "is_loongarch_feature_detected", + description: r##"# `is_loongarch_feature_detected` -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. +The tracking issue for this feature is: [#117425] + +[#117425]: https://github.com/rust-lang/rust/issues/117425 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "isqrt", - description: r##"# `isqrt` + label: "is_riscv_feature_detected", + description: r##"# `is_riscv_feature_detected` -The tracking issue for this feature is: [#116226] +The tracking issue for this feature is: [#111192] -[#116226]: https://github.com/rust-lang/rust/issues/116226 +[#111192]: https://github.com/rust-lang/rust/issues/111192 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "iter_advance_by", @@ -5962,6 +7313,9 @@ The tracking issue for this feature is: [#77404] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "iter_array_chunks", @@ -5973,6 +7327,9 @@ The tracking issue for this feature is: [#100450] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "iter_chain", @@ -5984,6 +7341,9 @@ The tracking issue for this feature is: [#125964] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "iter_collect_into", @@ -5995,6 +7355,9 @@ The tracking issue for this feature is: [#94780] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "iter_from_coroutine", @@ -6006,6 +7369,9 @@ The tracking issue for this feature is: [#43122] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "iter_intersperse", @@ -6017,6 +7383,9 @@ The tracking issue for this feature is: [#79524] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "iter_is_partitioned", @@ -6028,6 +7397,9 @@ The tracking issue for this feature is: [#62544] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "iter_map_windows", @@ -6039,6 +7411,9 @@ The tracking issue for this feature is: [#87155] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "iter_next_chunk", @@ -6050,6 +7425,9 @@ The tracking issue for this feature is: [#98326] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "iter_order_by", @@ -6061,6 +7439,9 @@ The tracking issue for this feature is: [#64295] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "iter_partition_in_place", @@ -6072,17 +7453,9 @@ The tracking issue for this feature is: [#62543] ------------------------ "##, - }, - Lint { - label: "iter_repeat_n", - description: r##"# `iter_repeat_n` - -The tracking issue for this feature is: [#104434] - -[#104434]: https://github.com/rust-lang/rust/issues/104434 - ------------------------- -"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "iterator_try_collect", @@ -6094,6 +7467,9 @@ The tracking issue for this feature is: [#94047] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "iterator_try_reduce", @@ -6105,6 +7481,9 @@ The tracking issue for this feature is: [#87053] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "junction_point", @@ -6116,6 +7495,9 @@ The tracking issue for this feature is: [#121709] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "lahfsahf_target_feature", @@ -6127,6 +7509,9 @@ The tracking issue for this feature is: [#44839] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "lang_items", @@ -6246,6 +7631,9 @@ An up-to-date list of all language items can be found [here] in the compiler cod [here]: https://github.com/rust-lang/rust/blob/master/compiler/rustc_hir/src/lang_items.rs "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "large_assignments", @@ -6257,6 +7645,9 @@ The tracking issue for this feature is: [#83518] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "layout_for_ptr", @@ -6268,6 +7659,9 @@ The tracking issue for this feature is: [#69835] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "lazy_cell_into_inner", @@ -6279,6 +7673,23 @@ The tracking issue for this feature is: [#125623] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "lazy_get", + description: r##"# `lazy_get` + +The tracking issue for this feature is: [#129333] + +[#129333]: https://github.com/rust-lang/rust/issues/129333 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "lazy_type_alias", @@ -6290,6 +7701,21 @@ The tracking issue for this feature is: [#112792] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "legacy_receiver_trait", + description: r##"# `legacy_receiver_trait` + +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "let_chains", @@ -6301,6 +7727,9 @@ The tracking issue for this feature is: [#53667] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "liballoc_internals", @@ -6310,6 +7739,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "libstd_sys_internals", @@ -6319,6 +7751,9 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "lifetime_capture_rules_2024", @@ -6328,6 +7763,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "link_arg_attribute", @@ -6353,6 +7791,9 @@ extern "C" {} [#99427]: https://github.com/rust-lang/rust/issues/99427 "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "link_cfg", @@ -6362,6 +7803,9 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "link_llvm_intrinsics", @@ -6373,6 +7817,9 @@ The tracking issue for this feature is: [#29602] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "linkage", @@ -6384,6 +7831,9 @@ The tracking issue for this feature is: [#29603] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "linked_list_cursors", @@ -6395,6 +7845,9 @@ The tracking issue for this feature is: [#58533] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "linked_list_remove", @@ -6406,6 +7859,9 @@ The tracking issue for this feature is: [#69210] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "linked_list_retain", @@ -6417,6 +7873,9 @@ The tracking issue for this feature is: [#114135] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "linux_pidfd", @@ -6428,6 +7887,9 @@ The tracking issue for this feature is: [#82971] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "local_waker", @@ -6439,6 +7901,9 @@ The tracking issue for this feature is: [#118959] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "log_syntax", @@ -6450,6 +7915,9 @@ The tracking issue for this feature is: [#29598] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "loongarch_target_feature", @@ -6461,6 +7929,9 @@ The tracking issue for this feature is: [#44839] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "macro_metavar_expr", @@ -6472,6 +7943,9 @@ The tracking issue for this feature is: [#83527] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "macro_metavar_expr_concat", @@ -6483,17 +7957,9 @@ The tracking issue for this feature is: [#124225] ------------------------ "##, - }, - Lint { - label: "map_entry_replace", - description: r##"# `map_entry_replace` - -The tracking issue for this feature is: [#44286] - -[#44286]: https://github.com/rust-lang/rust/issues/44286 - ------------------------- -"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "map_many_mut", @@ -6505,6 +7971,9 @@ The tracking issue for this feature is: [#97601] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "map_try_insert", @@ -6516,6 +7985,9 @@ The tracking issue for this feature is: [#82766] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "mapped_lock_guards", @@ -6527,6 +7999,9 @@ The tracking issue for this feature is: [#117108] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "marker_trait_attr", @@ -6566,6 +8041,9 @@ fn cheap_clone<T: CheapToClone>(t: T) -> T { This is expected to replace the unstable `overlapping_marker_traits` feature, which applied to all empty traits (without needing an opt-in). "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "maybe_uninit_array_assume_init", @@ -6577,6 +8055,9 @@ The tracking issue for this feature is: [#96097] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "maybe_uninit_as_bytes", @@ -6588,6 +8069,9 @@ The tracking issue for this feature is: [#93092] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "maybe_uninit_fill", @@ -6599,6 +8083,9 @@ The tracking issue for this feature is: [#117428] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "maybe_uninit_slice", @@ -6610,6 +8097,9 @@ The tracking issue for this feature is: [#63569] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "maybe_uninit_uninit_array", @@ -6621,6 +8111,9 @@ The tracking issue for this feature is: [#96097] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "maybe_uninit_uninit_array_transpose", @@ -6632,6 +8125,9 @@ The tracking issue for this feature is: [#96097] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "maybe_uninit_write_slice", @@ -6643,6 +8139,9 @@ The tracking issue for this feature is: [#79995] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "mem_copy_fn", @@ -6654,17 +8153,23 @@ The tracking issue for this feature is: [#98262] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "min_exhaustive_patterns", - description: r##"# `min_exhaustive_patterns` + label: "min_generic_const_args", + description: r##"# `min_generic_const_args` -The tracking issue for this feature is: [#119612] +The tracking issue for this feature is: [#132980] -[#119612]: https://github.com/rust-lang/rust/issues/119612 +[#132980]: https://github.com/rust-lang/rust/issues/132980 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "min_specialization", @@ -6676,6 +8181,9 @@ The tracking issue for this feature is: [#31844] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "mips_target_feature", @@ -6687,6 +8195,23 @@ The tracking issue for this feature is: [#44839] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "mixed_integer_ops_unsigned_sub", + description: r##"# `mixed_integer_ops_unsigned_sub` + +The tracking issue for this feature is: [#126043] + +[#126043]: https://github.com/rust-lang/rust/issues/126043 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "more_float_constants", @@ -6698,6 +8223,21 @@ The tracking issue for this feature is: [#103883] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "more_maybe_bounds", + description: r##"# `more_maybe_bounds` + +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "more_qualified_paths", @@ -6706,6 +8246,10 @@ The tracking issue for this feature is: [#103883] The `more_qualified_paths` feature can be used in order to enable the use of qualified paths in patterns. +The tracking issue for this feature is: [#86935](https://github.com/rust-lang/rust/issues/86935). + +------------------------ + ## Example ```rust @@ -6731,6 +8275,23 @@ impl A for Foo { } ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "mpmc_channel", + description: r##"# `mpmc_channel` + +The tracking issue for this feature is: [#126840] + +[#126840]: https://github.com/rust-lang/rust/issues/126840 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "multiple_supertrait_upcastable", @@ -6740,6 +8301,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "must_not_suspend", @@ -6751,6 +8315,9 @@ The tracking issue for this feature is: [#83310] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "mut_ref", @@ -6762,6 +8329,9 @@ The tracking issue for this feature is: [#123076] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "naked_functions", @@ -6773,6 +8343,9 @@ The tracking issue for this feature is: [#90957] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "native_link_modifiers_as_needed", @@ -6795,6 +8368,9 @@ The modifier does nothing for linkers that don't support it (e.g. `link.exe`). The default for this modifier is unclear, some targets currently specify it as `+as-needed`, some do not. We may want to try making `+as-needed` a default for all targets. "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "needs_panic_runtime", @@ -6806,6 +8382,9 @@ The tracking issue for this feature is: [#32837] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "negative_bounds", @@ -6815,6 +8394,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "negative_impls", @@ -6876,6 +8458,9 @@ This serves two purposes: * For proving the correctness of unsafe code, we can use that impl as evidence that no `DerefMut` or `Clone` impl exists. * It prevents downstream crates from creating such impls. "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "never_patterns", @@ -6887,6 +8472,9 @@ The tracking issue for this feature is: [#118155] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "never_type", @@ -6898,6 +8486,9 @@ The tracking issue for this feature is: [#35121] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "never_type_fallback", @@ -6909,6 +8500,9 @@ The tracking issue for this feature is: [#65992] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "new_range_api", @@ -6920,17 +8514,23 @@ The tracking issue for this feature is: [#125687] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "new_uninit", - description: r##"# `new_uninit` + label: "new_zeroed_alloc", + description: r##"# `new_zeroed_alloc` -The tracking issue for this feature is: [#63291] +The tracking issue for this feature is: [#129396] -[#63291]: https://github.com/rust-lang/rust/issues/63291 +[#129396]: https://github.com/rust-lang/rust/issues/129396 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "no_core", @@ -6942,6 +8542,9 @@ The tracking issue for this feature is: [#29639] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "no_sanitize", @@ -6975,6 +8578,9 @@ fn foo() { } ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "non_exhaustive_omitted_patterns_lint", @@ -6986,6 +8592,9 @@ The tracking issue for this feature is: [#89554] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "non_lifetime_binders", @@ -6997,6 +8606,23 @@ The tracking issue for this feature is: [#108185] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "non_null_from_ref", + description: r##"# `non_null_from_ref` + +The tracking issue for this feature is: [#130823] + +[#130823]: https://github.com/rust-lang/rust/issues/130823 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "non_zero_count_ones", @@ -7008,6 +8634,23 @@ The tracking issue for this feature is: [#120287] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "nonzero_bitwise", + description: r##"# `nonzero_bitwise` + +The tracking issue for this feature is: [#128281] + +[#128281]: https://github.com/rust-lang/rust/issues/128281 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "nonzero_from_mut", @@ -7019,6 +8662,9 @@ The tracking issue for this feature is: [#106290] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "nonzero_internals", @@ -7028,6 +8674,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "nonzero_ops", @@ -7039,21 +8688,13 @@ The tracking issue for this feature is: [#84186] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "noop_waker", - description: r##"# `noop_waker` - -The tracking issue for this feature is: [#98286] - -[#98286]: https://github.com/rust-lang/rust/issues/98286 - ------------------------- -"##, - }, - Lint { - label: "num_midpoint", - description: r##"# `num_midpoint` + label: "num_midpoint_signed", + description: r##"# `num_midpoint_signed` The tracking issue for this feature is: [#110840] @@ -7061,6 +8702,9 @@ The tracking issue for this feature is: [#110840] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "numfmt", @@ -7070,17 +8714,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, - }, - Lint { - label: "dyn_compatible_for_dispatch", - description: r##"# `dyn_compatible_for_dispatch` - -The tracking issue for this feature is: [#43561] - -[#43561]: https://github.com/rust-lang/rust/issues/43561 - ------------------------- -"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "offset_of_enum", @@ -7092,17 +8728,9 @@ The tracking issue for this feature is: [#120141] ------------------------ "##, - }, - Lint { - label: "offset_of_nested", - description: r##"# `offset_of_nested` - -The tracking issue for this feature is: [#120140] - -[#120140]: https://github.com/rust-lang/rust/issues/120140 - ------------------------- -"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "offset_of_slice", @@ -7114,6 +8742,9 @@ The tracking issue for this feature is: [#126151] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "omit_gdb_pretty_printer_section", @@ -7123,6 +8754,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "once_cell_get_mut", @@ -7134,6 +8768,9 @@ The tracking issue for this feature is: [#121641] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "once_cell_try", @@ -7145,6 +8782,9 @@ The tracking issue for this feature is: [#109737] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "once_cell_try_insert", @@ -7156,6 +8796,23 @@ The tracking issue for this feature is: [#116693] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "once_wait", + description: r##"# `once_wait` + +The tracking issue for this feature is: [#127527] + +[#127527]: https://github.com/rust-lang/rust/issues/127527 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "one_sided_range", @@ -7167,6 +8824,9 @@ The tracking issue for this feature is: [#69780] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "optimize_attribute", @@ -7178,17 +8838,23 @@ The tracking issue for this feature is: [#54882] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "option_get_or_insert_default", - description: r##"# `option_get_or_insert_default` + label: "option_array_transpose", + description: r##"# `option_array_transpose` -The tracking issue for this feature is: [#82901] +The tracking issue for this feature is: [#130828] -[#82901]: https://github.com/rust-lang/rust/issues/82901 +[#130828]: https://github.com/rust-lang/rust/issues/130828 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "option_zip", @@ -7200,6 +8866,9 @@ The tracking issue for this feature is: [#70086] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "os_str_display", @@ -7211,6 +8880,9 @@ The tracking issue for this feature is: [#120048] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "os_str_slice", @@ -7222,6 +8894,9 @@ The tracking issue for this feature is: [#118485] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "os_string_pathbuf_leak", @@ -7233,6 +8908,23 @@ The tracking issue for this feature is: [#125965] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "os_string_truncate", + description: r##"# `os_string_truncate` + +The tracking issue for this feature is: [#133262] + +[#133262]: https://github.com/rust-lang/rust/issues/133262 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "panic_abort", @@ -7244,6 +8936,9 @@ The tracking issue for this feature is: [#32837] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "panic_always_abort", @@ -7255,6 +8950,9 @@ The tracking issue for this feature is: [#84438] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "panic_backtrace_config", @@ -7266,6 +8964,9 @@ The tracking issue for this feature is: [#93346] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "panic_can_unwind", @@ -7277,6 +8978,9 @@ The tracking issue for this feature is: [#92988] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "panic_internals", @@ -7286,6 +8990,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "panic_payload_as_str", @@ -7297,6 +9004,9 @@ The tracking issue for this feature is: [#125175] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "panic_runtime", @@ -7308,6 +9018,9 @@ The tracking issue for this feature is: [#32837] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "panic_unwind", @@ -7319,6 +9032,9 @@ The tracking issue for this feature is: [#32837] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "panic_update_hook", @@ -7330,6 +9046,9 @@ The tracking issue for this feature is: [#92649] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "patchable_function_entry", @@ -7341,6 +9060,9 @@ The tracking issue for this feature is: [#123115] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "path_add_extension", @@ -7352,6 +9074,9 @@ The tracking issue for this feature is: [#127292] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "path_file_prefix", @@ -7363,6 +9088,9 @@ The tracking issue for this feature is: [#86319] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "pattern", @@ -7374,6 +9102,9 @@ The tracking issue for this feature is: [#27721] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "pattern_complexity", @@ -7383,6 +9114,23 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "pattern_type_macro", + description: r##"# `pattern_type_macro` + +The tracking issue for this feature is: [#123646] + +[#123646]: https://github.com/rust-lang/rust/issues/123646 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "pattern_types", @@ -7394,6 +9142,9 @@ The tracking issue for this feature is: [#123646] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "peer_credentials_unix_socket", @@ -7405,17 +9156,37 @@ The tracking issue for this feature is: [#42839] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "pin_deref_mut", - description: r##"# `pin_deref_mut` + label: "pin_coerce_unsized_trait", + description: r##"# `pin_coerce_unsized_trait` -The tracking issue for this feature is: [#86918] +The tracking issue for this feature is: [#123430] -[#86918]: https://github.com/rust-lang/rust/issues/86918 +[#123430]: https://github.com/rust-lang/rust/issues/123430 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "pin_ergonomics", + description: r##"# `pin_ergonomics` + +The tracking issue for this feature is: [#130494] + +[#130494]: https://github.com/rust-lang/rust/issues/130494 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "pointer_is_aligned_to", @@ -7427,6 +9198,9 @@ The tracking issue for this feature is: [#96284] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "pointer_like_trait", @@ -7436,6 +9210,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "portable_simd", @@ -7447,6 +9224,9 @@ The tracking issue for this feature is: [#86656] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "postfix_match", @@ -7455,6 +9235,10 @@ The tracking issue for this feature is: [#86656] `postfix-match` adds the feature for matching upon values postfix the expressions that generate the values. +The tracking issue for this feature is: [#121618](https://github.com/rust-lang/rust/issues/121618). + +------------------------ + ```rust,edition2021 #![feature(postfix_match)] @@ -7473,6 +9257,9 @@ get_foo().match { } ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "powerpc_target_feature", @@ -7484,17 +9271,23 @@ The tracking issue for this feature is: [#44839] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "precise_capturing", - description: r##"# `precise_capturing` + label: "precise_capturing_in_traits", + description: r##"# `precise_capturing_in_traits` -The tracking issue for this feature is: [#123432] +The tracking issue for this feature is: [#130044] -[#123432]: https://github.com/rust-lang/rust/issues/123432 +[#130044]: https://github.com/rust-lang/rust/issues/130044 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "prelude_2024", @@ -7506,6 +9299,9 @@ The tracking issue for this feature is: [#121042] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "prelude_import", @@ -7515,6 +9311,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "prfchw_target_feature", @@ -7526,6 +9325,9 @@ The tracking issue for this feature is: [#44839] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "print_internals", @@ -7535,6 +9337,9 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "proc_macro_def_site", @@ -7546,6 +9351,9 @@ The tracking issue for this feature is: [#54724] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "proc_macro_diagnostic", @@ -7557,6 +9365,9 @@ The tracking issue for this feature is: [#54140] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "proc_macro_expand", @@ -7568,6 +9379,9 @@ The tracking issue for this feature is: [#90765] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "proc_macro_hygiene", @@ -7579,6 +9393,9 @@ The tracking issue for this feature is: [#54727] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "proc_macro_internals", @@ -7590,6 +9407,9 @@ The tracking issue for this feature is: [#27812] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "proc_macro_quote", @@ -7601,6 +9421,9 @@ The tracking issue for this feature is: [#54722] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "proc_macro_span", @@ -7612,6 +9435,23 @@ The tracking issue for this feature is: [#54725] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "proc_macro_totokens", + description: r##"# `proc_macro_totokens` + +The tracking issue for this feature is: [#130977] + +[#130977]: https://github.com/rust-lang/rust/issues/130977 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "proc_macro_tracked_env", @@ -7623,6 +9463,9 @@ The tracking issue for this feature is: [#99515] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "process_exitcode_internals", @@ -7632,6 +9475,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "process_internals", @@ -7641,6 +9487,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "profiler_runtime", @@ -7650,6 +9499,9 @@ The tracking issue for this feature is: [#42524](https://github.com/rust-lang/ru ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "profiler_runtime_lib", @@ -7659,6 +9511,9 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "ptr_alignment_type", @@ -7670,6 +9525,9 @@ The tracking issue for this feature is: [#102070] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "ptr_as_ref_unchecked", @@ -7681,6 +9539,9 @@ The tracking issue for this feature is: [#122034] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "ptr_as_uninit", @@ -7692,6 +9553,9 @@ The tracking issue for this feature is: [#75402] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "ptr_internals", @@ -7701,6 +9565,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "ptr_mask", @@ -7712,6 +9579,9 @@ The tracking issue for this feature is: [#98290] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "ptr_metadata", @@ -7723,6 +9593,9 @@ The tracking issue for this feature is: [#81513] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "ptr_sub_ptr", @@ -7734,6 +9607,9 @@ The tracking issue for this feature is: [#95892] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "pub_crate_should_not_need_unstable_attr", @@ -7743,28 +9619,37 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "raw_os_error_ty", - description: r##"# `raw_os_error_ty` + label: "random", + description: r##"# `random` -The tracking issue for this feature is: [#107792] +The tracking issue for this feature is: [#130703] -[#107792]: https://github.com/rust-lang/rust/issues/107792 +[#130703]: https://github.com/rust-lang/rust/issues/130703 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "raw_ref_op", - description: r##"# `raw_ref_op` + label: "raw_os_error_ty", + description: r##"# `raw_os_error_ty` -The tracking issue for this feature is: [#64490] +The tracking issue for this feature is: [#107792] -[#64490]: https://github.com/rust-lang/rust/issues/64490 +[#107792]: https://github.com/rust-lang/rust/issues/107792 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "raw_slice_split", @@ -7776,6 +9661,9 @@ The tracking issue for this feature is: [#95595] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "raw_vec_internals", @@ -7785,6 +9673,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "read_buf", @@ -7796,26 +9687,9 @@ The tracking issue for this feature is: [#78485] ------------------------ "##, - }, - Lint { - label: "ready_into_inner", - description: r##"# `ready_into_inner` - -The tracking issue for this feature is: [#101196] - -[#101196]: https://github.com/rust-lang/rust/issues/101196 - ------------------------- -"##, - }, - Lint { - label: "receiver_trait", - description: r##"# `receiver_trait` - -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. - ------------------------- -"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "reentrant_lock", @@ -7827,6 +9701,9 @@ The tracking issue for this feature is: [#121440] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "ref_pat_eat_one_layer_2024", @@ -7838,6 +9715,9 @@ The tracking issue for this feature is: [#123076] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "ref_pat_eat_one_layer_2024_structural", @@ -7849,6 +9729,9 @@ The tracking issue for this feature is: [#123076] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "register_tool", @@ -7860,6 +9743,9 @@ The tracking issue for this feature is: [#66079] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "repr128", @@ -7882,6 +9768,9 @@ enum Foo { } ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "repr_simd", @@ -7893,6 +9782,9 @@ The tracking issue for this feature is: [#27731] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "restricted_std", @@ -7902,24 +9794,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, - }, - Lint { - label: "result_ffi_guarantees", - description: r##"# `result_ffi_guarantees` - -The tracking issue for this feature is: [#110503] - -[#110503]: https://github.com/rust-lang/rust/issues/110503 - ------------------------- - -This feature adds the possibility of using `Result<T, E>` in FFI if T's niche -value can be used to describe E or vise-versa. - -See [RFC 3391] for more information. - -[RFC 3391]: https://github.com/rust-lang/rfcs/blob/master/text/3391-result_ffi_guarantees.md -"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "result_flattening", @@ -7931,6 +9808,9 @@ The tracking issue for this feature is: [#70142] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "return_type_notation", @@ -7942,6 +9822,9 @@ The tracking issue for this feature is: [#109417] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "riscv_target_feature", @@ -7953,6 +9836,9 @@ The tracking issue for this feature is: [#44839] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "round_char_boundary", @@ -7964,6 +9850,9 @@ The tracking issue for this feature is: [#93743] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "rt", @@ -7973,6 +9862,9 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "rtm_target_feature", @@ -7984,6 +9876,9 @@ The tracking issue for this feature is: [#44839] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "rust_cold_cc", @@ -7995,6 +9890,9 @@ The tracking issue for this feature is: [#97544] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "rustc_allow_const_fn_unstable", @@ -8006,6 +9904,9 @@ The tracking issue for this feature is: [#69399] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "rustc_attrs", @@ -8063,6 +9964,9 @@ error: size: Size { raw: 16 } error: aborting due to 2 previous errors ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "rustc_encodable_decodable", @@ -8072,6 +9976,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "rustc_private", @@ -8082,7 +9989,14 @@ The tracking issue for this feature is: [#27812] [#27812]: https://github.com/rust-lang/rust/issues/27812 ------------------------ + +This feature allows access to unstable internal compiler crates. + +Additionally it changes the linking behavior of crates which have this feature enabled. It will prevent linking to a dylib if there's a static variant of it already statically linked into another dylib dependency. This is required to successfully link to `rustc_driver`. "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "rustdoc_internals", @@ -8094,6 +10008,9 @@ The tracking issue for this feature is: [#90418] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "rustdoc_missing_doc_code_examples", @@ -8105,6 +10022,23 @@ The tracking issue for this feature is: [#101730] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "rwlock_downgrade", + description: r##"# `rwlock_downgrade` + +The tracking issue for this feature is: [#128203] + +[#128203]: https://github.com/rust-lang/rust/issues/128203 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "s390x_target_feature", @@ -8116,6 +10050,9 @@ The tracking issue for this feature is: [#44839] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "sealed", @@ -8125,6 +10062,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "seek_stream_len", @@ -8136,6 +10076,9 @@ The tracking issue for this feature is: [#59359] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "set_ptr_value", @@ -8147,6 +10090,9 @@ The tracking issue for this feature is: [#75091] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "setgroups", @@ -8158,6 +10104,9 @@ The tracking issue for this feature is: [#90747] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "sgx_platform", @@ -8169,17 +10118,23 @@ The tracking issue for this feature is: [#56975] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "shorter_tail_lifetimes", - description: r##"# `shorter_tail_lifetimes` + label: "sha512_sm_x86", + description: r##"# `sha512_sm_x86` -The tracking issue for this feature is: [#123739] +The tracking issue for this feature is: [#126624] -[#123739]: https://github.com/rust-lang/rust/issues/123739 +[#126624]: https://github.com/rust-lang/rust/issues/126624 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "simd_ffi", @@ -8191,6 +10146,9 @@ The tracking issue for this feature is: [#27731] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "sized_type_properties", @@ -8200,6 +10158,23 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "slice_as_array", + description: r##"# `slice_as_array` + +The tracking issue for this feature is: [#133508] + +[#133508]: https://github.com/rust-lang/rust/issues/133508 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "slice_as_chunks", @@ -8211,6 +10186,9 @@ The tracking issue for this feature is: [#74985] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "slice_concat_ext", @@ -8222,6 +10200,9 @@ The tracking issue for this feature is: [#27747] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "slice_concat_trait", @@ -8233,6 +10214,9 @@ The tracking issue for this feature is: [#27747] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "slice_from_ptr_range", @@ -8244,6 +10228,9 @@ The tracking issue for this feature is: [#89792] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "slice_index_methods", @@ -8253,6 +10240,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "slice_internals", @@ -8262,6 +10252,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "slice_iter_mut_as_mut_slice", @@ -8273,6 +10266,9 @@ The tracking issue for this feature is: [#93079] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "slice_partition_dedup", @@ -8284,6 +10280,9 @@ The tracking issue for this feature is: [#54279] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "slice_pattern", @@ -8295,6 +10294,9 @@ The tracking issue for this feature is: [#56345] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "slice_ptr_get", @@ -8306,6 +10308,9 @@ The tracking issue for this feature is: [#74265] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "slice_range", @@ -8317,6 +10322,9 @@ The tracking issue for this feature is: [#76393] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "slice_split_once", @@ -8328,6 +10336,9 @@ The tracking issue for this feature is: [#112811] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "slice_swap_unchecked", @@ -8339,6 +10350,9 @@ The tracking issue for this feature is: [#88539] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "slice_take", @@ -8350,6 +10364,9 @@ The tracking issue for this feature is: [#62280] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "solid_ext", @@ -8359,6 +10376,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "sort_floats", @@ -8370,6 +10390,23 @@ The tracking issue for this feature is: [#93396] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "sparc_target_feature", + description: r##"# `sparc_target_feature` + +The tracking issue for this feature is: [#132783] + +[#132783]: https://github.com/rust-lang/rust/issues/132783 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "specialization", @@ -8381,6 +10418,9 @@ The tracking issue for this feature is: [#31844] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "split_array", @@ -8392,6 +10432,9 @@ The tracking issue for this feature is: [#90091] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "split_as_slice", @@ -8403,6 +10446,9 @@ The tracking issue for this feature is: [#96137] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "sse4a_target_feature", @@ -8414,6 +10460,9 @@ The tracking issue for this feature is: [#44839] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "staged_api", @@ -8423,6 +10472,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "start", @@ -8486,6 +10538,9 @@ fn start(_argc: isize, _argv: *const *const u8) -> isize { } ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "std_internals", @@ -8495,6 +10550,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "stdarch_arm_feature_detection", @@ -8506,6 +10564,9 @@ The tracking issue for this feature is: [#111190] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "stdarch_mips_feature_detection", @@ -8517,6 +10578,9 @@ The tracking issue for this feature is: [#111188] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "stdarch_powerpc_feature_detection", @@ -8528,6 +10592,9 @@ The tracking issue for this feature is: [#111191] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "stdio_makes_pipe", @@ -8539,6 +10606,9 @@ The tracking issue for this feature is: [#98288] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "step_trait", @@ -8550,6 +10620,9 @@ The tracking issue for this feature is: [#42168] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "stmt_expr_attributes", @@ -8561,6 +10634,23 @@ The tracking issue for this feature is: [#15701] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "str_as_str", + description: r##"# `str_as_str` + +The tracking issue for this feature is: [#130366] + +[#130366]: https://github.com/rust-lang/rust/issues/130366 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "str_from_raw_parts", @@ -8572,6 +10662,9 @@ The tracking issue for this feature is: [#119206] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "str_from_utf16_endian", @@ -8583,6 +10676,9 @@ The tracking issue for this feature is: [#116258] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "str_internals", @@ -8592,6 +10688,9 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "str_lines_remainder", @@ -8603,6 +10702,9 @@ The tracking issue for this feature is: [#77998] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "str_split_inclusive_remainder", @@ -8614,6 +10716,9 @@ The tracking issue for this feature is: [#77998] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "str_split_remainder", @@ -8625,6 +10730,9 @@ The tracking issue for this feature is: [#77998] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "str_split_whitespace_remainder", @@ -8636,6 +10744,9 @@ The tracking issue for this feature is: [#77998] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "strict_overflow_ops", @@ -8647,24 +10758,40 @@ The tracking issue for this feature is: [#118260] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "strict_provenance", - description: r##"# `strict_provenance` + label: "strict_provenance_atomic_ptr", + description: r##"# `strict_provenance_atomic_ptr` + +The tracking issue for this feature is: [#99108] + +[#99108]: https://github.com/rust-lang/rust/issues/99108 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "strict_provenance_lints", + description: r##"# `strict_provenance_lints` The tracking issue for this feature is: [#95228] [#95228]: https://github.com/rust-lang/rust/issues/95228 ----- -The `strict_provenance` feature allows to enable the `fuzzy_provenance_casts` and `lossy_provenance_casts` lints. +The `strict_provenance_lints` feature allows to enable the `fuzzy_provenance_casts` and `lossy_provenance_casts` lints. These lint on casts between integers and pointers, that are recommended against or invalid in the strict provenance model. -The same feature gate is also used for the experimental strict provenance API in `std` (actually `core`). ## Example ```rust -#![feature(strict_provenance)] +#![feature(strict_provenance_lints)] #![warn(fuzzy_provenance_casts)] fn main() { @@ -8673,17 +10800,9 @@ fn main() { } ``` "##, - }, - Lint { - label: "strict_provenance_atomic_ptr", - description: r##"# `strict_provenance_atomic_ptr` - -The tracking issue for this feature is: [#99108] - -[#99108]: https://github.com/rust-lang/rust/issues/99108 - ------------------------- -"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "string_deref_patterns", @@ -8733,6 +10852,9 @@ pub fn is_it_the_answer(value: Value) -> bool { [its `Deref` implementation]: https://doc.rust-lang.org/std/string/struct.String.html#impl-Deref-for-String "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "string_extend_from_within", @@ -8744,6 +10866,23 @@ The tracking issue for this feature is: [#103806] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "string_from_utf8_lossy_owned", + description: r##"# `string_from_utf8_lossy_owned` + +The tracking issue for this feature is: [#129436] + +[#129436]: https://github.com/rust-lang/rust/issues/129436 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "string_remove_matches", @@ -8755,6 +10894,9 @@ The tracking issue for this feature is: [#72826] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "structural_match", @@ -8766,6 +10908,23 @@ The tracking issue for this feature is: [#31434] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "substr_range", + description: r##"# `substr_range` + +The tracking issue for this feature is: [#126769] + +[#126769]: https://github.com/rust-lang/rust/issues/126769 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "sync_unsafe_cell", @@ -8777,6 +10936,9 @@ The tracking issue for this feature is: [#95439] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "target_feature_11", @@ -8788,6 +10950,9 @@ The tracking issue for this feature is: [#69098] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "tbm_target_feature", @@ -8799,6 +10964,9 @@ The tracking issue for this feature is: [#44839] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "tcp_deferaccept", @@ -8810,6 +10978,9 @@ The tracking issue for this feature is: [#119639] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "tcp_linger", @@ -8821,6 +10992,9 @@ The tracking issue for this feature is: [#88494] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "tcp_quickack", @@ -8832,6 +11006,9 @@ The tracking issue for this feature is: [#96256] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "tcplistener_into_incoming", @@ -8843,6 +11020,9 @@ The tracking issue for this feature is: [#88373] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "test", @@ -9005,6 +11185,9 @@ test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured However, the optimizer can still modify a testcase in an undesirable manner even when using either of the above. "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "test_unstable_lint", @@ -9014,6 +11197,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "thin_box", @@ -9025,6 +11211,9 @@ The tracking issue for this feature is: [#92791] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "thread_id_value", @@ -9036,6 +11225,9 @@ The tracking issue for this feature is: [#67939] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "thread_local", @@ -9047,6 +11239,9 @@ The tracking issue for this feature is: [#29594] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "thread_local_internals", @@ -9056,6 +11251,23 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "thread_raw", + description: r##"# `thread_raw` + +The tracking issue for this feature is: [#97523] + +[#97523]: https://github.com/rust-lang/rust/issues/97523 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "thread_sleep_until", @@ -9067,17 +11279,23 @@ The tracking issue for this feature is: [#113752] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "thread_spawn_unchecked", - description: r##"# `thread_spawn_unchecked` + label: "thread_spawn_hook", + description: r##"# `thread_spawn_hook` -The tracking issue for this feature is: [#55132] +The tracking issue for this feature is: [#132951] -[#55132]: https://github.com/rust-lang/rust/issues/55132 +[#132951]: https://github.com/rust-lang/rust/issues/132951 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "trace_macros", @@ -9121,6 +11339,9 @@ note: trace_macro Finished dev [unoptimized + debuginfo] target(s) in 0.60 secs ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "track_path", @@ -9132,6 +11353,9 @@ The tracking issue for this feature is: [#99515] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "trait_alias", @@ -9170,6 +11394,9 @@ pub fn main() { } ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "trait_upcasting", @@ -9187,7 +11414,6 @@ so long as `Bar: Foo`. ```rust,edition2018 #![feature(trait_upcasting)] -#![allow(incomplete_features)] trait Foo {} @@ -9201,6 +11427,9 @@ let bar: &dyn Bar = &123; let foo: &dyn Foo = bar; ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "transmutability", @@ -9212,6 +11441,9 @@ The tracking issue for this feature is: [#99571] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "transmute_generic_consts", @@ -9223,6 +11455,9 @@ The tracking issue for this feature is: [#109929] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "transparent_unions", @@ -9310,6 +11545,9 @@ it is transparent). The Rust compiler is free to perform this optimization if possible, but is not required to, and different compiler versions may differ in their application of these optimizations. "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "trivial_bounds", @@ -9321,6 +11559,9 @@ The tracking issue for this feature is: [#48214] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "trusted_fused", @@ -9330,6 +11571,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "trusted_len", @@ -9341,6 +11585,9 @@ The tracking issue for this feature is: [#37572] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "trusted_len_next_unchecked", @@ -9352,6 +11599,9 @@ The tracking issue for this feature is: [#37572] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "trusted_random_access", @@ -9361,6 +11611,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "trusted_step", @@ -9372,6 +11625,9 @@ The tracking issue for this feature is: [#85731] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "try_blocks", @@ -9406,6 +11662,9 @@ let result: Result<i32, ParseIntError> = try { assert!(result.is_err()); ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "try_find", @@ -9417,6 +11676,9 @@ The tracking issue for this feature is: [#63178] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "try_reserve_kind", @@ -9428,6 +11690,9 @@ The tracking issue for this feature is: [#48043] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "try_trait_v2", @@ -9439,6 +11704,9 @@ The tracking issue for this feature is: [#84277] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "try_trait_v2_residual", @@ -9450,6 +11718,9 @@ The tracking issue for this feature is: [#91285] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "try_trait_v2_yeet", @@ -9461,6 +11732,9 @@ The tracking issue for this feature is: [#96374] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "try_with_capacity", @@ -9472,6 +11746,9 @@ The tracking issue for this feature is: [#91913] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "tuple_trait", @@ -9481,6 +11758,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "type_alias_impl_trait", @@ -9492,6 +11772,9 @@ The tracking issue for this feature is: [#63063] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "type_ascription", @@ -9503,6 +11786,9 @@ The tracking issue for this feature is: [#23416] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "type_changing_struct_update", @@ -9540,6 +11826,9 @@ fn main () { } ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "ub_checks", @@ -9549,6 +11838,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "uefi_std", @@ -9560,6 +11852,23 @@ The tracking issue for this feature is: [#100499] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "unbounded_shifts", + description: r##"# `unbounded_shifts` + +The tracking issue for this feature is: [#129375] + +[#129375]: https://github.com/rust-lang/rust/issues/129375 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "unboxed_closures", @@ -9589,6 +11898,9 @@ extern "rust-call" fn add_args(args: (u32, u32)) -> u32 { fn main() {} ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "unchecked_neg", @@ -9600,6 +11912,9 @@ The tracking issue for this feature is: [#85122] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "unchecked_shifts", @@ -9611,6 +11926,9 @@ The tracking issue for this feature is: [#85122] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "unicode_internals", @@ -9620,6 +11938,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "unique_rc_arc", @@ -9631,6 +11952,9 @@ The tracking issue for this feature is: [#112566] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "unix_file_vectored_at", @@ -9642,6 +11966,9 @@ The tracking issue for this feature is: [#89517] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "unix_set_mark", @@ -9653,6 +11980,9 @@ The tracking issue for this feature is: [#96467] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "unix_socket_ancillary_data", @@ -9664,6 +11994,9 @@ The tracking issue for this feature is: [#76915] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "unix_socket_peek", @@ -9675,59 +12008,89 @@ The tracking issue for this feature is: [#76923] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "unnamed_fields", - description: r##"# `unnamed_fields` + label: "unqualified_local_imports", + description: r##"# `unqualified_local_imports` -The tracking issue for this feature is: [#49804] - -[#49804]: https://github.com/rust-lang/rust/issues/49804 +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "unsafe_attributes", - description: r##"# `unsafe_attributes` + label: "unsafe_fields", + description: r##"# `unsafe_fields` -The tracking issue for this feature is: [#123757] +The tracking issue for this feature is: [#132922] -[#123757]: https://github.com/rust-lang/rust/issues/123757 +[#132922]: https://github.com/rust-lang/rust/issues/132922 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "unsafe_cell_from_mut", - description: r##"# `unsafe_cell_from_mut` + label: "unsafe_pin_internals", + description: r##"# `unsafe_pin_internals` + +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "unsigned_is_multiple_of", + description: r##"# `unsigned_is_multiple_of` -The tracking issue for this feature is: [#111645] +The tracking issue for this feature is: [#128101] -[#111645]: https://github.com/rust-lang/rust/issues/111645 +[#128101]: https://github.com/rust-lang/rust/issues/128101 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "unsafe_extern_blocks", - description: r##"# `unsafe_extern_blocks` + label: "unsigned_nonzero_div_ceil", + description: r##"# `unsigned_nonzero_div_ceil` -The tracking issue for this feature is: [#123743] +The tracking issue for this feature is: [#132968] -[#123743]: https://github.com/rust-lang/rust/issues/123743 +[#132968]: https://github.com/rust-lang/rust/issues/132968 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "unsafe_pin_internals", - description: r##"# `unsafe_pin_internals` + label: "unsigned_signed_diff", + description: r##"# `unsigned_signed_diff` -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. +The tracking issue for this feature is: [#126041] + +[#126041]: https://github.com/rust-lang/rust/issues/126041 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "unsize", @@ -9739,6 +12102,9 @@ The tracking issue for this feature is: [#18598] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "unsized_const_params", @@ -9750,6 +12116,9 @@ The tracking issue for this feature is: [#95174] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "unsized_fn_params", @@ -9761,6 +12130,9 @@ The tracking issue for this feature is: [#48055] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "unsized_locals", @@ -9940,6 +12312,9 @@ fn main() { will unnecessarily extend the stack frame. "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "unsized_tuple_coercion", @@ -9971,6 +12346,9 @@ fn main() { [RFC0401]: https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "unwrap_infallible", @@ -9982,6 +12360,9 @@ The tracking issue for this feature is: [#61695] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "update_panic_count", @@ -9991,6 +12372,9 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "used_with_arg", @@ -10002,6 +12386,9 @@ The tracking issue for this feature is: [#93798] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "utf16_extra", @@ -10013,28 +12400,37 @@ The tracking issue for this feature is: [#94919] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "utf16_extra_const", - description: r##"# `utf16_extra_const` + label: "variant_count", + description: r##"# `variant_count` -The tracking issue for this feature is: [#94919] +The tracking issue for this feature is: [#73662] -[#94919]: https://github.com/rust-lang/rust/issues/94919 +[#73662]: https://github.com/rust-lang/rust/issues/73662 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "variant_count", - description: r##"# `variant_count` + label: "vec_deque_iter_as_slices", + description: r##"# `vec_deque_iter_as_slices` -The tracking issue for this feature is: [#73662] +The tracking issue for this feature is: [#123947] -[#73662]: https://github.com/rust-lang/rust/issues/73662 +[#123947]: https://github.com/rust-lang/rust/issues/123947 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "vec_into_raw_parts", @@ -10046,6 +12442,9 @@ The tracking issue for this feature is: [#65816] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "vec_pop_if", @@ -10057,6 +12456,9 @@ The tracking issue for this feature is: [#122741] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "vec_push_within_capacity", @@ -10068,6 +12470,9 @@ The tracking issue for this feature is: [#100486] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "vec_split_at_spare", @@ -10079,17 +12484,9 @@ The tracking issue for this feature is: [#81944] ------------------------ "##, - }, - Lint { - label: "waker_getters", - description: r##"# `waker_getters` - -The tracking issue for this feature is: [#96992] - -[#96992]: https://github.com/rust-lang/rust/issues/96992 - ------------------------- -"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "wasi_ext", @@ -10101,6 +12498,9 @@ The tracking issue for this feature is: [#71213] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "wasm_target_feature", @@ -10112,6 +12512,9 @@ The tracking issue for this feature is: [#44839] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "windows_by_handle", @@ -10123,6 +12526,9 @@ The tracking issue for this feature is: [#63010] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "windows_c", @@ -10132,6 +12538,9 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "windows_change_time", @@ -10143,6 +12552,9 @@ The tracking issue for this feature is: [#121478] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "windows_handle", @@ -10152,6 +12564,9 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "windows_net", @@ -10161,6 +12576,9 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "windows_process_exit_code_from", @@ -10172,6 +12590,9 @@ The tracking issue for this feature is: [#111688] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "windows_process_extensions_async_pipes", @@ -10183,6 +12604,9 @@ The tracking issue for this feature is: [#98289] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "windows_process_extensions_force_quotes", @@ -10194,6 +12618,9 @@ The tracking issue for this feature is: [#82227] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "windows_process_extensions_main_thread_handle", @@ -10205,6 +12632,9 @@ The tracking issue for this feature is: [#96723] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "windows_process_extensions_raw_attribute", @@ -10216,6 +12646,9 @@ The tracking issue for this feature is: [#114854] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "windows_process_extensions_show_window", @@ -10227,6 +12660,9 @@ The tracking issue for this feature is: [#127544] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "windows_stdio", @@ -10236,6 +12672,9 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "with_negative_coherence", @@ -10245,6 +12684,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "wrapping_int_impl", @@ -10256,6 +12698,9 @@ The tracking issue for this feature is: [#32463] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "wrapping_next_power_of_two", @@ -10267,6 +12712,9 @@ The tracking issue for this feature is: [#32463] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "write_all_vectored", @@ -10278,6 +12726,9 @@ The tracking issue for this feature is: [#70436] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "x86_amx_intrinsics", @@ -10289,6 +12740,9 @@ The tracking issue for this feature is: [#126622] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "xop_target_feature", @@ -10300,6 +12754,9 @@ The tracking issue for this feature is: [#127208] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "yeet_desugar_details", @@ -10309,6 +12766,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "yeet_expr", @@ -10339,6 +12799,9 @@ fn bar() -> Option<String> { assert_eq!(bar(), None); ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, ]; @@ -10346,6 +12809,9 @@ pub const CLIPPY_LINTS: &[Lint] = &[ Lint { label: "clippy::absolute_paths", description: r##"Checks for usage of items through absolute paths, like `std::env::current_dir`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::absurd_extreme_comparisons", @@ -10353,10 +12819,16 @@ pub const CLIPPY_LINTS: &[Lint] = &[ either the minimum or maximum value for its type and warns if it involves a case that is always true or always false. Only integer and boolean types are checked."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::alloc_instead_of_core", description: r##"Finds items imported through `alloc` when available through `core`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::allow_attributes", @@ -10365,19 +12837,31 @@ the `#[expect]` (See [RFC 2383](https://rust-lang.github.io/rfcs/2383-lint-reaso This lint only warns outer attributes (`#[allow]`), as inner attributes (`#![allow]`) are usually used to enable or disable lints on a global scale."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::allow_attributes_without_reason", description: r##"Checks for attributes that allow lints without a reason."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::almost_complete_range", description: r##"Checks for ranges which almost include the entire range of letters from 'a' to 'z' or digits from '0' to '9', but don't because they're a half open range."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::almost_swapped", description: r##"Checks for `foo = bar; bar = foo` sequences."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::approx_constant", @@ -10387,11 +12871,17 @@ constants which are defined in or [`std::f64::consts`](https://doc.rust-lang.org/stable/std/f64/consts/#constants), respectively, suggesting to use the predefined constant."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::arc_with_non_send_sync", description: r##". This lint warns when you use `Arc` with a type that does not implement `Send` or `Sync`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::arithmetic_side_effects", @@ -10403,6 +12893,9 @@ or can panic (`/`, `%`). Known safe built-in types like `Wrapping` or `Saturating`, floats, operations in constant environments, allowed types and non-constant operations that won't overflow are ignored."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::as_conversions", @@ -10415,54 +12908,90 @@ If you want more precise lints for `as`, please consider using these separate li `fn_to_numeric_cast(_with_truncation)`, `char_lit_as_u8`, `ref_to_mut` and `ptr_as_ptr`. There is a good explanation the reason why this lint should work in this way and how it is useful [in this issue](https://github.com/rust-lang/rust-clippy/issues/5122)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::as_ptr_cast_mut", description: r##"Checks for the result of a `&self`-taking `as_ptr` being cast to a mutable pointer."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::as_underscore", description: r##"Checks for the usage of `as _` conversion using inferred type."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::assertions_on_constants", description: r##"Checks for `assert!(true)` and `assert!(false)` calls."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::assertions_on_result_states", description: r##"Checks for `assert!(r.is_ok())` or `assert!(r.is_err())` calls."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::assign_op_pattern", description: r##"Checks for `a = a op b` or `a = b commutative_op a` patterns."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::assign_ops", - description: r##"Nothing. This lint has been deprecated."##, + description: r##"Nothing. This lint has been deprecated"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::assigning_clones", description: r##"Checks for code like `foo = bar.clone();`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::async_yields_async", description: r##"Checks for async blocks that yield values of types that can themselves be awaited."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::await_holding_invalid_type", description: r##"Allows users to configure types which should not be held across await suspension points."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::await_holding_lock", description: r##"Checks for calls to `await` while holding a non-async-aware `MutexGuard`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::await_holding_refcell_ref", description: r##"Checks for calls to `await` while holding a `RefCell`, `Ref`, or `RefMut`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::bad_bit_mask", @@ -10481,126 +13010,210 @@ table: |`==` or `!=`| `\\|` |`x \\| 1 == 0`|`false` |`c \\| m != c` | |`<` or `>=`| `\\|` |`x \\| 1 < 1` |`false` |`m >= c` | |`<=` or `>` | `\\|` |`x \\| 1 > 0` |`true` |`m > c` |"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::big_endian_bytes", description: r##"Checks for the usage of the `to_be_bytes` method and/or the function `from_be_bytes`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::bind_instead_of_map", description: r##"Checks for usage of `_.and_then(|x| Some(y))`, `_.and_then(|x| Ok(y))` or `_.or_else(|x| Err(y))`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::blanket_clippy_restriction_lints", description: r##"Checks for `warn`/`deny`/`forbid` attributes targeting the whole clippy::restriction category."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::blocks_in_conditions", description: r##"Checks for `if` and `match` conditions that use blocks containing an expression, statements or conditions that use closures with blocks."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::bool_assert_comparison", description: r##"This lint warns about boolean comparisons in assert-like macros."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::bool_comparison", description: r##"Checks for expressions of the form `x == true`, `x != true` and order comparisons such as `x < true` (or vice versa) and suggest using the variable directly."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::bool_to_int_with_if", description: r##"Instead of using an if statement to convert a bool to an int, this lint suggests using a `from()` function or an `as` coercion."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::borrow_as_ptr", description: r##"Checks for the usage of `&expr as *const T` or `&mut expr as *mut T`, and suggest using `ptr::addr_of` or `ptr::addr_of_mut` instead."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::borrow_deref_ref", + description: r##"Checks for `&*(&T)`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::borrow_deref_ref", description: r##"Checks for `&*(&T)`."## }, Lint { label: "clippy::borrow_interior_mutable_const", description: r##"Checks if `const` items which is interior mutable (e.g., contains a `Cell`, `Mutex`, `AtomicXxxx`, etc.) has been borrowed directly."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::borrowed_box", description: r##"Checks for usage of `&Box<T>` anywhere in the code. Check the [Box documentation](https://doc.rust-lang.org/std/boxed/index.html) for more information."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::box_collection", description: r##"Checks for usage of `Box<T>` where T is a collection such as Vec anywhere in the code. Check the [Box documentation](https://doc.rust-lang.org/std/boxed/index.html) for more information."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::box_default", description: r##"checks for `Box::new(Default::default())`, which can be written as `Box::default()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::boxed_local", description: r##"Checks for usage of `Box<T>` where an unboxed `T` would work fine."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::branches_sharing_code", description: r##"Checks if the `if` and `else` block contain shared code that can be moved out of the blocks."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::builtin_type_shadow", description: r##"Warns if a generic shadows a built-in type."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::byte_char_slices", description: r##"Checks for hard to read slices of byte characters, that could be more easily expressed as a byte string."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::bytes_count_to_len", description: r##"It checks for `str::bytes().count()` and suggests replacing it with `str::len()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::bytes_nth", description: r##"Checks for the use of `.bytes().nth()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::cargo_common_metadata", description: r##"Checks to see if all common metadata is defined in `Cargo.toml`. See: https://rust-lang-nursery.github.io/api-guidelines/documentation.html#cargotoml-includes-all-common-metadata-c-metadata"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::case_sensitive_file_extension_comparisons", description: r##"Checks for calls to `ends_with` with possible file extensions and suggests to use a case-insensitive approach instead."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::cast_abs_to_unsigned", description: r##"Checks for usage of the `abs()` method that cast the result to unsigned."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::cast_enum_constructor", description: r##"Checks for casts from an enum tuple constructor to an integer."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::cast_enum_truncation", description: r##"Checks for casts from an enum type to an integral type that will definitely truncate the value."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::cast_lossless", description: r##"Checks for casts between numeric types that can be replaced by safe conversion functions."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::cast_nan_to_int", description: r##"Checks for a known NaN float being cast to an integer"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::cast_possible_truncation", @@ -10608,6 +13221,9 @@ conversion functions."##, truncate large values. This is expected behavior, so the cast is `Allow` by default. It suggests user either explicitly ignore the lint, or use `try_from()` and handle the truncation, default, or panic explicitly."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::cast_possible_wrap", @@ -10618,6 +13234,9 @@ changed at the bit level), and the binary representation of the value is reinterpreted. This can cause wrapping if the value is too big for the target signed type. However, the cast works as defined, so this lint is `Allow` by default."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::cast_precision_loss", @@ -10628,11 +13247,17 @@ rounding errors. This possible rounding is to be expected, so this lint is Basically, this warns on casting any integer with 32 or more bits to `f32` or any 64-bit integer to `f64`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::cast_ptr_alignment", description: r##"Checks for casts, using `as` or `pointer::cast`, from a less strictly aligned pointer to a more strictly aligned pointer."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::cast_sign_loss", @@ -10640,79 +13265,130 @@ less strictly aligned pointer to a more strictly aligned pointer."##, type. In this case, negative values wrap around to large positive values, which can be quite surprising in practice. However, since the cast works as defined, this lint is `Allow` by default."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::cast_slice_different_sizes", description: r##"Checks for `as` casts between raw pointers to slices with differently sized elements."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::cast_slice_from_raw_parts", description: r##"Checks for a raw slice being cast to a slice pointer"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::cfg_not_test", - description: r##"Checks for usage of `cfg` that excludes code from `test` builds. (i.e., `#{cfg(not(test))]`)"##, + description: r##"Checks for usage of `cfg` that excludes code from `test` builds. (i.e., `#[cfg(not(test))]`)"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::char_lit_as_u8", description: r##"Checks for expressions where a character literal is cast to `u8` and suggests using a byte literal instead."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::chars_last_cmp", description: r##"Checks for usage of `_.chars().last()` or `_.chars().next_back()` on a `str` to check if it ends with a given char."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::chars_next_cmp", description: r##"Checks for usage of `.chars().next()` on a `str` to check if it starts with a given char."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::checked_conversions", description: r##"Checks for explicit bounds checking when casting."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::clear_with_drain", description: r##"Checks for usage of `.drain(..)` for the sole purpose of clearing a container."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::clone_on_copy", description: r##"Checks for usage of `.clone()` on a `Copy` type."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::clone_on_ref_ptr", description: r##"Checks for usage of `.clone()` on a ref-counted pointer, (`Rc`, `Arc`, `rc::Weak`, or `sync::Weak`), and suggests calling Clone via unified function syntax instead (e.g., `Rc::clone(foo)`)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::cloned_instead_of_copied", description: r##"Checks for usage of `cloned()` on an `Iterator` or `Option` where `copied()` could be used instead."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::cmp_null", description: r##"This lint checks for equality comparisons with `ptr::null`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::cmp_owned", description: r##"Checks for conversions to owned values just for the sake of a comparison."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::cognitive_complexity", description: r##"Checks for methods with high cognitive complexity."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::collapsible_else_if", description: r##"Checks for collapsible `else { if ... }` expressions that can be collapsed to `else if ...`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::collapsible_if", description: r##"Checks for nested `if` statements which can be collapsed by `&&`-combining their conditions."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::collapsible_match", @@ -10721,73 +13397,121 @@ without adding any branches. Note that this lint is not intended to find _all_ cases where nested match patterns can be merged, but only cases where merging would most likely make the code more readable."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::collapsible_str_replace", description: r##"Checks for consecutive calls to `str::replace` (2 or more) that can be collapsed into a single call."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::collection_is_never_read", description: r##"Checks for collections that are never queried."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::comparison_chain", description: r##"Checks comparison chains written with `if` that can be rewritten with `match` and `cmp`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::comparison_to_empty", description: r##"Checks for comparing to an empty slice such as `` or `[]`, and suggests using `.is_empty()` where applicable."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::const_is_empty", description: r##"It identifies calls to `.is_empty()` on constant values."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::copy_iterator", description: r##"Checks for types that implement `Copy` as well as `Iterator`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::crate_in_macro_def", description: r##"Checks for usage of `crate` as opposed to `$crate` in a macro definition."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::create_dir", description: r##"Checks usage of `std::fs::create_dir` and suggest using `std::fs::create_dir_all` instead."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::crosspointer_transmute", description: r##"Checks for transmutes between a type `T` and `*T`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::dbg_macro", description: r##"Checks for usage of the [`dbg!`](https://doc.rust-lang.org/std/macro.dbg.html) macro."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::debug_assert_with_mut_call", description: r##"Checks for function/method calls with a mutable parameter in `debug_assert!`, `debug_assert_eq!` and `debug_assert_ne!` macros."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::decimal_literal_representation", description: r##"Warns if there is a better representation for a numeric literal."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::declare_interior_mutable_const", description: r##"Checks for declaration of `const` items which is interior mutable (e.g., contains a `Cell`, `Mutex`, `AtomicXxxx`, etc.)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::default_constructed_unit_structs", description: r##"Checks for construction on unit struct using `default`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::default_instead_of_iter_empty", description: r##"It checks for `std::iter::Empty::default()` and suggests replacing it with `std::iter::empty()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::default_numeric_fallback", @@ -10799,58 +13523,94 @@ types at the end of type inference, then integer type is bound to `i32`, and sim floating type is bound to `f64`. See [RFC0212](https://github.com/rust-lang/rfcs/blob/master/text/0212-restore-int-fallback.md) for more information about the fallback."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::default_trait_access", description: r##"Checks for literal calls to `Default::default()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::default_union_representation", description: r##"Displays a warning when a union is declared with the default representation (without a `#[repr(C)]` attribute)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::deprecated_cfg_attr", description: r##"Checks for `#[cfg_attr(rustfmt, rustfmt_skip)]` and suggests to replace it with `#[rustfmt::skip]`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::deprecated_clippy_cfg_attr", description: r##"Checks for `#[cfg_attr(feature = cargo-clippy, ...)]` and for `#[cfg(feature = cargo-clippy)]` and suggests to replace it with `#[cfg_attr(clippy, ...)]` or `#[cfg(clippy)]`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::deprecated_semver", description: r##"Checks for `#[deprecated]` annotations with a `since` field that is not a valid semantic version. Also allows TBD to signal future deprecation."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::deref_addrof", description: r##"Checks for usage of `*&` and `*&mut` in expressions."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::deref_by_slicing", description: r##"Checks for slicing expressions which are equivalent to dereferencing the value."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::derivable_impls", description: r##"Detects manual `std::default::Default` implementations that are identical to a derived implementation."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::derive_ord_xor_partial_ord", description: r##"Lints against manual `PartialOrd` and `Ord` implementations for types with a derived `Ord` or `PartialOrd` implementation."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::derive_partial_eq_without_eq", description: r##"Checks for types that derive `PartialEq` and could implement `Eq`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::derived_hash_with_manual_eq", description: r##"Lints against manual `PartialEq` implementations for types with a derived `Hash` implementation."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::disallowed_macros", @@ -10858,6 +13618,9 @@ implementation."##, Note: Even though this lint is warn-by-default, it will only trigger if macros are defined in the clippy.toml file."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::disallowed_methods", @@ -10865,11 +13628,17 @@ macros are defined in the clippy.toml file."##, Note: Even though this lint is warn-by-default, it will only trigger if methods are defined in the clippy.toml file."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::disallowed_names", description: r##"Checks for usage of disallowed names for variables, such as `foo`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::disallowed_script_idents", @@ -10885,6 +13654,9 @@ See also: [`non_ascii_idents`]. [aliases]: http://www.unicode.org/reports/tr24/tr24-31.html#Script_Value_Aliases [supported_scripts]: https://www.unicode.org/iso15924/iso15924-codes.html"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::disallowed_types", @@ -10892,11 +13664,17 @@ See also: [`non_ascii_idents`]. Note: Even though this lint is warn-by-default, it will only trigger if types are defined in the clippy.toml file."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::diverging_sub_expression", description: r##"Checks for diverging calls that are not match arms or statements."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::doc_lazy_continuation", @@ -10904,34 +13682,55 @@ statements."##, paragraph nested within a list or block quote does not need any line after the first one to be indented or marked. The specification calls this a lazy paragraph continuation."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::doc_link_with_quotes", description: r##"Detects the syntax `['foo']` in documentation comments (notice quotes instead of backticks) outside of code blocks"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::doc_markdown", description: r##"Checks for the presence of `_`, `::` or camel-case words outside ticks in documentation."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::double_comparisons", description: r##"Checks for double comparisons that could be simplified to a single expression."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::double_must_use", description: r##"Checks for a `#[must_use]` attribute without further information on functions and methods that return a type already marked as `#[must_use]`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::double_neg", description: r##"Detects expressions of the form `--x`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::double_parens", description: r##"Checks for unnecessary double parentheses."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::drain_collect", @@ -10939,43 +13738,76 @@ marked as `#[must_use]`."##, > Collection in this context refers to any type with a `drain` method: > `Vec`, `VecDeque`, `BinaryHeap`, `HashSet`,`HashMap`, `String`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::drop_non_drop", description: r##"Checks for calls to `std::mem::drop` with a value that does not implement `Drop`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::duplicate_mod", description: r##"Checks for files that are included as modules multiple times."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::duplicate_underscore_argument", description: r##"Checks for function arguments having the similar names differing by an underscore."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::duplicated_attributes", description: r##"Checks for attributes that appear two or more times."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::duration_subsec", description: r##"Checks for calculation of subsecond microseconds or milliseconds from other `Duration` methods."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::eager_transmute", description: r##"Checks for integer validity checks, followed by a transmute that is (incorrectly) evaluated eagerly (e.g. using `bool::then_some`)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::else_if_without_else", description: r##"Checks for usage of if expressions with an `else if` branch, but without a final `else` branch."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::empty_docs", + description: r##"Detects documentation that is empty."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::empty_docs", description: r##"Detects documentation that is empty."## }, Lint { label: "clippy::empty_drop", description: r##"Checks for empty `Drop` implementations."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::empty_enum", @@ -10984,271 +13816,458 @@ but without a final `else` branch."##, As of this writing, the `never_type` is still a nightly-only experimental API. Therefore, this lint is only triggered if `#![feature(never_type)]` is enabled."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::empty_enum_variants_with_brackets", description: r##"Finds enum variants without fields that are declared with empty brackets."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::empty_line_after_doc_comments", - description: r##"Checks for empty lines after documentation comments."##, + description: r##"Checks for empty lines after doc comments."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::empty_line_after_outer_attr", description: r##"Checks for empty lines after outer attributes"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::empty_loop", + description: r##"Checks for empty `loop` expressions."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::empty_loop", description: r##"Checks for empty `loop` expressions."## }, Lint { label: "clippy::empty_structs_with_brackets", description: r##"Finds structs without fields (a so-called empty struct) that are declared with brackets."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::enum_clike_unportable_variant", description: r##"Checks for C-like enumerations that are `repr(isize/usize)` and have values that don't fit into an `i32`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::enum_glob_use", + description: r##"Checks for `use Enum::*`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::enum_glob_use", description: r##"Checks for `use Enum::*`."## }, Lint { label: "clippy::enum_variant_names", description: r##"Detects enumeration variants that are prefixed or suffixed by the same characters."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::eq_op", description: r##"Checks for equal operands to comparison, logical and bitwise, difference and division binary operators (`==`, `>`, etc., `&&`, `||`, `&`, `|`, `^`, `-` and `/`)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::equatable_if_let", description: r##"Checks for pattern matchings that can be expressed using equality."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::erasing_op", description: r##"Checks for erasing operations, e.g., `x * 0`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::err_expect", description: r##"Checks for `.err().expect()` calls on the `Result` type."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::error_impl_error", description: r##"Checks for types named `Error` that implement `Error`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::excessive_nesting", description: r##"Checks for blocks which are nested beyond a certain threshold. Note: Even though this lint is warn-by-default, it will only trigger if a maximum nesting level is defined in the clippy.toml file."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::excessive_precision", description: r##"Checks for float literals with a precision greater than that supported by the underlying type."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::exhaustive_enums", description: r##"Warns on any exported `enum`s that are not tagged `#[non_exhaustive]`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::exhaustive_structs", description: r##"Warns on any exported `struct`s that are not tagged `#[non_exhaustive]`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::exit", description: r##"Detects calls to the `exit()` function which terminates the program."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::expect_fun_call", description: r##"Checks for calls to `.expect(&format!(...))`, `.expect(foo(..))`, etc., and suggests to use `unwrap_or_else` instead"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::expect_used", description: r##"Checks for `.expect()` or `.expect_err()` calls on `Result`s and `.expect()` call on `Option`s."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::expl_impl_clone_on_copy", description: r##"Checks for explicit `Clone` implementations for `Copy` types."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::explicit_auto_deref", description: r##"Checks for dereferencing expressions which would be covered by auto-deref."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::explicit_counter_loop", description: r##"Checks `for` loops over slices with an explicit counter and suggests the use of `.enumerate()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::explicit_deref_methods", description: r##"Checks for explicit `deref()` or `deref_mut()` method calls."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::explicit_into_iter_loop", description: r##"Checks for loops on `y.into_iter()` where `y` will do, and suggests the latter."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::explicit_iter_loop", description: r##"Checks for loops on `x.iter()` where `&x` will do, and suggests the latter."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::explicit_write", description: r##"Checks for usage of `write!()` / `writeln()!` which can be replaced with `(e)print!()` / `(e)println!()`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::extend_from_slice", - description: r##"Nothing. This lint has been deprecated."##, + description: r##"Nothing. This lint has been deprecated"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::extend_with_drain", description: r##"Checks for occurrences where one vector gets extended instead of append"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::extra_unused_lifetimes", description: r##"Checks for lifetimes in generics that are never used anywhere else."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::extra_unused_type_parameters", description: r##"Checks for type parameters in generics that are never used anywhere else."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::fallible_impl_from", description: r##"Checks for impls of `From<..>` that contain `panic!()` or `unwrap()`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::field_reassign_with_default", description: r##"Checks for immediate reassignment of fields initialized with Default::default()."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::field_scoped_visibility_modifiers", description: r##"Checks for usage of scoped visibility modifiers, like `pub(crate)`, on fields. These make a field visible within a scope between public and private."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::filetype_is_file", description: r##"Checks for `FileType::is_file()`."##, - }, - Lint { - label: "clippy::filter_map", - description: r##"Nothing. This lint has been deprecated."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::filter_map_bool_then", description: r##"Checks for usage of `bool::then` in `Iterator::filter_map`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::filter_map_identity", description: r##"Checks for usage of `filter_map(|x| x)`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::filter_map_next", description: r##"Checks for usage of `_.filter_map(_).next()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::filter_next", description: r##"Checks for usage of `_.filter(_).next()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::find_map", description: r##"Nothing. This lint has been deprecated."## }, Lint { label: "clippy::flat_map_identity", description: r##"Checks for usage of `flat_map(|x| x)`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::flat_map_option", description: r##"Checks for usage of `Iterator::flat_map()` where `filter_map()` could be used instead."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::float_arithmetic", + description: r##"Checks for float arithmetic."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::float_arithmetic", description: r##"Checks for float arithmetic."## }, Lint { label: "clippy::float_cmp", description: r##"Checks for (in-)equality comparisons on floating-point values (apart from zero), except in functions called `*eq*` (which probably implement equality for a type involving floats)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::float_cmp_const", description: r##"Checks for (in-)equality comparisons on constant floating-point values (apart from zero), except in functions called `*eq*` (which probably implement equality for a type involving floats)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::float_equality_without_abs", description: r##"Checks for statements of the form `(a - b) < f32::EPSILON` or `(a - b) < f64::EPSILON`. Notes the missing `.abs()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::fn_address_comparisons", description: r##"Checks for comparisons with an address of a function item."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::fn_params_excessive_bools", description: r##"Checks for excessive use of bools in function definitions."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::fn_to_numeric_cast", description: r##"Checks for casts of function pointers to something other than `usize`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::fn_to_numeric_cast_any", description: r##"Checks for casts of a function pointer to any integer type."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::fn_to_numeric_cast_with_truncation", description: r##"Checks for casts of a function pointer to a numeric type not wide enough to store an address."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::for_kv_map", description: r##"Checks for iterating a map (`HashMap` or `BTreeMap`) and ignoring either the keys or values."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::forget_non_drop", description: r##"Checks for calls to `std::mem::forget` with a value that does not implement `Drop`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::format_collect", description: r##"Checks for usage of `.map(|_| format!(..)).collect::<String>()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::format_in_format_args", description: r##"Detects `format!` within the arguments of another macro that does formatting such as `format!` itself, `write!` or `println!`. Suggests inlining the `format!` call."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::format_push_string", description: r##"Detects cases where the result of a `format!` call is appended to an existing `String`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::four_forward_slashes", description: r##"Checks for outer doc comments written with 4 forward slashes (`////`)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::from_iter_instead_of_collect", description: r##"Checks for `from_iter()` function calls on types that implement the `FromIterator` trait."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::from_over_into", description: r##"Searches for implementations of the `Into<..>` trait and suggests to implement `From<..>` instead."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::from_raw_with_void_ptr", description: r##"Checks if we're passing a `c_void` raw pointer to `{Box,Rc,Arc,Weak}::from_raw(_)`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::from_str_radix_10", description: r##"Checks for function invocations of the form `primitive::from_str_radix(s, 10)`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::future_not_send", @@ -11256,60 +14275,92 @@ trait."##, functions and methods to implement the `Send` marker trait. It is mostly used by library authors (public and internal) that target an audience where multithreaded executors are likely to be used for running these Futures."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::get_first", description: r##"Checks for usage of `x.get(0)` instead of `x.first()` or `x.front()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::get_last_with_len", description: r##"Checks for usage of `x.get(x.len() - 1)` instead of `x.last()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::get_unwrap", description: r##"Checks for usage of `.get().unwrap()` (or `.get_mut().unwrap`) on a standard library type which implements `Index`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::host_endian_bytes", description: r##"Checks for the usage of the `to_ne_bytes` method and/or the function `from_ne_bytes`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::identity_op", description: r##"Checks for identity operations, e.g., `x + 0`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::if_let_mutex", description: r##"Checks for `Mutex::lock` calls in `if let` expression with lock calls in any of the else blocks."##, - }, - Lint { - label: "clippy::if_let_redundant_pattern_matching", - description: r##"Nothing. This lint has been deprecated."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::if_not_else", description: r##"Checks for usage of `!` or `!=` in an if condition with an else branch."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::if_same_then_else", description: r##"Checks for `if/else` with the same body as the *then* part and the *else* part."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::if_then_some_else_none", description: r##"Checks for if-else that could be written using either `bool::then` or `bool::then_some`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::ifs_same_cond", description: r##"Checks for consecutive `if`s with the same condition."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::ignored_unit_patterns", description: r##"Checks for usage of `_` in patterns of type `()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::impl_hash_borrow_with_str_and_bytes", @@ -11317,32 +14368,53 @@ and the *else* part."##, type that implements all three of `Hash`, `Borrow<str>` and `Borrow<[u8]>` as it is impossible to satisfy the semantics of Borrow and `Hash` for both `Borrow<str>` and `Borrow<[u8]>`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::impl_trait_in_params", description: r##"Lints when `impl Trait` is being used in a function's parameters."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::implicit_clone", description: r##"Checks for the usage of `_.to_owned()`, `vec.to_vec()`, or similar when calling `_.clone()` would be clearer."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::implicit_hasher", description: r##"Checks for public `impl` or `fn` missing generalization over different hashers and implicitly defaulting to the default hashing algorithm (`SipHash`)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::implicit_return", description: r##"Checks for missing return statements at the end of a block."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::implicit_saturating_add", description: r##"Checks for implicit saturating addition."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::implicit_saturating_sub", description: r##"Checks for implicit saturating subtraction."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::implied_bounds_in_impls", @@ -11350,43 +14422,67 @@ algorithm (`SipHash`)."##, This can happen when a trait is specified that another trait already has as a supertrait (e.g. `fn() -> impl Deref + DerefMut<Target = i32>` has an unnecessary `Deref` bound, because `Deref` is a supertrait of `DerefMut`)"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::impossible_comparisons", description: r##"Checks for double comparisons that can never succeed"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::imprecise_flops", description: r##"Looks for floating-point expressions that can be expressed using built-in methods to improve accuracy at the cost of performance."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::incompatible_msrv", description: r##"This lint checks that no function newer than the defined MSRV (minimum supported rust version) is used in the crate."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::inconsistent_digit_grouping", description: r##"Warns if an integral or floating-point constant is grouped inconsistently with underscores."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::inconsistent_struct_constructor", description: r##"Checks for struct constructors where all fields are shorthand and the order of the field init shorthand in the constructor is inconsistent with the order in the struct definition."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::index_refutable_slice", description: r##"The lint checks for slice bindings in patterns that are only used to access individual slice values."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::indexing_slicing", description: r##"Checks for usage of indexing or slicing. Arrays are special cases, this lint does report on arrays if we can tell that slicing operations are in bounds and does not lint on constant `usize` indexing on arrays because that is handled by rustc's `const_err` lint."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::ineffective_bit_mask", @@ -11398,241 +14494,417 @@ following table: |----------|----------|------------|-------| |`>` / `<=`|`\\|` / `^`|`x \\| 2 > 3`|`x > 3`| |`<` / `>=`|`\\|` / `^`|`x ^ 1 < 4` |`x < 4`|"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::ineffective_open_options", description: r##"Checks if both `.write(true)` and `.append(true)` methods are called on a same `OpenOptions`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::inefficient_to_string", description: r##"Checks for usage of `.to_string()` on an `&&T` where `T` implements `ToString` directly (like `&&str` or `&&String`)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::infallible_destructuring_match", description: r##"Checks for matches being used to destructure a single-variant enum or tuple struct where a `let` will suffice."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::infinite_iter", description: r##"Checks for iteration that is guaranteed to be infinite."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::infinite_loop", description: r##"Checks for infinite loops in a function where the return type is not `!` and lint accordingly."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::inherent_to_string", description: r##"Checks for the definition of inherent methods with a signature of `to_string(&self) -> String`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::inherent_to_string_shadow_display", description: r##"Checks for the definition of inherent methods with a signature of `to_string(&self) -> String` and if the type implementing this method also implements the `Display` trait."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::init_numbered_fields", description: r##"Checks for tuple structs initialized with field syntax. It will however not lint if a base initializer is present. The lint will also ignore code in macros."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::inline_always", description: r##"Checks for items annotated with `#[inline(always)]`, unless the annotated function is empty or simply panics."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::inline_asm_x86_att_syntax", description: r##"Checks for usage of AT&T x86 assembly syntax."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::inline_asm_x86_intel_syntax", description: r##"Checks for usage of Intel x86 assembly syntax."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::inline_fn_without_body", description: r##"Checks for `#[inline]` on trait methods without bodies"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::inspect_for_each", description: r##"Checks for usage of `inspect().for_each()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::int_plus_one", description: r##"Checks for usage of `x >= y + 1` or `x - 1 >= y` (and `<=`) in a block"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::integer_division", + description: r##"Checks for division of integers"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::integer_division", description: r##"Checks for division of integers"## }, Lint { label: "clippy::integer_division_remainder_used", description: r##"Checks for the usage of division (`/`) and remainder (`%`) operations when performed on any integer types using the default `Div` and `Rem` trait implementations."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::into_iter_on_ref", description: r##"Checks for `into_iter` calls on references which should be replaced by `iter` or `iter_mut`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::into_iter_without_iter", description: r##"This is the opposite of the `iter_without_into_iter` lint. It looks for `IntoIterator for (&|&mut) Type` implementations without an inherent `iter` or `iter_mut` method on the type or on any of the types in its `Deref` chain."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::invalid_null_ptr_usage", description: r##"This lint checks for invalid usages of `ptr::null`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::invalid_regex", description: r##"Checks [regex](https://crates.io/crates/regex) creation (with `Regex::new`, `RegexBuilder::new`, or `RegexSet::new`) for correct regex syntax."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::invalid_upcast_comparisons", description: r##"Checks for comparisons where the relation is always either true or false, but where one side has been upcast so that the comparison is necessary. Only integer types are checked."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::inverted_saturating_sub", + description: r##"Checks for comparisons between integers, followed by subtracting the greater value from the +lower one."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::invisible_characters", description: r##"Checks for invisible Unicode characters in the code."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::is_digit_ascii_radix", description: r##"Finds usages of [`char::is_digit`](https://doc.rust-lang.org/stable/std/primitive.char.html#method.is_digit) that can be replaced with [`is_ascii_digit`](https://doc.rust-lang.org/stable/std/primitive.char.html#method.is_ascii_digit) or [`is_ascii_hexdigit`](https://doc.rust-lang.org/stable/std/primitive.char.html#method.is_ascii_hexdigit)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::items_after_statements", description: r##"Checks for items declared after some statement in a block."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::items_after_test_module", description: r##"Triggers if an item is declared after the testing module marked with `#[cfg(test)]`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::iter_cloned_collect", description: r##"Checks for the use of `.cloned().collect()` on slice to create a `Vec`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::iter_count", description: r##"Checks for the use of `.iter().count()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::iter_filter_is_ok", description: r##"Checks for usage of `.filter(Result::is_ok)` that may be replaced with a `.flatten()` call. This lint will require additional changes to the follow-up calls as it affects the type."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::iter_filter_is_some", description: r##"Checks for usage of `.filter(Option::is_some)` that may be replaced with a `.flatten()` call. This lint will require additional changes to the follow-up calls as it affects the type."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::iter_kv_map", description: r##"Checks for iterating a map (`HashMap` or `BTreeMap`) and ignoring either the keys or values."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::iter_next_loop", + description: r##"Checks for loops on `x.next()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::iter_next_loop", description: r##"Checks for loops on `x.next()`."## }, Lint { label: "clippy::iter_next_slice", description: r##"Checks for usage of `iter().next()` on a Slice or an Array"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::iter_not_returning_iterator", description: r##"Detects methods named `iter` or `iter_mut` that do not have a return type that implements `Iterator`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::iter_nth", description: r##"Checks for usage of `.iter().nth()`/`.iter_mut().nth()` on standard library types that have equivalent `.get()`/`.get_mut()` methods."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::iter_nth_zero", description: r##"Checks for the use of `iter.nth(0)`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::iter_on_empty_collections", description: r##"Checks for calls to `iter`, `iter_mut` or `into_iter` on empty collections"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::iter_on_single_items", description: r##"Checks for calls to `iter`, `iter_mut` or `into_iter` on collections containing a single item"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::iter_out_of_bounds", description: r##"Looks for iterator combinator calls such as `.take(x)` or `.skip(x)` where `x` is greater than the amount of items that an iterator will produce."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::iter_over_hash_type", description: r##"This is a restriction lint which prevents the use of hash types (i.e., `HashSet` and `HashMap`) in for loops."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::iter_overeager_cloned", description: r##"Checks for usage of `_.cloned().<func>()` where call to `.cloned()` can be postponed."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::iter_skip_next", description: r##"Checks for usage of `.skip(x).next()` on iterators."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::iter_skip_zero", description: r##"Checks for usage of `.skip(0)` on iterators."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::iter_with_drain", description: r##"Checks for usage of `.drain(..)` on `Vec` and `VecDeque` for iteration."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::iter_without_into_iter", description: r##"Looks for `iter` and `iter_mut` methods without an associated `IntoIterator for (&|&mut) Type` implementation."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::iterator_step_by_zero", description: r##"Checks for calling `.step_by(0)` on iterators which panics."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::join_absolute_paths", description: r##"Checks for calls to `Path::join` that start with a path separator (`\\\\` or `/`)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::just_underscores_and_digits", description: r##"Checks if you have variables whose name consists of just underscores and digits."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::large_const_arrays", description: r##"Checks for large `const` arrays that should be defined as `static` instead."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::large_digit_groups", description: r##"Warns if the digits of an integral or floating-point constant are grouped into groups that are too large."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::large_enum_variant", description: r##"Checks for large size differences between variants on `enum`s."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::large_futures", description: r##"It checks for the size of a `Future` created by `async fn` or `async {}`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::large_include_file", description: r##"Checks for the inclusion of large files via `include_bytes!()` or `include_str!()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::large_stack_arrays", description: r##"Checks for local arrays that may be too large."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::large_stack_frames", @@ -11643,6 +14915,9 @@ or constructing *many* smaller-but-still-large structs, or copying around a lot This lint is a more general version of [`large_stack_arrays`](https://rust-lang.github.io/rust-clippy/master/#large_stack_arrays) that is intended to look at functions as a whole instead of only individual array expressions inside of a function."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::large_types_passed_by_value", @@ -11651,60 +14926,102 @@ the argument type is `Copy` and large enough to be worth considering passing by reference. Does not trigger if the function is being exported, because that might induce API breakage, if the parameter is declared as mutable, or if the argument is a `self`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::legacy_numeric_constants", description: r##"Checks for usage of `<integer>::max_value()`, `std::<integer>::MAX`, `std::<float>::EPSILON`, etc."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::len_without_is_empty", description: r##"Checks for items that implement `.len()` but not `.is_empty()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::len_zero", description: r##"Checks for getting the length of something via `.len()` just to compare to zero, and suggests using `.is_empty()` where applicable."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::let_and_return", description: r##"Checks for `let`-bindings, which are subsequently returned."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::let_underscore_future", description: r##"Checks for `let _ = <expr>` where the resulting type of expr implements `Future`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::let_underscore_lock", description: r##"Checks for `let _ = sync_lock`. This supports `mutex` and `rwlock` in `parking_lot`. For `std` locks see the `rustc` lint [`let_underscore_lock`](https://doc.rust-lang.org/nightly/rustc/lints/listing/deny-by-default.html#let-underscore-lock)"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::let_underscore_must_use", description: r##"Checks for `let _ = <expr>` where expr is `#[must_use]`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::let_underscore_untyped", description: r##"Checks for `let _ = <expr>` without a type annotation, and suggests to either provide one, or remove the `let` keyword altogether."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::let_unit_value", + description: r##"Checks for binding a unit value."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::let_unit_value", description: r##"Checks for binding a unit value."## }, Lint { label: "clippy::let_with_type_underscore", description: r##"Detects when a variable is declared with an explicit type of `_`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::lines_filter_map_ok", description: r##"Checks for usage of `lines.filter_map(Result::ok)` or `lines.flat_map(Result::ok)` when `lines` has type `std::io::Lines`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::linkedlist", description: r##"Checks for usage of any `LinkedList`, suggesting to use a `Vec` or a `VecDeque` (formerly called `RingBuf`)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::lint_groups_priority", @@ -11713,286 +15030,488 @@ when `lines` has type `std::io::Lines`."##, This lint will be removed once [cargo#12918](https://github.com/rust-lang/cargo/issues/12918) is resolved."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::little_endian_bytes", description: r##"Checks for the usage of the `to_le_bytes` method and/or the function `from_le_bytes`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::lossy_float_literal", description: r##"Checks for whole number float literals that cannot be represented as the underlying type without loss."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::macro_metavars_in_unsafe", description: r##"Looks for macros that expand metavariables in an unsafe block."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::macro_use_imports", description: r##"Checks for `#[macro_use] use...`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::main_recursion", description: r##"Checks for recursion using the entrypoint."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_assert", description: r##"Detects `if`-then-`panic!` that can be replaced with `assert!`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_async_fn", description: r##"It checks for manual implementations of `async` functions."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_bits", description: r##"Checks for usage of `std::mem::size_of::<T>() * 8` when `T::BITS` is available."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_c_str_literals", description: r##"Checks for the manual creation of C strings (a string with a `NUL` byte at the end), either through one of the `CStr` constructor functions, or more plainly by calling `.as_ptr()` on a (byte) string literal with a hardcoded `\\0` byte at the end."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_clamp", description: r##"Identifies good opportunities for a clamp function from std or core, and suggests using it."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::manual_div_ceil", + description: r##"Checks for an expression like `(x + (y - 1)) / y` which is a common manual reimplementation +of `x.div_ceil(y)`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_filter", description: r##"Checks for usage of `match` which could be implemented using `filter`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_filter_map", description: r##"Checks for usage of `_.filter(_).map(_)` that can be written more simply as `filter_map(_)`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_find", description: r##"Checks for manual implementations of Iterator::find"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_find_map", description: r##"Checks for usage of `_.find(_).map(_)` that can be written more simply as `find_map(_)`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_flatten", description: r##"Checks for unnecessary `if let` usage in a for loop where only the `Some` or `Ok` variant of the iterator element is used."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_hash_one", description: r##"Checks for cases where [`BuildHasher::hash_one`] can be used. [`BuildHasher::hash_one`]: https://doc.rust-lang.org/std/hash/trait.BuildHasher.html#method.hash_one"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_inspect", description: r##"Checks for uses of `map` which return the original item."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_instant_elapsed", description: r##"Lints subtraction between `Instant::now()` and another `Instant`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_is_ascii_check", description: r##"Suggests to use dedicated built-in methods, `is_ascii_(lowercase|uppercase|digit|hexdigit)` for checking on corresponding ascii range"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_is_finite", description: r##"Checks for manual `is_finite` reimplementations (i.e., `x != <float>::INFINITY && x != <float>::NEG_INFINITY`)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_is_infinite", description: r##"Checks for manual `is_infinite` reimplementations (i.e., `x == <float>::INFINITY || x == <float>::NEG_INFINITY`)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::manual_is_power_of_two", + description: r##"Checks for expressions like `x.count_ones() == 1` or `x & (x - 1) == 0`, with x and unsigned integer, which are manual +reimplementations of `x.is_power_of_two()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_is_variant_and", description: r##"Checks for usage of `option.map(f).unwrap_or_default()` and `result.map(f).unwrap_or_default()` where f is a function or closure that returns the `bool` type."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_let_else", description: r##"Warn of cases where `let...else` could be used"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_main_separator_str", description: r##"Checks for references on `std::path::MAIN_SEPARATOR.to_string()` used to build a `&str`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_map", description: r##"Checks for usage of `match` which could be implemented using `map`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_memcpy", description: r##"Checks for for-loops that manually copy items between slices that could be optimized by having a memcpy."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_next_back", description: r##"Checks for `.rev().next()` on a `DoubleEndedIterator`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_non_exhaustive", description: r##"Checks for manual implementations of the non-exhaustive pattern."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_ok_or", description: r##"Finds patterns that reimplement `Option::ok_or`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_pattern_char_comparison", description: r##"Checks for manual `char` comparison in string patterns"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_range_contains", description: r##"Checks for expressions like `x >= 3 && x < 8` that could be more readably expressed as `(3..8).contains(x)`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_range_patterns", description: r##"Looks for combined OR patterns that are all contained in a specific range, e.g. `6 | 4 | 5 | 9 | 7 | 8` can be rewritten as `4..=9`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_rem_euclid", description: r##"Checks for an expression like `((x % 4) + 4) % 4` which is a common manual reimplementation of `x.rem_euclid(4)`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_retain", description: r##"Checks for code to be replaced by `.retain()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_rotate", description: r##"It detects manual bit rotations that could be rewritten using standard functions `rotate_left` or `rotate_right`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_saturating_arithmetic", description: r##"Checks for `.checked_add/sub(x).unwrap_or(MAX/MIN)`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_slice_size_calculation", description: r##"When `a` is `&[T]`, detect `a.len() * size_of::<T>()` and suggest `size_of_val(a)` instead."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_split_once", description: r##"Checks for usage of `str::splitn(2, _)`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_str_repeat", description: r##"Checks for manual implementations of `str::repeat`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_string_new", description: r##"Checks for usage of `` to create a `String`, such as `.to_string()`, `.to_owned()`, `String::from()` and others."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_strip", description: r##"Suggests using `strip_{prefix,suffix}` over `str::{starts,ends}_with` and slicing using the pattern's length."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_swap", description: r##"Checks for manual swapping. Note that the lint will not be emitted in const blocks, as the suggestion would not be applicable."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_try_fold", description: r##"Checks for usage of `Iterator::fold` with a type that implements `Try`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_unwrap_or", description: r##"Finds patterns that reimplement `Option::unwrap_or` or `Result::unwrap_or`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_unwrap_or_default", description: r##"Checks if a `match` or `if let` expression can be simplified using `.unwrap_or_default()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_while_let_some", description: r##"Looks for loops that check for emptiness of a `Vec` in the condition and pop an element in the body as a separate operation."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::many_single_char_names", description: r##"Checks for too many variables whose name consists of a single character."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::map_clone", description: r##"Checks for usage of `map(|x| x.clone())` or dereferencing closures for `Copy` types, on `Iterator` or `Option`, and suggests `cloned()` or `copied()` instead"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::map_collect_result_unit", description: r##"Checks for usage of `_.map(_).collect::<Result<(), _>()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::map_entry", description: r##"Checks for usage of `contains_key` + `insert` on `HashMap` or `BTreeMap`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::map_err_ignore", description: r##"Checks for instances of `map_err(|_| Some::Enum)`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::map_flatten", description: r##"Checks for usage of `_.map(_).flatten(_)` on `Iterator` and `Option`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::map_identity", description: r##"Checks for instances of `map(f)` where `f` is the identity function."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::map_unwrap_or", description: r##"Checks for usage of `option.map(_).unwrap_or(_)` or `option.map(_).unwrap_or_else(_)` or `result.map(_).unwrap_or_else(_)`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::match_as_ref", description: r##"Checks for match which is used to add a reference to an `Option` value."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::match_bool", description: r##"Checks for matches where match expression is a `bool`. It suggests to replace the expression with an `if...else` block."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::match_like_matches_macro", description: r##"Checks for `match` or `if let` expressions producing a `bool` that could be written using `matches!`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::match_on_vec_items", description: r##"Checks for `match vec[idx]` or `match vec[n..m]`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::match_overlapping_arm", description: r##"Checks for overlapping match arms."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::match_ref_pats", description: r##"Checks for matches where all arms match a reference, suggesting to remove the reference and deref the matched expression instead. It also checks for `if let &foo = bar` blocks."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::match_result_ok", description: r##"Checks for unnecessary `ok()` in `while let`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::match_same_arms", @@ -12000,51 +15519,77 @@ instead. It also checks for `if let &foo = bar` blocks."##, Note: Does not lint on wildcards if the `non_exhaustive_omitted_patterns_lint` feature is enabled and disallowed."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::match_single_binding", description: r##"Checks for useless match that binds to only one value."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::match_str_case_mismatch", description: r##"Checks for `match` expressions modifying the case of a string with non-compliant arms"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::match_wild_err_arm", description: r##"Checks for arm which matches all errors with `Err(_)` and take drastic actions like `panic!`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::match_wildcard_for_single_variants", description: r##"Checks for wildcard enum matches for a single variant."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::maybe_infinite_iter", description: r##"Checks for iteration that may be infinite."##, - }, - Lint { - label: "clippy::maybe_misused_cfg", - description: r##"Nothing. This lint has been deprecated."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::mem_forget", description: r##"Checks for usage of `std::mem::forget(t)` where `t` is `Drop` or has a field that implements `Drop`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::mem_replace_option_with_none", description: r##"Checks for `mem::replace()` on an `Option` with `None`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::mem_replace_with_default", description: r##"Checks for `std::mem::replace` on a value of type `T` with `T::default()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::mem_replace_with_uninit", description: r##"Checks for `mem::replace(&mut _, mem::uninitialized())` and `mem::replace(&mut _, mem::zeroed())`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::min_ident_chars", @@ -12052,19 +15597,24 @@ and `mem::replace(&mut _, mem::zeroed())`."##, Note: This lint can be very noisy when enabled; it may be desirable to only enable it temporarily."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::min_max", description: r##"Checks for expressions where `std::cmp::min` and `max` are used to clamp values, but switched so that the result is constant."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::misaligned_transmute", - description: r##"Nothing. This lint has been deprecated."##, - }, - Lint { - label: "clippy::mismatched_target_os", - description: r##"Nothing. This lint has been deprecated."##, + description: r##"Nothing. This lint has been deprecated"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::mismatching_type_param_order", @@ -12072,36 +15622,60 @@ used to clamp values, but switched so that the result is constant."##, a type definition and impl block. Specifically, a parameter in an impl block which has the same name as a parameter in the type def, but is in a different place."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::misnamed_getters", description: r##"Checks for getter methods that return a field that doesn't correspond to the name of the method, when there is a field's whose name matches that of the method."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::misrefactored_assign_op", description: r##"Checks for `a op= a op b` or `a op= b op a` patterns."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::missing_assert_message", description: r##"Checks assertions without a custom panic message."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::missing_asserts_for_indexing", description: r##"Checks for repeated slice indexing without asserting beforehand that the length is greater than the largest index used to index into the slice."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::missing_const_for_fn", description: r##"Suggests the use of `const` in functions and methods where possible."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::missing_const_for_thread_local", description: r##"Suggests to use `const` in `thread_local!` macro if possible."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::missing_docs_in_private_items", description: r##"Warns if there is missing documentation for any private documentable item."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::missing_enforced_import_renames", @@ -12110,108 +15684,192 @@ in the `enforced-import-renames` config option. Note: Even though this lint is warn-by-default, it will only trigger if import renames are defined in the `clippy.toml` file."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::missing_errors_doc", description: r##"Checks the doc comments of publicly visible functions that return a `Result` type and warns if there is no `# Errors` section."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::missing_fields_in_debug", description: r##"Checks for manual [`core::fmt::Debug`](https://doc.rust-lang.org/core/fmt/trait.Debug.html) implementations that do not use all fields."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::missing_inline_in_public_items", description: r##"It lints if an exported function, method, trait method with default impl, or trait method impl is not `#[inline]`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::missing_panics_doc", description: r##"Checks the doc comments of publicly visible functions that may panic and warns if there is no `# Panics` section."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::missing_safety_doc", description: r##"Checks for the doc comments of publicly visible unsafe functions and warns if there is no `# Safety` section."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::missing_spin_loop", + description: r##"Checks for empty spin loops"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::missing_spin_loop", description: r##"Checks for empty spin loops"## }, Lint { label: "clippy::missing_trait_methods", description: r##"Checks if a provided method is used implicitly by a trait implementation."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::missing_transmute_annotations", description: r##"Checks if transmute calls have all generics specified."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::mistyped_literal_suffixes", description: r##"Warns for mistyped suffix in literals"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::mixed_attributes_style", description: r##"Checks for items that have the same kind of attributes with mixed styles (inner/outer)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::mixed_case_hex_literals", description: r##"Warns on hexadecimal literals with mixed-case letter digits."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::mixed_read_write_in_expression", description: r##"Checks for a read and a write to the same variable where whether the read occurs before or after the write depends on the evaluation order of sub-expressions."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::mod_module_files", description: r##"Checks that module layout uses only self named module files; bans `mod.rs` files."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::module_inception", description: r##"Checks for modules that have the same name as their parent module"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::module_name_repetitions", description: r##"Detects type names that are prefixed or suffixed by the containing module's name."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::modulo_arithmetic", + description: r##"Checks for modulo arithmetic."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::modulo_arithmetic", description: r##"Checks for modulo arithmetic."## }, Lint { label: "clippy::modulo_one", description: r##"Checks for getting the remainder of integer division by one or minus one."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::multi_assignments", + description: r##"Checks for nested assignments."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::multi_assignments", description: r##"Checks for nested assignments."## }, Lint { label: "clippy::multiple_bound_locations", description: r##"Check if a generic is defined both in the bound predicate and in the `where` clause."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::multiple_crate_versions", description: r##"Checks to see if multiple versions of a crate are being used."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::multiple_inherent_impl", description: r##"Checks for multiple inherent implementations of a struct"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::multiple_unsafe_ops_per_block", description: r##"Checks for `unsafe` blocks that contain more than one unsafe operation."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::must_use_candidate", description: r##"Checks for public functions that have no `#[must_use]` attribute, but return something not already marked must-use, have no mutable arg and mutate no statics."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::must_use_unit", description: r##"Checks for a `#[must_use]` attribute on unit-returning functions and methods."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::mut_from_ref", @@ -12221,77 +15879,131 @@ are multiple safe functions which will do this transformation To be on the conservative side, if there's at least one mutable reference with the output lifetime, this lint will not trigger."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::mut_mut", description: r##"Checks for instances of `mut mut` references."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::mut_mutex_lock", description: r##"Checks for `&mut Mutex::lock` calls"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::mut_range_bound", description: r##"Checks for loops with a range bound that is a mutable variable."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::mutable_key_type", description: r##"Checks for sets/maps with mutable key types."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::mutex_atomic", description: r##"Checks for usage of `Mutex<X>` where an atomic will do."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::mutex_integer", description: r##"Checks for usage of `Mutex<X>` where `X` is an integral type."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::naive_bytecount", + description: r##"Checks for naive byte counts"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::naive_bytecount", description: r##"Checks for naive byte counts"## }, Lint { label: "clippy::needless_arbitrary_self_type", description: r##"The lint checks for `self` in fn parameters that specify the `Self`-type explicitly"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_bitwise_bool", description: r##"Checks for usage of bitwise and/or operators between booleans, where performance may be improved by using a lazy and."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_bool", description: r##"Checks for expressions of the form `if c { true } else { false }` (or vice versa) and suggests using the condition directly."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_bool_assign", description: r##"Checks for expressions of the form `if c { x = true } else { x = false }` (or vice versa) and suggest assigning the variable directly from the condition."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_borrow", description: r##"Checks for address of operations (`&`) that are going to be dereferenced immediately by the compiler."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_borrowed_reference", description: r##"Checks for bindings that needlessly destructure a reference and borrow the inner value with `&ref`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_borrows_for_generic_args", description: r##"Checks for borrow operations (`&`) that are used as a generic argument to a function when the borrowed value could be used."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_character_iteration", description: r##"Checks if an iterator is used to check if a string is ascii."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_collect", description: r##"Checks for functions collecting an iterator when collect is not needed."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_continue", @@ -12299,53 +16011,92 @@ is not needed."##, that contain a `continue` statement in either their main blocks or their `else`-blocks, when omitting the `else`-block possibly with some rearrangement of code can make the code easier to understand."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_doctest_main", description: r##"Checks for `fn main() { .. }` in doctests"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::needless_else", + description: r##"Checks for empty `else` branches."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::needless_else", description: r##"Checks for empty `else` branches."## }, Lint { label: "clippy::needless_for_each", description: r##"Checks for usage of `for_each` that would be more simply written as a `for` loop."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_if", description: r##"Checks for empty `if` branches with no else branch."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_late_init", description: r##"Checks for late initializations that can be replaced by a `let` statement with an initializer."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_lifetimes", description: r##"Checks for lifetime annotations which can be removed by relying on lifetime elision."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_match", description: r##"Checks for unnecessary `match` or match-like `if let` returns for `Option` and `Result` when function signatures are the same."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_maybe_sized", description: r##"Lints `?Sized` bounds applied to type parameters that cannot be unsized"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_option_as_deref", description: r##"Checks for no-op uses of `Option::{as_deref, as_deref_mut}`, for example, `Option<&T>::as_deref()` returns the same type."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_option_take", description: r##"Checks for calling `take` function after `as_ref`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_parens_on_range_literals", description: r##"The lint checks for parenthesis on literals in range statements that are superfluous."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_pass_by_ref_mut", @@ -12353,45 +16104,75 @@ superfluous."##, Be careful if the function is publicly reexported as it would break compatibility with users of this function, when the users pass this function as an argument."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_pass_by_value", description: r##"Checks for functions taking arguments by value, but not consuming them in its body."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_pub_self", description: r##"Checks for usage of `pub(self)` and `pub(in self)`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_question_mark", description: r##"Suggests alternatives for useless applications of `?` in terminating expressions"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_range_loop", description: r##"Checks for looping over the range of `0..len` of some collection just to get the values by index."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_raw_string_hashes", description: r##"Checks for raw string literals with an unnecessary amount of hashes around them."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_raw_strings", description: r##"Checks for raw string literals where a string literal can be used instead."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_return", description: r##"Checks for return statements at the end of a block."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_return_with_question_mark", description: r##"Checks for return statements on `Err` paired with the `?` operator."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_splitn", description: r##"Checks for usage of `str::splitn` (or `str::rsplitn`) where using `str::split` would be the same."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_update", @@ -12400,70 +16181,118 @@ when all fields are changed anyway. This lint is not applied to structs marked with [non_exhaustive](https://doc.rust-lang.org/reference/attributes/type_system.html)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::neg_cmp_op_on_partial_ord", description: r##"Checks for the usage of negated comparison operators on types which only implement `PartialOrd` (e.g., `f64`)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::neg_multiply", description: r##"Checks for multiplication by -1 as a form of negation."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::negative_feature_names", description: r##"Checks for negative feature names with prefix `no-` or `not-`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::never_loop", description: r##"Checks for loops that will always `break`, `return` or `continue` an outer loop."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::new_ret_no_self", description: r##"Checks for `new` not returning a type that contains `Self`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::new_without_default", description: r##"Checks for public types with a `pub fn new() -> Self` method and no implementation of [`Default`](https://doc.rust-lang.org/std/default/trait.Default.html)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::no_effect", description: r##"Checks for statements which have no effect."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::no_effect_replace", description: r##"Checks for `replace` statements which have no effect."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::no_effect_underscore_binding", description: r##"Checks for binding to underscore prefixed variable without side-effects."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::no_mangle_with_rust_abi", description: r##"Checks for Rust ABI functions with the `#[no_mangle]` attribute."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::non_ascii_literal", description: r##"Checks for non-ASCII characters in string and char literals."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::non_canonical_clone_impl", description: r##"Checks for non-canonical implementations of `Clone` when `Copy` is already implemented."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::non_canonical_partial_ord_impl", description: r##"Checks for non-canonical implementations of `PartialOrd` when `Ord` is already implemented."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::non_minimal_cfg", description: r##"Checks for `any` and `all` combinators in `cfg` with only one condition."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::non_octal_unix_permissions", description: r##"Checks for non-octal values used to set Unix file permissions."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::non_send_fields_in_send_ty", @@ -12472,63 +16301,116 @@ contains fields that are not safe to be sent across threads. It tries to detect fields that can cause a soundness issue when sent to another thread (e.g., `Rc`) while allowing `!Send` fields that are expected to exist in a `Send` type, such as raw pointers."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::non_zero_suggestions", + description: r##"Checks for conversions from `NonZero` types to regular integer types, +and suggests using `NonZero` types for the target as well."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::nonminimal_bool", description: r##"Checks for boolean expressions that can be written more concisely."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::nonsensical_open_options", description: r##"Checks for duplicate open options as well as combinations that make no sense."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::nonstandard_macro_braces", description: r##"Checks that common macros are used with consistent bracing."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::not_unsafe_ptr_arg_deref", description: r##"Checks for public functions that dereference raw pointer arguments but are not marked `unsafe`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::obfuscated_if_else", description: r##"Checks for usage of `.then_some(..).unwrap_or(..)`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::octal_escapes", description: r##"Checks for `\\0` escapes in string and byte literals that look like octal character escapes in C."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::ok_expect", + description: r##"Checks for usage of `ok().expect(..)`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::ok_expect", description: r##"Checks for usage of `ok().expect(..)`."## }, Lint { label: "clippy::only_used_in_recursion", description: r##"Checks for arguments that are only used in recursion with no side-effects."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::op_ref", description: r##"Checks for arguments to `==` which have their address taken to satisfy a bound and suggests to dereference the other argument instead"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::option_as_ref_cloned", description: r##"Checks for usage of `.as_ref().cloned()` and `.as_mut().cloned()` on `Option`s"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::option_as_ref_deref", description: r##"Checks for usage of `_.as_ref().map(Deref::deref)` or its aliases (such as String::as_str)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::option_env_unwrap", description: r##"Checks for usage of `option_env!(...).unwrap()` and suggests usage of the `env!` macro."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::option_filter_map", description: r##"Checks for iterators of `Option`s using `.filter(Option::is_some).map(Option::unwrap)` that may be replaced with a `.flatten()` call."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::option_if_let_else", @@ -12537,24 +16419,39 @@ be replaced with a `.flatten()` call."##, idiomatically done with `Option::map_or` (if the else bit is a pure expression) or `Option::map_or_else` (if the else bit is an impure expression)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::option_map_or_err_ok", description: r##"Checks for usage of `_.map_or(Err(_), Ok)`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::option_map_or_none", description: r##"Checks for usage of `_.map_or(None, _)`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::option_map_unit_fn", description: r##"Checks for usage of `option.map(f)` where f is a function or closure that returns the unit type `()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::option_option", description: r##"Checks for usage of `Option<Option<_>>` in function signatures and type definitions"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::or_fun_call", @@ -12562,52 +16459,91 @@ definitions"##, `.or_insert(foo(..))` etc., and suggests to use `.or_else(|| foo(..))`, `.unwrap_or_else(|| foo(..))`, `.unwrap_or_default()` or `.or_default()` etc. instead."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::or_then_unwrap", description: r##"Checks for `.or(…).unwrap()` calls to Options and Results."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::out_of_bounds_indexing", description: r##"Checks for out of bounds array indexing with a constant index."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::overly_complex_bool_expr", description: r##"Checks for boolean expressions that contain terminals that can be eliminated."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::panic", + description: r##"Checks for usage of `panic!`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::panic", description: r##"Checks for usage of `panic!`."## }, Lint { label: "clippy::panic_in_result_fn", description: r##"Checks for usage of `panic!` or assertions in a function whose return type is `Result`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::panicking_overflow_checks", description: r##"Detects C-style underflow/overflow checks."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::panicking_unwrap", description: r##"Checks for calls of `unwrap[_err]()` that will always fail."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::partial_pub_fields", description: r##"Checks whether some but not all fields of a `struct` are public. Either make all fields of a type public, or make none of them public"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::partialeq_ne_impl", description: r##"Checks for manual re-implementations of `PartialEq::ne`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::partialeq_to_none", description: r##"Checks for binary comparisons to a literal `Option::None`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::path_buf_push_overwrite", description: r##"* Checks for [push](https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.push) calls on `PathBuf` that can cause overwrites."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::path_ends_with_ext", @@ -12617,10 +16553,16 @@ By default, Clippy has a short list of known filenames that start with a dot but aren't necessarily file extensions (e.g. the `.git` folder), which are allowed by default. The `allowed-dotfiles` configuration can be used to allow additional file extensions that Clippy should not lint."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::pathbuf_init_then_push", description: r##"Checks for calls to `push` immediately after creating a new `PathBuf`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::pattern_type_mismatch", @@ -12642,90 +16584,157 @@ and reference semantics in your code. The available tooling would expose these t in a general way even outside of the various pattern matching mechanics. Of course this lint can still be used to highlight areas of interest and ensure a good understanding of ownership semantics."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::permissions_set_readonly_false", description: r##"Checks for calls to `std::fs::Permissions.set_readonly` with argument `false`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::pointers_in_nomem_asm_block", + description: r##"Checks if any pointer is being passed to an asm! block with `nomem` option."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::possible_missing_comma", description: r##"Checks for possible missing comma in an array. It lints if an array element is a binary operator expression and it lies on two lines."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::precedence", description: r##"Checks for operations where precedence may be unclear and suggests to add parentheses. Currently it catches the following: * mixed usage of arithmetic and bit shifting/combining operators without -parentheses -* a negative numeric literal (which is really a unary `-` followed by a -numeric literal) - followed by a method call"##, +parentheses"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::print_in_format_impl", description: r##"Checks for usage of `println`, `print`, `eprintln` or `eprint` in an implementation of a formatting trait."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::print_literal", description: r##"This lint warns about the use of literals as `print!`/`println!` args."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::print_stderr", description: r##"Checks for printing on *stderr*. The purpose of this lint is to catch debugging remnants."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::print_stdout", description: r##"Checks for printing on *stdout*. The purpose of this lint is to catch debugging remnants."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::print_with_newline", description: r##"This lint warns when you use `print!()` with a format string that ends in a newline."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::println_empty_string", description: r##"This lint warns when you use `println!()` to print a newline."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::ptr_arg", description: r##"This lint checks for function arguments of type `&String`, `&Vec`, `&PathBuf`, and `Cow<_>`. It will also suggest you replace `.clone()` calls with the appropriate `.to_owned()`/`to_string()` calls."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::ptr_as_ptr", description: r##"Checks for `as` casts between raw pointers that don't change their constness, namely `*const T` to `*const U` and `*mut T` to `*mut U`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::ptr_cast_constness", description: r##"Checks for `as` casts between raw pointers that change their constness, namely `*const T` to `*mut T` and `*mut T` to `*const T`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::ptr_eq", + description: r##"Use `std::ptr::eq` when applicable"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::ptr_eq", description: r##"Use `std::ptr::eq` when applicable"## }, Lint { label: "clippy::ptr_offset_with_cast", description: r##"Checks for usage of the `offset` pointer method with a `usize` casted to an `isize`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::pub_enum_variant_names", - description: r##"Nothing. This lint has been deprecated."##, + description: r##"Nothing. This lint has been deprecated"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::pub_underscore_fields", description: r##"Checks whether any field of the struct is prefixed with an `_` (underscore) and also marked `pub` (public)"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::pub_use", + description: r##"Restricts the usage of `pub use ...`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::pub_use", description: r##"Restricts the usage of `pub use ...`"## }, Lint { label: "clippy::pub_with_shorthand", description: r##"Checks for usage of `pub(<loc>)` with `in`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::pub_without_shorthand", @@ -12733,180 +16742,310 @@ constness, namely `*const T` to `*const U` and `*mut T` to `*mut U`."##, Note: As you cannot write a module's path in `pub(<loc>)`, this will only trigger on `pub(super)` and the like."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::question_mark", description: r##"Checks for expressions that could be replaced by the question mark operator."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::question_mark_used", description: r##"Checks for expressions that use the question mark operator and rejects them."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::range_minus_one", description: r##"Checks for inclusive ranges where 1 is subtracted from the upper bound, e.g., `x..=(y-1)`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::range_plus_one", description: r##"Checks for exclusive ranges where 1 is added to the upper bound, e.g., `x..(y+1)`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::range_step_by_zero", - description: r##"Nothing. This lint has been deprecated."##, + description: r##"Nothing. This lint has been deprecated"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::range_zip_with_len", description: r##"Checks for zipping a collection with the range of `0.._.len()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::rc_buffer", description: r##"Checks for `Rc<T>` and `Arc<T>` when `T` is a mutable buffer type such as `String` or `Vec`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::rc_clone_in_vec_init", description: r##"Checks for reference-counted pointers (`Arc`, `Rc`, `rc::Weak`, and `sync::Weak`) in `vec![elem; len]`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::rc_mutex", + description: r##"Checks for `Rc<Mutex<T>>`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::rc_mutex", description: r##"Checks for `Rc<Mutex<T>>`."## }, Lint { label: "clippy::read_line_without_trim", description: r##"Looks for calls to [`Stdin::read_line`] to read a line from the standard input into a string, then later attempting to use that string for an operation that will never work for strings with a trailing newline character in it (e.g. parsing into a `i32`)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::read_zero_byte_vec", description: r##"This lint catches reads into a zero-length `Vec`. Especially in the case of a call to `with_capacity`, this lint warns that read gets the number of bytes from the `Vec`'s length, not its capacity."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::readonly_write_lock", description: r##"Looks for calls to `RwLock::write` where the lock is only used for reading."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::recursive_format_impl", description: r##"Checks for format trait implementations (e.g. `Display`) with a recursive call to itself which uses `self` as a parameter. This is typically done indirectly with the `write!` macro or with `to_string()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::redundant_allocation", description: r##"Checks for usage of redundant allocations anywhere in the code."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::redundant_as_str", description: r##"Checks for usage of `as_str()` on a `String` chained with a method available on the `String` itself."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::redundant_async_block", description: r##"Checks for `async` block that only returns `await` on a future."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::redundant_at_rest_pattern", description: r##"Checks for `[all @ ..]` patterns."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::redundant_clone", description: r##"Checks for a redundant `clone()` (and its relatives) which clones an owned value that is going to be dropped without further use."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::redundant_closure", description: r##"Checks for closures which just call another function where the function can be called directly. `unsafe` functions, calls where types get adjusted or where the callee is marked `#[track_caller]` are ignored."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::redundant_closure_call", description: r##"Detects closures called in the same expression where they are defined."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::redundant_closure_for_method_calls", description: r##"Checks for closures which only invoke a method on the closure argument and can be replaced by referencing the method directly."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::redundant_comparisons", description: r##"Checks for ineffective double comparisons against constants."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::redundant_else", description: r##"Checks for `else` blocks that can be removed without changing semantics."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::redundant_feature_names", description: r##"Checks for feature names with prefix `use-`, `with-` or suffix `-support`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::redundant_field_names", description: r##"Checks for fields in struct literals where shorthands could be used."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::redundant_guards", description: r##"Checks for unnecessary guards in match expressions."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::redundant_locals", description: r##"Checks for redundant redefinitions of local bindings."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::redundant_pattern", description: r##"Checks for patterns in the form `name @ _`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::redundant_pattern_matching", description: r##"Lint for redundant pattern matching over `Result`, `Option`, `std::task::Poll`, `std::net::IpAddr` or `bool`s"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::redundant_pub_crate", description: r##"Checks for items declared `pub(crate)` that are not crate visible because they are inside a private module."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::redundant_slicing", description: r##"Checks for redundant slicing expressions which use the full range, and do not change the type."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::redundant_static_lifetimes", description: r##"Checks for constants and statics with an explicit `'static` lifetime."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::redundant_type_annotations", description: r##"Warns about needless / redundant type annotations."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::ref_as_ptr", description: r##"Checks for casts of references to pointer using `as` and suggests `std::ptr::from_ref` and `std::ptr::from_mut` instead."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::ref_binding_to_reference", description: r##"Checks for `ref` bindings which create a reference to a reference."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::ref_option", + description: r##"Warns when a function signature uses `&Option<T>` instead of `Option<&T>`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::ref_option_ref", description: r##"Checks for usage of `&Option<&T>`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::ref_patterns", description: r##"Checks for usages of the `ref` keyword."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::regex_macro", - description: r##"Nothing. This lint has been deprecated."##, + description: r##"Nothing. This lint has been deprecated"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::renamed_function_params", description: r##"Lints when the name of function parameters from trait impl is different than its default implementation."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::repeat_once", @@ -12917,152 +17056,248 @@ different than its default implementation."##, The lint will evaluate constant expressions and values as arguments of `.repeat(..)` and emit a message if they are equivalent to `1`. (Related discussion in [rust-clippy#7306](https://github.com/rust-lang/rust-clippy/issues/7306))"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::repeat_vec_with_capacity", description: r##"Looks for patterns such as `vec![Vec::with_capacity(x); n]` or `iter::repeat(Vec::with_capacity(x))`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::replace_consts", - description: r##"Nothing. This lint has been deprecated."##, + description: r##"Nothing. This lint has been deprecated"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::reserve_after_initialization", description: r##"Informs the user about a more concise way to create a vector with a known capacity."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::rest_pat_in_fully_bound_structs", description: r##"Checks for unnecessary '..' pattern binding on struct when all fields are explicitly matched."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::result_filter_map", description: r##"Checks for iterators of `Result`s using `.filter(Result::is_ok).map(Result::unwrap)` that may be replaced with a `.flatten()` call."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::result_large_err", description: r##"Checks for functions that return `Result` with an unusually large `Err`-variant."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::result_map_or_into_option", description: r##"Checks for usage of `_.map_or(None, Some)`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::result_map_unit_fn", description: r##"Checks for usage of `result.map(f)` where f is a function or closure that returns the unit type `()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::result_unit_err", description: r##"Checks for public functions that return a `Result` with an `Err` type of `()`. It suggests using a custom type that implements `std::error::Error`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::return_self_not_must_use", description: r##"This lint warns when a method returning `Self` doesn't have the `#[must_use]` attribute."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::reversed_empty_ranges", description: r##"Checks for range expressions `x..y` where both `x` and `y` are constant and `x` is greater to `y`. Also triggers if `x` is equal to `y` when they are conditions to a `for` loop."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::same_functions_in_if_condition", description: r##"Checks for consecutive `if`s with the same function call."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::same_item_push", description: r##"Checks whether a for loop is being used to push a constant value into a Vec."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::same_name_method", description: r##"It lints if a struct has two methods with the same name: one from a trait, another not from a trait."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::search_is_some", description: r##"Checks for an iterator or string search (such as `find()`, `position()`, or `rposition()`) followed by a call to `is_some()` or `is_none()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::seek_from_current", description: r##"Checks if the `seek` method of the `Seek` trait is called with `SeekFrom::Current(0)`, and if it is, suggests using `stream_position` instead."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::seek_to_start_instead_of_rewind", description: r##"Checks for jumps to the start of a stream that implements `Seek` and uses the `seek` method providing `Start` as parameter."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::self_assignment", description: r##"Checks for explicit self-assignments."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::self_named_constructors", description: r##"Warns when constructors have the same name as their types."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::self_named_module_files", description: r##"Checks that module layout uses only `mod.rs` files."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::semicolon_if_nothing_returned", description: r##"Looks for blocks of expressions and fires if the last expression returns `()` but is not followed by a semicolon."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::semicolon_inside_block", description: r##"Suggests moving the semicolon after a block to the inside of the block, after its last expression."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::semicolon_outside_block", description: r##"Suggests moving the semicolon from a block's final expression outside of the block."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::separated_literal_suffix", description: r##"Warns if literal suffixes are separated by an underscore. To enforce separated literal suffix style, see the `unseparated_literal_suffix` lint."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::serde_api_misuse", description: r##"Checks for misuses of the serde API."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::set_contains_or_insert", - description: r##"Checks for usage of `contains` to see if a value is not -present on `HashSet` followed by a `insert`."##, + description: r##"Checks for usage of `contains` to see if a value is not present +in a set like `HashSet` or `BTreeSet`, followed by an `insert`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::shadow_reuse", description: r##"Checks for bindings that shadow other bindings already in scope, while reusing the original value."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::shadow_same", description: r##"Checks for bindings that shadow other bindings already in scope, while just changing reference level or mutability."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::shadow_unrelated", description: r##"Checks for bindings that shadow other bindings already in scope, either without an initialization or with one that does not even use the original value."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::short_circuit_statement", description: r##"Checks for the use of short circuit boolean conditions as a statement."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::should_assert_eq", - description: r##"Nothing. This lint has been deprecated."##, + description: r##"Nothing. This lint has been deprecated"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::should_implement_trait", @@ -13070,21 +17305,33 @@ statement."##, implementation of a `std` trait (see [llogiq's blog post](http://llogiq.github.io/2015/07/30/traits.html) for further information) instead of an inherent implementation."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::should_panic_without_expect", description: r##"Checks for `#[should_panic]` attributes without specifying the expected panic message."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::significant_drop_in_scrutinee", description: r##"Checks for temporaries returned from function calls in a match scrutinee that have the `clippy::has_significant_drop` attribute."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::significant_drop_tightening", description: r##"Searches for elements marked with `#[clippy::has_significant_drop]` that could be early dropped but are in fact dropped at the end of their scopes. In other words, enforces the tightening of their possible lifetimes."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::similar_names", @@ -13093,33 +17340,54 @@ tightening of their possible lifetimes."##, Note: this lint looks for similar names throughout each scope. To allow it, you need to allow it on the scope level, not on the name that is reported."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::single_call_fn", description: r##"Checks for functions that are only used once. Does not lint tests."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::single_char_add_str", description: r##"Warns when using `push_str`/`insert_str` with a single-character string literal where `push`/`insert` with a `char` would work fine."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::single_char_lifetime_names", description: r##"Checks for lifetimes with names which are one character long."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::single_char_pattern", description: r##"Checks for string methods that receive a single-character `str` as an argument, e.g., `_.split(x)`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::single_component_path_imports", description: r##"Checking for imports with single component use path."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::single_element_loop", description: r##"Checks whether a for loop has a single element."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::single_match", @@ -13130,337 +17398,572 @@ This intentionally does not lint if there are comments inside of the other arm, so as to allow the user to document why having another explicit pattern with an empty body is necessary, or because the comments need to be preserved for other reasons."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::single_match_else", description: r##"Checks for matches with two arms where an `if let else` will usually suffice."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::single_range_in_vec_init", description: r##"Checks for `Vec` or array initializations that contain only one range."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::size_of_in_element_count", description: r##"Detects expressions where `size_of::<T>` or `size_of_val::<T>` is used as a count of elements of type `T`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::size_of_ref", description: r##"Checks for calls to `std::mem::size_of_val()` where the argument is a reference to a reference."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::skip_while_next", description: r##"Checks for usage of `_.skip_while(condition).next()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::slow_vector_initialization", description: r##"Checks slow zero-filled vector initialization"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::stable_sort_primitive", description: r##"When sorting primitive values (integers, bools, chars, as well as arrays, slices, and tuples of such items), it is typically better to use an unstable sort than a stable sort."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::std_instead_of_alloc", description: r##"Finds items imported through `std` when available through `alloc`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::std_instead_of_core", description: r##"Finds items imported through `std` when available through `core`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::str_split_at_newline", description: r##"Checks for usages of `str.trim().split(\ )` and `str.trim().split(\\ )`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::str_to_string", description: r##"This lint checks for `.to_string()` method calls on values of type `&str`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::string_add", description: r##"Checks for all instances of `x + _` where `x` is of type `String`, but only if [`string_add_assign`](#string_add_assign) does *not* match."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::string_add_assign", description: r##"Checks for string appends of the form `x = x + y` (without `let`!)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::string_extend_chars", description: r##"Checks for the use of `.extend(s.chars())` where s is a `&str` or `String`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::string_from_utf8_as_bytes", description: r##"Check if the string is transformed to byte array and casted back to string."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::string_lit_as_bytes", description: r##"Checks for the `as_bytes` method called on string literals that contain only ASCII characters."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::string_lit_chars_any", description: r##"Checks for `<string_lit>.chars().any(|i| i == c)`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::string_slice", description: r##"Checks for slice operations on strings"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::string_to_string", description: r##"This lint checks for `.to_string()` method calls on values of type `String`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::strlen_on_c_strings", description: r##"Checks for usage of `libc::strlen` on a `CString` or `CStr` value, and suggest calling `as_bytes().len()` or `to_bytes().len()` respectively instead."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::struct_excessive_bools", description: r##"Checks for excessive use of bools in structs."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::struct_field_names", description: r##"Detects struct fields that are prefixed or suffixed by the same characters or the name of the struct itself."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::suboptimal_flops", description: r##"Looks for floating-point expressions that can be expressed using built-in methods to improve both accuracy and performance."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::suspicious_arithmetic_impl", description: r##"Lints for suspicious operations in impls of arithmetic operators, e.g. subtracting elements in an Add impl."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::suspicious_assignment_formatting", description: r##"Checks for usage of the non-existent `=*`, `=!` and `=-` operators."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::suspicious_command_arg_space", description: r##"Checks for `Command::arg()` invocations that look like they should be multiple arguments instead, such as `arg(-t ext2)`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::suspicious_doc_comments", description: r##"Detects the use of outer doc comments (`///`, `/**`) followed by a bang (`!`): `///!`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::suspicious_else_formatting", description: r##"Checks for formatting of `else`. It lints if the `else` is followed immediately by a newline or the `else` seems to be missing."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::suspicious_map", description: r##"Checks for calls to `map` followed by a `count`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::suspicious_op_assign_impl", description: r##"Lints for suspicious operations in impls of OpAssign, e.g. subtracting elements in an AddAssign impl."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::suspicious_open_options", description: r##"Checks for the suspicious use of `OpenOptions::create()` without an explicit `OpenOptions::truncate()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::suspicious_operation_groupings", description: r##"Checks for unlikely usages of binary operators that are almost certainly typos and/or copy/paste errors, given the other usages of binary operators nearby."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::suspicious_splitn", description: r##"Checks for calls to [`splitn`] (https://doc.rust-lang.org/std/primitive.str.html#method.splitn) and related functions with either zero or one splits."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::suspicious_to_owned", description: r##"Checks for the usage of `_.to_owned()`, on a `Cow<'_, _>`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::suspicious_unary_op_formatting", description: r##"Checks the formatting of a unary operator on the right hand side of a binary operator. It lints if there is no space between the binary and unary operators, but there is a space between the unary and its operand."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::suspicious_xor_used_as_pow", description: r##"Warns for a Bitwise XOR (`^`) operator being probably confused as a powering. It will not trigger if any of the numbers are not in decimal."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::swap_ptr_to_ref", description: r##"Checks for calls to `core::mem::swap` where either parameter is derived from a pointer"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::tabs_in_doc_comments", description: r##"Checks doc comments for usage of tab characters."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::temporary_assignment", description: r##"Checks for construction of a structure or tuple just to assign a value in it."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::test_attr_in_doctest", description: r##"Checks for `#[test]` in doctests unless they are marked with either `ignore`, `no_run` or `compile_fail`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::tests_outside_test_module", description: r##"Triggers when a testing function (marked with the `#[test]` attribute) isn't inside a testing module (marked with `#[cfg(test)]`)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::to_digit_is_some", description: r##"Checks for `.to_digit(..).is_some()` on `char`s."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::to_string_in_format_args", description: r##"Checks for [`ToString::to_string`](https://doc.rust-lang.org/std/string/trait.ToString.html#tymethod.to_string) applied to a type that implements [`Display`](https://doc.rust-lang.org/std/fmt/trait.Display.html) in a macro that does formatting."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::to_string_trait_impl", description: r##"Checks for direct implementations of `ToString`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::todo", + description: r##"Checks for usage of `todo!`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::too_long_first_doc_paragraph", + description: r##"Checks if the first line in the documentation of items listed in module page is too long."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::todo", description: r##"Checks for usage of `todo!`."## }, Lint { label: "clippy::too_many_arguments", description: r##"Checks for functions with too many parameters."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::too_many_lines", description: r##"Checks for functions with a large amount of lines."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::toplevel_ref_arg", description: r##"Checks for function arguments and let bindings denoted as `ref`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::trailing_empty_array", description: r##"Displays a warning when a struct with a trailing zero-sized array is declared without a `repr` attribute."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::trait_duplication_in_bounds", description: r##"Checks for cases where generics or trait objects are being used and multiple syntax specifications for trait bounds are used simultaneously."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::transmute_bytes_to_str", description: r##"Checks for transmutes from a `&[u8]` to a `&str`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::transmute_float_to_int", description: r##"Checks for transmutes from a float to an integer."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::transmute_int_to_bool", description: r##"Checks for transmutes from an integer to a `bool`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::transmute_int_to_char", description: r##"Checks for transmutes from an integer to a `char`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::transmute_int_to_float", description: r##"Checks for transmutes from an integer to a float."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::transmute_int_to_non_zero", description: r##"Checks for transmutes from `T` to `NonZero<T>`, and suggests the `new_unchecked` method instead."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::transmute_null_to_fn", description: r##"Checks for null function pointer creation through transmute."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::transmute_num_to_bytes", description: r##"Checks for transmutes from a number to an array of `u8`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::transmute_ptr_to_ptr", description: r##"Checks for transmutes from a pointer to a pointer, or from a reference to a reference."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::transmute_ptr_to_ref", description: r##"Checks for transmutes from a pointer to a reference."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::transmute_undefined_repr", description: r##"Checks for transmutes between types which do not have a representation defined relative to each other."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::transmutes_expressible_as_ptr_casts", description: r##"Checks for transmutes that could be a pointer cast."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::transmuting_null", description: r##"Checks for transmute calls which would receive a null pointer."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::trim_split_whitespace", description: r##"Warns about calling `str::trim` (or variants) before `str::split_whitespace`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::trivial_regex", description: r##"Checks for trivial [regex](https://crates.io/crates/regex) creation (with `Regex::new`, `RegexBuilder::new`, or `RegexSet::new`)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::trivially_copy_pass_by_ref", description: r##"Checks for functions taking arguments by reference, where the argument type is `Copy` and small enough to be more efficient to always pass by value."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::try_err", + description: r##"Checks for usage of `Err(x)?`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::try_err", description: r##"Checks for usage of `Err(x)?`."## }, Lint { label: "clippy::tuple_array_conversions", description: r##"Checks for tuple<=>array conversions that are not done with `.into()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::type_complexity", description: r##"Checks for types used in structs, parameters and `let` declarations above a certain complexity threshold."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::type_id_on_box", description: r##"Looks for calls to `.type_id()` on a `Box<dyn _>`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::type_repetition_in_bounds", description: r##"This lint warns about unnecessary type repetitions in trait bounds"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unchecked_duration_subtraction", description: r##"Lints subtraction between an `Instant` and a `Duration`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unconditional_recursion", description: r##"Checks that there isn't an infinite recursion in trait implementations."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::undocumented_unsafe_blocks", @@ -13485,53 +17988,89 @@ foo( /* SAFETY: Neither is this */ unsafe { *x }, ); ```"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unicode_not_nfc", description: r##"Checks for string literals that contain Unicode in a form that is not equal to its [NFC-recomposition](http://www.unicode.org/reports/tr15/#Norm_Forms)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unimplemented", description: r##"Checks for usage of `unimplemented!`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::uninhabited_references", description: r##"It detects references to uninhabited types, such as `!` and warns when those are either dereferenced or returned from a function."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::uninit_assumed_init", description: r##"Checks for `MaybeUninit::uninit().assume_init()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::uninit_vec", description: r##"Checks for `set_len()` call that creates `Vec` with uninitialized elements. This is commonly caused by calling `set_len()` right after allocating or reserving a buffer with `new()`, `default()`, `with_capacity()`, or `reserve()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::uninlined_format_args", description: r##"Detect when a variable is not inlined in a format string, and suggests to inline it."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unit_arg", description: r##"Checks for passing a unit value as an argument to a function without using a unit literal (`()`)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unit_cmp", description: r##"Checks for comparisons to unit. This includes all binary comparisons (like `==` and `<`) and asserts."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::unit_hash", + description: r##"Detects `().hash(_)`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::unit_hash", description: r##"Detects `().hash(_)`."## }, Lint { label: "clippy::unit_return_expecting_ord", description: r##"Checks for functions that expect closures of type Fn(...) -> Ord where the implemented closure returns the unit type. The lint also suggests to remove the semi-colon at the end of the statement if present."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_box_returns", @@ -13539,48 +18078,83 @@ The lint also suggests to remove the semi-colon at the end of the statement if p The lint ignores `Box<T>` where `T` is larger than `unnecessary_box_size`, as returning a large `T` directly may be detrimental to performance."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_cast", description: r##"Checks for casts to the same type, casts of int literals to integer types, casts of float literals to float types, and casts between raw pointers that don't change type or constness."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_clippy_cfg", description: r##"Checks for `#[cfg_attr(clippy, allow(clippy::lint))]` and suggests to replace it with `#[allow(clippy::lint)]`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_fallible_conversions", description: r##"Checks for calls to `TryInto::try_into` and `TryFrom::try_from` when their infallible counterparts could be used."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_filter_map", description: r##"Checks for `filter_map` calls that could be replaced by `filter` or `map`. More specifically it checks if the closure provided is only performing one of the filter or map operations and suggests the appropriate option."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_find_map", description: r##"Checks for `find_map` calls that could be replaced by `find` or `map`. More specifically it checks if the closure provided is only performing one of the find or map operations and suggests the appropriate option."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::unnecessary_first_then_check", + description: r##"Checks the usage of `.first().is_some()` or `.first().is_none()` to check if a slice is +empty."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_fold", description: r##"Checks for usage of `fold` when a more succinct alternative exists. Specifically, this checks for `fold`s which could be replaced by `any`, `all`, `sum` or `product`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_get_then_check", description: r##"Checks the usage of `.get().is_some()` or `.get().is_none()` on std map types."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_join", description: r##"Checks for usage of `.collect::<Vec<String>>().join()` on iterators."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_lazy_evaluations", @@ -13595,80 +18169,131 @@ simpler code: - `get_or_insert_with` to `get_or_insert` - `ok_or_else` to `ok_or` - `then` to `then_some` (for msrv >= 1.62.0)"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_literal_unwrap", description: r##"Checks for `.unwrap()` related calls on `Result`s and `Option`s that are constructed."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_map_on_constructor", description: r##"Suggests removing the use of a `map()` (or `map_err()`) method when an `Option` or `Result` is being constructed."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_min_or_max", description: r##"Checks for unnecessary calls to `min()` or `max()` in the following cases - Either both side is constant - One side is clearly larger than the other, like i32::MIN and an i32 variable"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_mut_passed", description: r##"Detects passing a mutable reference to a function that only requires an immutable reference."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_operation", description: r##"Checks for expression statements that can be reduced to a sub-expression."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_owned_empty_strings", description: r##"Detects cases of owned empty strings being passed as an argument to a function expecting `&str`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_result_map_or_else", description: r##"Checks for usage of `.map_or_else()` map closure for `Result` type."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_safety_comment", description: r##"Checks for `// SAFETY: ` comments on safe code."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_safety_doc", description: r##"Checks for the doc comments of publicly visible safe functions and traits and warns if there is a `# Safety` section."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_self_imports", description: r##"Checks for imports ending in `::{self}`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_sort_by", description: r##"Checks for usage of `Vec::sort_by` passing in a closure which compares the two arguments, either directly or indirectly."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_struct_initialization", description: r##"Checks for initialization of an identical `struct` from another instance of the type, either by copying a base without setting any field or by moving all fields individually."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_to_owned", description: r##"Checks for unnecessary calls to [`ToOwned::to_owned`](https://doc.rust-lang.org/std/borrow/trait.ToOwned.html#tymethod.to_owned) and other `to_owned`-like functions."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_unwrap", description: r##"Checks for calls of `unwrap[_err]()` that cannot fail."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_wraps", description: r##"Checks for private functions that only return `Ok` or `Some`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unneeded_field_pattern", description: r##"Checks for structure field patterns bound to wildcards."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unneeded_wildcard_pattern", @@ -13679,6 +18304,9 @@ _NOTE_: While `_, ..` means there is at least one element left, `..` means there are 0 or more elements left. This can make a difference when refactoring, but shouldn't result in errors in the refactored code, since the wildcard pattern isn't used anyway."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnested_or_patterns", @@ -13687,26 +18315,47 @@ suggests replacing the pattern with a nested one, `Some(0 | 2)`. Another way to think of this is that it rewrites patterns in *disjunctive normal form (DNF)* into *conjunctive normal form (CNF)*."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::unreachable", + description: r##"Checks for usage of `unreachable!`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::unreachable", description: r##"Checks for usage of `unreachable!`."## }, Lint { label: "clippy::unreadable_literal", description: r##"Warns if a long integral or floating-point constant does not contain underscores."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unsafe_derive_deserialize", description: r##"Checks for deriving `serde::Deserialize` on a type that has methods using `unsafe`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unsafe_removed_from_name", description: r##"Checks for imports that remove unsafe from an item's name."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unsafe_vector_initialization", - description: r##"Nothing. This lint has been deprecated."##, + description: r##"Nothing. This lint has been deprecated"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unseparated_literal_suffix", @@ -13714,66 +18363,125 @@ name."##, underscore. To enforce unseparated literal suffix style, see the `separated_literal_suffix` lint."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unsound_collection_transmute", description: r##"Checks for transmutes between collections whose types have different ABI, size or alignment."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unstable_as_mut_slice", - description: r##"Nothing. This lint has been deprecated."##, + description: r##"Nothing. This lint has been deprecated"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unstable_as_slice", - description: r##"Nothing. This lint has been deprecated."##, + description: r##"Nothing. This lint has been deprecated"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unused_async", description: r##"Checks for functions that are declared `async` but have no `.await`s inside of them."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unused_collect", - description: r##"Nothing. This lint has been deprecated."##, + description: r##"Nothing. This lint has been deprecated"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unused_enumerate_index", description: r##"Checks for uses of the `enumerate` method where the index is unused (`_`)"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unused_format_specs", description: r##"Detects [formatting parameters] that have no effect on the output of `format!()`, `println!()` or similar macros."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unused_io_amount", description: r##"Checks for unused written/read amount."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unused_peekable", description: r##"Checks for the creation of a `peekable` iterator that is never `.peek()`ed"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::unused_result_ok", + description: r##"Checks for calls to `Result::ok()` without using the returned `Option`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unused_rounding", description: r##"Detects cases where a whole-number literal float is being rounded, using the `floor`, `ceil`, or `round` methods."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unused_self", description: r##"Checks methods that contain a `self` argument but don't use it"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::unused_trait_names", + description: r##"Checks for `use Trait` where the Trait is only used for its methods and not referenced by a path directly."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unused_unit", description: r##"Checks for unit (`()`) expressions that can be removed."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unusual_byte_groupings", description: r##"Warns if hexadecimal or binary literals are not grouped by nibble or byte."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unwrap_in_result", description: r##"Checks for functions of type `Result` that contain `expect()` or `unwrap()`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unwrap_or_default", @@ -13783,34 +18491,63 @@ by nibble or byte."##, - `unwrap_or_else` - `or_insert` - `or_insert_with`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unwrap_used", description: r##"Checks for `.unwrap()` or `.unwrap_err()` calls on `Result`s and `.unwrap()` call on `Option`s."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::upper_case_acronyms", description: r##"Checks for fully capitalized names and optionally names containing a capitalized acronym."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::use_debug", description: r##"Checks for usage of `Debug` formatting. The purpose of this lint is to catch debugging remnants."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::use_self", description: r##"Checks for unnecessary repetition of structure name when a replacement with `Self` is applicable."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::used_underscore_binding", description: r##"Checks for the use of bindings with a single leading underscore."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::used_underscore_items", + description: r##"Checks for the use of item with a single leading +underscore."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::useless_asref", description: r##"Checks for usage of `.as_ref()` or `.as_mut()` where the types before and after the call are the same."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::useless_attribute", @@ -13838,36 +18575,57 @@ For `use` items these lints are: For `extern crate` items these lints are: * `unused_imports` on items with `#[macro_use]`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::useless_conversion", description: r##"Checks for `Into`, `TryInto`, `From`, `TryFrom`, or `IntoIter` calls which uselessly convert to the same type."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::useless_format", description: r##"Checks for the use of `format!(string literal with no argument)` and `format!({}, foo)` where `foo` is a string."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::useless_let_if_seq", description: r##"Checks for variable declarations immediately followed by a conditional affectation."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::useless_transmute", description: r##"Checks for transmutes to the original type of the object and transmutes that could be a cast."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::useless_vec", description: r##"Checks for usage of `vec![..]` when using `[..]` would be possible."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::vec_box", description: r##"Checks for usage of `Vec<Box<T>>` where T: Sized anywhere in the code. Check the [Box documentation](https://doc.rust-lang.org/std/boxed/index.html) for more information."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::vec_init_then_push", @@ -13879,76 +18637,127 @@ constant and the number of pushes is greater than or equal to the initial capaci If the `Vec` is extended after the initial sequence of pushes and it was default initialized then this will only lint after there were at least four pushes. This number may change in the future."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::vec_resize_to_zero", description: r##"Finds occurrences of `Vec::resize(0, an_int)`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::verbose_bit_mask", description: r##"Checks for bit masks that can be replaced by a call to `trailing_zeros`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::verbose_file_reads", description: r##"Checks for usage of File::read_to_end and File::read_to_string."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::waker_clone_wake", description: r##"Checks for usage of `waker.clone().wake()`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::while_float", description: r##"Checks for while loops comparing floating point values."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::while_immutable_condition", description: r##"Checks whether variables used within while loop condition can be (and are) mutated in the body."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::while_let_loop", description: r##"Detects `loop + match` combinations that are easier written as a `while let` loop."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::while_let_on_iterator", description: r##"Checks for `while let` expressions on iterators."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::wildcard_dependencies", description: r##"Checks for wildcard dependencies in the `Cargo.toml`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::wildcard_enum_match_arm", description: r##"Checks for wildcard enum matches using `_`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::wildcard_imports", description: r##"Checks for wildcard imports `use _::*`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::wildcard_in_or_patterns", description: r##"Checks for wildcard pattern used with others patterns in same match arm."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::write_literal", description: r##"This lint warns about the use of literals as `write!`/`writeln!` args."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::write_with_newline", description: r##"This lint warns when you use `write!()` with a format string that ends in a newline."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::writeln_empty_string", description: r##"This lint warns when you use `writeln!(buf, )` to print a newline."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::wrong_pub_self_convention", - description: r##"Nothing. This lint has been deprecated."##, + description: r##"Nothing. This lint has been deprecated"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::wrong_self_convention", @@ -13977,34 +18786,68 @@ Clippy allows `Pin<&Self>` and `Pin<&mut Self>` if `&self` and `&mut self` is re Please find more info here: https://rust-lang.github.io/api-guidelines/naming.html#ad-hoc-conversions-follow-as_-to_-into_-conventions-c-conv"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::wrong_transmute", description: r##"Checks for transmutes that can't ever be correct on any architecture."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::zero_divided_by_zero", + description: r##"Checks for `0.0 / 0.0`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::zero_divided_by_zero", description: r##"Checks for `0.0 / 0.0`."## }, Lint { label: "clippy::zero_prefixed_literal", description: r##"Warns if an integral constant literal starts with `0`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::zero_ptr", description: r##"Catch casts from `0` to some pointer type"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::zero_repeat_side_effects", description: r##"Checks for array or vec initializations which call a function or method, but which have a repeat count of zero."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::zero_sized_map_values", description: r##"Checks for maps with zero-sized value types anywhere in the code."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::zombie_processes", + description: r##"Looks for code that spawns a process but never calls `wait()` on the child."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::zst_offset", description: r##"Checks for `offset(_)`, `wrapping_`{`add`, `sub`}, etc. on raw pointers to zero-sized types"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, ]; pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ @@ -14012,6 +18855,9 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ lint: Lint { label: "clippy::cargo", description: r##"lint group for: clippy::cargo_common_metadata, clippy::multiple_crate_versions, clippy::negative_feature_names, clippy::redundant_feature_names, clippy::wildcard_dependencies"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, children: &[ "clippy::cargo_common_metadata", @@ -14024,7 +18870,10 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ LintGroup { lint: Lint { label: "clippy::complexity", - description: r##"lint group for: clippy::bind_instead_of_map, clippy::bool_comparison, clippy::borrow_deref_ref, clippy::borrowed_box, clippy::bytes_count_to_len, clippy::char_lit_as_u8, clippy::clone_on_copy, clippy::crosspointer_transmute, clippy::default_constructed_unit_structs, clippy::deprecated_cfg_attr, clippy::deref_addrof, clippy::derivable_impls, clippy::diverging_sub_expression, clippy::double_comparisons, clippy::double_parens, clippy::duration_subsec, clippy::excessive_nesting, clippy::explicit_auto_deref, clippy::explicit_counter_loop, clippy::explicit_write, clippy::extra_unused_lifetimes, clippy::extra_unused_type_parameters, clippy::filter_map_identity, clippy::filter_next, clippy::flat_map_identity, clippy::get_last_with_len, clippy::identity_op, clippy::implied_bounds_in_impls, clippy::inspect_for_each, clippy::int_plus_one, clippy::iter_count, clippy::iter_kv_map, clippy::let_with_type_underscore, clippy::manual_clamp, clippy::manual_filter, clippy::manual_filter_map, clippy::manual_find, clippy::manual_find_map, clippy::manual_flatten, clippy::manual_hash_one, clippy::manual_inspect, clippy::manual_main_separator_str, clippy::manual_range_patterns, clippy::manual_rem_euclid, clippy::manual_slice_size_calculation, clippy::manual_split_once, clippy::manual_strip, clippy::manual_swap, clippy::manual_unwrap_or, clippy::map_flatten, clippy::map_identity, clippy::match_as_ref, clippy::match_single_binding, clippy::needless_arbitrary_self_type, clippy::needless_bool, clippy::needless_bool_assign, clippy::needless_borrowed_reference, clippy::needless_if, clippy::needless_lifetimes, clippy::needless_match, clippy::needless_option_as_deref, clippy::needless_option_take, clippy::needless_question_mark, clippy::needless_splitn, clippy::needless_update, clippy::neg_cmp_op_on_partial_ord, clippy::no_effect, clippy::nonminimal_bool, clippy::only_used_in_recursion, clippy::option_as_ref_deref, clippy::option_filter_map, clippy::option_map_unit_fn, clippy::or_then_unwrap, clippy::partialeq_ne_impl, clippy::precedence, clippy::ptr_offset_with_cast, clippy::range_zip_with_len, clippy::redundant_as_str, clippy::redundant_async_block, clippy::redundant_at_rest_pattern, clippy::redundant_closure_call, clippy::redundant_guards, clippy::redundant_slicing, clippy::repeat_once, clippy::reserve_after_initialization, clippy::result_filter_map, clippy::result_map_unit_fn, clippy::search_is_some, clippy::seek_from_current, clippy::seek_to_start_instead_of_rewind, clippy::short_circuit_statement, clippy::single_element_loop, clippy::skip_while_next, clippy::string_from_utf8_as_bytes, clippy::strlen_on_c_strings, clippy::temporary_assignment, clippy::too_many_arguments, clippy::transmute_bytes_to_str, clippy::transmute_float_to_int, clippy::transmute_int_to_bool, clippy::transmute_int_to_char, clippy::transmute_int_to_float, clippy::transmute_int_to_non_zero, clippy::transmute_num_to_bytes, clippy::transmute_ptr_to_ref, clippy::transmutes_expressible_as_ptr_casts, clippy::type_complexity, clippy::unit_arg, clippy::unnecessary_cast, clippy::unnecessary_filter_map, clippy::unnecessary_find_map, clippy::unnecessary_literal_unwrap, clippy::unnecessary_map_on_constructor, clippy::unnecessary_min_or_max, clippy::unnecessary_operation, clippy::unnecessary_sort_by, clippy::unnecessary_unwrap, clippy::unneeded_wildcard_pattern, clippy::unused_format_specs, clippy::useless_asref, clippy::useless_conversion, clippy::useless_format, clippy::useless_transmute, clippy::vec_box, clippy::while_let_loop, clippy::wildcard_in_or_patterns, clippy::zero_divided_by_zero, clippy::zero_prefixed_literal"##, + description: r##"lint group for: clippy::bind_instead_of_map, clippy::bool_comparison, clippy::borrow_deref_ref, clippy::borrowed_box, clippy::bytes_count_to_len, clippy::char_lit_as_u8, clippy::clone_on_copy, clippy::crosspointer_transmute, clippy::default_constructed_unit_structs, clippy::deprecated_cfg_attr, clippy::deref_addrof, clippy::derivable_impls, clippy::diverging_sub_expression, clippy::double_comparisons, clippy::double_parens, clippy::duration_subsec, clippy::excessive_nesting, clippy::explicit_auto_deref, clippy::explicit_counter_loop, clippy::explicit_write, clippy::extra_unused_lifetimes, clippy::extra_unused_type_parameters, clippy::filter_map_identity, clippy::filter_next, clippy::flat_map_identity, clippy::get_last_with_len, clippy::identity_op, clippy::implied_bounds_in_impls, clippy::inspect_for_each, clippy::int_plus_one, clippy::iter_count, clippy::iter_kv_map, clippy::let_with_type_underscore, clippy::manual_c_str_literals, clippy::manual_clamp, clippy::manual_div_ceil, clippy::manual_filter, clippy::manual_filter_map, clippy::manual_find, clippy::manual_find_map, clippy::manual_flatten, clippy::manual_hash_one, clippy::manual_inspect, clippy::manual_is_power_of_two, clippy::manual_main_separator_str, clippy::manual_range_patterns, clippy::manual_rem_euclid, clippy::manual_slice_size_calculation, clippy::manual_split_once, clippy::manual_strip, clippy::manual_swap, clippy::manual_unwrap_or, clippy::map_flatten, clippy::map_identity, clippy::match_as_ref, clippy::match_single_binding, clippy::needless_arbitrary_self_type, clippy::needless_bool, clippy::needless_bool_assign, clippy::needless_borrowed_reference, clippy::needless_if, clippy::needless_lifetimes, clippy::needless_match, clippy::needless_option_as_deref, clippy::needless_option_take, clippy::needless_question_mark, clippy::needless_splitn, clippy::needless_update, clippy::neg_cmp_op_on_partial_ord, clippy::no_effect, clippy::nonminimal_bool, clippy::only_used_in_recursion, clippy::option_as_ref_deref, clippy::option_filter_map, clippy::option_map_unit_fn, clippy::or_then_unwrap, clippy::partialeq_ne_impl, clippy::precedence, clippy::ptr_offset_with_cast, clippy::range_zip_with_len, clippy::redundant_as_str, clippy::redundant_async_block, clippy::redundant_at_rest_pattern, clippy::redundant_closure_call, clippy::redundant_guards, clippy::redundant_slicing, clippy::repeat_once, clippy::reserve_after_initialization, clippy::result_filter_map, clippy::result_map_unit_fn, clippy::search_is_some, clippy::seek_from_current, clippy::seek_to_start_instead_of_rewind, clippy::short_circuit_statement, clippy::single_element_loop, clippy::skip_while_next, clippy::string_from_utf8_as_bytes, clippy::strlen_on_c_strings, clippy::temporary_assignment, clippy::too_many_arguments, clippy::transmute_bytes_to_str, clippy::transmute_float_to_int, clippy::transmute_int_to_bool, clippy::transmute_int_to_char, clippy::transmute_int_to_float, clippy::transmute_int_to_non_zero, clippy::transmute_num_to_bytes, clippy::transmute_ptr_to_ref, clippy::transmutes_expressible_as_ptr_casts, clippy::type_complexity, clippy::unit_arg, clippy::unnecessary_cast, clippy::unnecessary_filter_map, clippy::unnecessary_find_map, clippy::unnecessary_first_then_check, clippy::unnecessary_literal_unwrap, clippy::unnecessary_map_on_constructor, clippy::unnecessary_min_or_max, clippy::unnecessary_operation, clippy::unnecessary_sort_by, clippy::unnecessary_unwrap, clippy::unneeded_wildcard_pattern, clippy::unused_format_specs, clippy::useless_asref, clippy::useless_conversion, clippy::useless_format, clippy::useless_transmute, clippy::vec_box, clippy::while_let_loop, clippy::wildcard_in_or_patterns, clippy::zero_divided_by_zero, clippy::zero_prefixed_literal"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, children: &[ "clippy::bind_instead_of_map", @@ -14060,7 +18909,9 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ "clippy::iter_count", "clippy::iter_kv_map", "clippy::let_with_type_underscore", + "clippy::manual_c_str_literals", "clippy::manual_clamp", + "clippy::manual_div_ceil", "clippy::manual_filter", "clippy::manual_filter_map", "clippy::manual_find", @@ -14068,6 +18919,7 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ "clippy::manual_flatten", "clippy::manual_hash_one", "clippy::manual_inspect", + "clippy::manual_is_power_of_two", "clippy::manual_main_separator_str", "clippy::manual_range_patterns", "clippy::manual_rem_euclid", @@ -14138,6 +18990,7 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ "clippy::unnecessary_cast", "clippy::unnecessary_filter_map", "clippy::unnecessary_find_map", + "clippy::unnecessary_first_then_check", "clippy::unnecessary_literal_unwrap", "clippy::unnecessary_map_on_constructor", "clippy::unnecessary_min_or_max", @@ -14160,7 +19013,10 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ LintGroup { lint: Lint { label: "clippy::correctness", - description: r##"lint group for: clippy::absurd_extreme_comparisons, clippy::almost_swapped, clippy::approx_constant, clippy::async_yields_async, clippy::bad_bit_mask, clippy::cast_slice_different_sizes, clippy::deprecated_semver, clippy::derive_ord_xor_partial_ord, clippy::derived_hash_with_manual_eq, clippy::eager_transmute, clippy::enum_clike_unportable_variant, clippy::eq_op, clippy::erasing_op, clippy::fn_address_comparisons, clippy::if_let_mutex, clippy::ifs_same_cond, clippy::impl_hash_borrow_with_str_and_bytes, clippy::impossible_comparisons, clippy::ineffective_bit_mask, clippy::infinite_iter, clippy::inherent_to_string_shadow_display, clippy::inline_fn_without_body, clippy::invalid_null_ptr_usage, clippy::invalid_regex, clippy::invisible_characters, clippy::iter_next_loop, clippy::iter_skip_zero, clippy::iterator_step_by_zero, clippy::let_underscore_lock, clippy::lint_groups_priority, clippy::match_str_case_mismatch, clippy::mem_replace_with_uninit, clippy::min_max, clippy::mistyped_literal_suffixes, clippy::modulo_one, clippy::mut_from_ref, clippy::never_loop, clippy::non_octal_unix_permissions, clippy::nonsensical_open_options, clippy::not_unsafe_ptr_arg_deref, clippy::option_env_unwrap, clippy::out_of_bounds_indexing, clippy::overly_complex_bool_expr, clippy::panicking_overflow_checks, clippy::panicking_unwrap, clippy::possible_missing_comma, clippy::read_line_without_trim, clippy::recursive_format_impl, clippy::redundant_comparisons, clippy::redundant_locals, clippy::reversed_empty_ranges, clippy::self_assignment, clippy::serde_api_misuse, clippy::size_of_in_element_count, clippy::suspicious_splitn, clippy::transmute_null_to_fn, clippy::transmuting_null, clippy::uninit_assumed_init, clippy::uninit_vec, clippy::unit_cmp, clippy::unit_hash, clippy::unit_return_expecting_ord, clippy::unsound_collection_transmute, clippy::unused_io_amount, clippy::useless_attribute, clippy::vec_resize_to_zero, clippy::while_immutable_condition, clippy::wrong_transmute, clippy::zst_offset"##, + description: r##"lint group for: clippy::absurd_extreme_comparisons, clippy::almost_swapped, clippy::approx_constant, clippy::async_yields_async, clippy::bad_bit_mask, clippy::cast_slice_different_sizes, clippy::deprecated_semver, clippy::derive_ord_xor_partial_ord, clippy::derived_hash_with_manual_eq, clippy::eager_transmute, clippy::enum_clike_unportable_variant, clippy::eq_op, clippy::erasing_op, clippy::fn_address_comparisons, clippy::if_let_mutex, clippy::ifs_same_cond, clippy::impl_hash_borrow_with_str_and_bytes, clippy::impossible_comparisons, clippy::ineffective_bit_mask, clippy::infinite_iter, clippy::inherent_to_string_shadow_display, clippy::inline_fn_without_body, clippy::invalid_null_ptr_usage, clippy::invalid_regex, clippy::inverted_saturating_sub, clippy::invisible_characters, clippy::iter_next_loop, clippy::iter_skip_zero, clippy::iterator_step_by_zero, clippy::let_underscore_lock, clippy::lint_groups_priority, clippy::match_str_case_mismatch, clippy::mem_replace_with_uninit, clippy::min_max, clippy::mistyped_literal_suffixes, clippy::modulo_one, clippy::mut_from_ref, clippy::never_loop, clippy::non_octal_unix_permissions, clippy::nonsensical_open_options, clippy::not_unsafe_ptr_arg_deref, clippy::option_env_unwrap, clippy::out_of_bounds_indexing, clippy::overly_complex_bool_expr, clippy::panicking_overflow_checks, clippy::panicking_unwrap, clippy::possible_missing_comma, clippy::read_line_without_trim, clippy::recursive_format_impl, clippy::redundant_comparisons, clippy::redundant_locals, clippy::reversed_empty_ranges, clippy::self_assignment, clippy::serde_api_misuse, clippy::size_of_in_element_count, clippy::suspicious_splitn, clippy::transmute_null_to_fn, clippy::transmuting_null, clippy::uninit_assumed_init, clippy::uninit_vec, clippy::unit_cmp, clippy::unit_hash, clippy::unit_return_expecting_ord, clippy::unsound_collection_transmute, clippy::unused_io_amount, clippy::useless_attribute, clippy::vec_resize_to_zero, clippy::while_immutable_condition, clippy::wrong_transmute, clippy::zst_offset"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, children: &[ "clippy::absurd_extreme_comparisons", @@ -14187,6 +19043,7 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ "clippy::inline_fn_without_body", "clippy::invalid_null_ptr_usage", "clippy::invalid_regex", + "clippy::inverted_saturating_sub", "clippy::invisible_characters", "clippy::iter_next_loop", "clippy::iter_skip_zero", @@ -14237,17 +19094,15 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ LintGroup { lint: Lint { label: "clippy::deprecated", - description: r##"lint group for: clippy::assign_ops, clippy::extend_from_slice, clippy::filter_map, clippy::find_map, clippy::if_let_redundant_pattern_matching, clippy::maybe_misused_cfg, clippy::misaligned_transmute, clippy::mismatched_target_os, clippy::pub_enum_variant_names, clippy::range_step_by_zero, clippy::regex_macro, clippy::replace_consts, clippy::should_assert_eq, clippy::unsafe_vector_initialization, clippy::unstable_as_mut_slice, clippy::unstable_as_slice, clippy::unused_collect, clippy::wrong_pub_self_convention"##, + description: r##"lint group for: clippy::assign_ops, clippy::extend_from_slice, clippy::misaligned_transmute, clippy::pub_enum_variant_names, clippy::range_step_by_zero, clippy::regex_macro, clippy::replace_consts, clippy::should_assert_eq, clippy::unsafe_vector_initialization, clippy::unstable_as_mut_slice, clippy::unstable_as_slice, clippy::unused_collect, clippy::wrong_pub_self_convention"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, children: &[ "clippy::assign_ops", "clippy::extend_from_slice", - "clippy::filter_map", - "clippy::find_map", - "clippy::if_let_redundant_pattern_matching", - "clippy::maybe_misused_cfg", "clippy::misaligned_transmute", - "clippy::mismatched_target_os", "clippy::pub_enum_variant_names", "clippy::range_step_by_zero", "clippy::regex_macro", @@ -14263,7 +19118,10 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ LintGroup { lint: Lint { label: "clippy::nursery", - description: r##"lint group for: clippy::as_ptr_cast_mut, clippy::branches_sharing_code, clippy::clear_with_drain, clippy::cognitive_complexity, clippy::collection_is_never_read, clippy::debug_assert_with_mut_call, clippy::derive_partial_eq_without_eq, clippy::empty_line_after_doc_comments, clippy::empty_line_after_outer_attr, clippy::equatable_if_let, clippy::fallible_impl_from, clippy::future_not_send, clippy::imprecise_flops, clippy::iter_on_empty_collections, clippy::iter_on_single_items, clippy::iter_with_drain, clippy::large_stack_frames, clippy::missing_const_for_fn, clippy::mutex_integer, clippy::needless_collect, clippy::needless_pass_by_ref_mut, clippy::non_send_fields_in_send_ty, clippy::nonstandard_macro_braces, clippy::option_if_let_else, clippy::or_fun_call, clippy::path_buf_push_overwrite, clippy::read_zero_byte_vec, clippy::redundant_clone, clippy::redundant_pub_crate, clippy::set_contains_or_insert, clippy::significant_drop_in_scrutinee, clippy::significant_drop_tightening, clippy::string_lit_as_bytes, clippy::suboptimal_flops, clippy::suspicious_operation_groupings, clippy::trailing_empty_array, clippy::trait_duplication_in_bounds, clippy::transmute_undefined_repr, clippy::trivial_regex, clippy::tuple_array_conversions, clippy::type_repetition_in_bounds, clippy::uninhabited_references, clippy::unnecessary_struct_initialization, clippy::unused_peekable, clippy::unused_rounding, clippy::use_self, clippy::useless_let_if_seq, clippy::while_float"##, + description: r##"lint group for: clippy::as_ptr_cast_mut, clippy::branches_sharing_code, clippy::clear_with_drain, clippy::cognitive_complexity, clippy::collection_is_never_read, clippy::debug_assert_with_mut_call, clippy::derive_partial_eq_without_eq, clippy::equatable_if_let, clippy::fallible_impl_from, clippy::future_not_send, clippy::imprecise_flops, clippy::iter_on_empty_collections, clippy::iter_on_single_items, clippy::iter_with_drain, clippy::large_stack_frames, clippy::missing_const_for_fn, clippy::mutex_integer, clippy::needless_collect, clippy::needless_pass_by_ref_mut, clippy::non_send_fields_in_send_ty, clippy::nonstandard_macro_braces, clippy::option_if_let_else, clippy::or_fun_call, clippy::path_buf_push_overwrite, clippy::read_zero_byte_vec, clippy::redundant_clone, clippy::redundant_pub_crate, clippy::set_contains_or_insert, clippy::significant_drop_in_scrutinee, clippy::significant_drop_tightening, clippy::string_lit_as_bytes, clippy::suboptimal_flops, clippy::suspicious_operation_groupings, clippy::trailing_empty_array, clippy::trait_duplication_in_bounds, clippy::transmute_undefined_repr, clippy::trivial_regex, clippy::tuple_array_conversions, clippy::type_repetition_in_bounds, clippy::uninhabited_references, clippy::unnecessary_struct_initialization, clippy::unused_peekable, clippy::unused_rounding, clippy::use_self, clippy::useless_let_if_seq, clippy::while_float"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, children: &[ "clippy::as_ptr_cast_mut", @@ -14273,8 +19131,6 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ "clippy::collection_is_never_read", "clippy::debug_assert_with_mut_call", "clippy::derive_partial_eq_without_eq", - "clippy::empty_line_after_doc_comments", - "clippy::empty_line_after_outer_attr", "clippy::equatable_if_let", "clippy::fallible_impl_from", "clippy::future_not_send", @@ -14319,7 +19175,10 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ LintGroup { lint: Lint { label: "clippy::pedantic", - description: r##"lint group for: clippy::assigning_clones, clippy::bool_to_int_with_if, clippy::borrow_as_ptr, clippy::case_sensitive_file_extension_comparisons, clippy::cast_lossless, clippy::cast_possible_truncation, clippy::cast_possible_wrap, clippy::cast_precision_loss, clippy::cast_ptr_alignment, clippy::cast_sign_loss, clippy::checked_conversions, clippy::cloned_instead_of_copied, clippy::copy_iterator, clippy::default_trait_access, clippy::doc_link_with_quotes, clippy::doc_markdown, clippy::empty_enum, clippy::enum_glob_use, clippy::expl_impl_clone_on_copy, clippy::explicit_deref_methods, clippy::explicit_into_iter_loop, clippy::explicit_iter_loop, clippy::filter_map_next, clippy::flat_map_option, clippy::float_cmp, clippy::fn_params_excessive_bools, clippy::from_iter_instead_of_collect, clippy::if_not_else, clippy::ignored_unit_patterns, clippy::implicit_clone, clippy::implicit_hasher, clippy::inconsistent_struct_constructor, clippy::index_refutable_slice, clippy::inefficient_to_string, clippy::inline_always, clippy::into_iter_without_iter, clippy::invalid_upcast_comparisons, clippy::items_after_statements, clippy::iter_filter_is_ok, clippy::iter_filter_is_some, clippy::iter_not_returning_iterator, clippy::iter_without_into_iter, clippy::large_digit_groups, clippy::large_futures, clippy::large_stack_arrays, clippy::large_types_passed_by_value, clippy::linkedlist, clippy::macro_use_imports, clippy::manual_assert, clippy::manual_c_str_literals, clippy::manual_instant_elapsed, clippy::manual_is_variant_and, clippy::manual_let_else, clippy::manual_ok_or, clippy::manual_string_new, clippy::many_single_char_names, clippy::map_unwrap_or, clippy::match_bool, clippy::match_on_vec_items, clippy::match_same_arms, clippy::match_wild_err_arm, clippy::match_wildcard_for_single_variants, clippy::maybe_infinite_iter, clippy::mismatching_type_param_order, clippy::missing_errors_doc, clippy::missing_fields_in_debug, clippy::missing_panics_doc, clippy::module_name_repetitions, clippy::must_use_candidate, clippy::mut_mut, clippy::naive_bytecount, clippy::needless_bitwise_bool, clippy::needless_continue, clippy::needless_for_each, clippy::needless_pass_by_value, clippy::needless_raw_string_hashes, clippy::no_effect_underscore_binding, clippy::no_mangle_with_rust_abi, clippy::option_as_ref_cloned, clippy::option_option, clippy::ptr_as_ptr, clippy::ptr_cast_constness, clippy::pub_underscore_fields, clippy::range_minus_one, clippy::range_plus_one, clippy::redundant_closure_for_method_calls, clippy::redundant_else, clippy::ref_as_ptr, clippy::ref_binding_to_reference, clippy::ref_option_ref, clippy::return_self_not_must_use, clippy::same_functions_in_if_condition, clippy::semicolon_if_nothing_returned, clippy::should_panic_without_expect, clippy::similar_names, clippy::single_char_pattern, clippy::single_match_else, clippy::stable_sort_primitive, clippy::str_split_at_newline, clippy::string_add_assign, clippy::struct_excessive_bools, clippy::struct_field_names, clippy::too_many_lines, clippy::transmute_ptr_to_ptr, clippy::trivially_copy_pass_by_ref, clippy::unchecked_duration_subtraction, clippy::unicode_not_nfc, clippy::uninlined_format_args, clippy::unnecessary_box_returns, clippy::unnecessary_join, clippy::unnecessary_wraps, clippy::unnested_or_patterns, clippy::unreadable_literal, clippy::unsafe_derive_deserialize, clippy::unused_async, clippy::unused_self, clippy::used_underscore_binding, clippy::verbose_bit_mask, clippy::wildcard_imports, clippy::zero_sized_map_values"##, + description: r##"lint group for: clippy::assigning_clones, clippy::bool_to_int_with_if, clippy::borrow_as_ptr, clippy::case_sensitive_file_extension_comparisons, clippy::cast_lossless, clippy::cast_possible_truncation, clippy::cast_possible_wrap, clippy::cast_precision_loss, clippy::cast_ptr_alignment, clippy::cast_sign_loss, clippy::checked_conversions, clippy::cloned_instead_of_copied, clippy::copy_iterator, clippy::default_trait_access, clippy::doc_link_with_quotes, clippy::doc_markdown, clippy::empty_enum, clippy::enum_glob_use, clippy::expl_impl_clone_on_copy, clippy::explicit_deref_methods, clippy::explicit_into_iter_loop, clippy::explicit_iter_loop, clippy::filter_map_next, clippy::flat_map_option, clippy::float_cmp, clippy::fn_params_excessive_bools, clippy::from_iter_instead_of_collect, clippy::if_not_else, clippy::ignored_unit_patterns, clippy::implicit_clone, clippy::implicit_hasher, clippy::inconsistent_struct_constructor, clippy::index_refutable_slice, clippy::inefficient_to_string, clippy::inline_always, clippy::into_iter_without_iter, clippy::invalid_upcast_comparisons, clippy::items_after_statements, clippy::iter_filter_is_ok, clippy::iter_filter_is_some, clippy::iter_not_returning_iterator, clippy::iter_without_into_iter, clippy::large_digit_groups, clippy::large_futures, clippy::large_stack_arrays, clippy::large_types_passed_by_value, clippy::linkedlist, clippy::macro_use_imports, clippy::manual_assert, clippy::manual_instant_elapsed, clippy::manual_is_variant_and, clippy::manual_let_else, clippy::manual_ok_or, clippy::manual_string_new, clippy::many_single_char_names, clippy::map_unwrap_or, clippy::match_bool, clippy::match_on_vec_items, clippy::match_same_arms, clippy::match_wild_err_arm, clippy::match_wildcard_for_single_variants, clippy::maybe_infinite_iter, clippy::mismatching_type_param_order, clippy::missing_errors_doc, clippy::missing_fields_in_debug, clippy::missing_panics_doc, clippy::module_name_repetitions, clippy::must_use_candidate, clippy::mut_mut, clippy::naive_bytecount, clippy::needless_bitwise_bool, clippy::needless_continue, clippy::needless_for_each, clippy::needless_pass_by_value, clippy::needless_raw_string_hashes, clippy::no_effect_underscore_binding, clippy::no_mangle_with_rust_abi, clippy::option_as_ref_cloned, clippy::option_option, clippy::ptr_as_ptr, clippy::ptr_cast_constness, clippy::pub_underscore_fields, clippy::range_minus_one, clippy::range_plus_one, clippy::redundant_closure_for_method_calls, clippy::redundant_else, clippy::ref_as_ptr, clippy::ref_binding_to_reference, clippy::ref_option, clippy::ref_option_ref, clippy::return_self_not_must_use, clippy::same_functions_in_if_condition, clippy::semicolon_if_nothing_returned, clippy::should_panic_without_expect, clippy::similar_names, clippy::single_char_pattern, clippy::single_match_else, clippy::stable_sort_primitive, clippy::str_split_at_newline, clippy::string_add_assign, clippy::struct_excessive_bools, clippy::struct_field_names, clippy::too_many_lines, clippy::transmute_ptr_to_ptr, clippy::trivially_copy_pass_by_ref, clippy::unchecked_duration_subtraction, clippy::unicode_not_nfc, clippy::uninlined_format_args, clippy::unnecessary_box_returns, clippy::unnecessary_join, clippy::unnecessary_wraps, clippy::unnested_or_patterns, clippy::unreadable_literal, clippy::unsafe_derive_deserialize, clippy::unused_async, clippy::unused_self, clippy::used_underscore_binding, clippy::used_underscore_items, clippy::verbose_bit_mask, clippy::wildcard_imports, clippy::zero_sized_map_values"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, children: &[ "clippy::assigning_clones", @@ -14371,7 +19230,6 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ "clippy::linkedlist", "clippy::macro_use_imports", "clippy::manual_assert", - "clippy::manual_c_str_literals", "clippy::manual_instant_elapsed", "clippy::manual_is_variant_and", "clippy::manual_let_else", @@ -14411,6 +19269,7 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ "clippy::redundant_else", "clippy::ref_as_ptr", "clippy::ref_binding_to_reference", + "clippy::ref_option", "clippy::ref_option_ref", "clippy::return_self_not_must_use", "clippy::same_functions_in_if_condition", @@ -14439,6 +19298,7 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ "clippy::unused_async", "clippy::unused_self", "clippy::used_underscore_binding", + "clippy::used_underscore_items", "clippy::verbose_bit_mask", "clippy::wildcard_imports", "clippy::zero_sized_map_values", @@ -14448,6 +19308,9 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ lint: Lint { label: "clippy::perf", description: r##"lint group for: clippy::box_collection, clippy::boxed_local, clippy::cmp_owned, clippy::collapsible_str_replace, clippy::drain_collect, clippy::expect_fun_call, clippy::extend_with_drain, clippy::format_collect, clippy::format_in_format_args, clippy::iter_overeager_cloned, clippy::large_const_arrays, clippy::large_enum_variant, clippy::manual_memcpy, clippy::manual_retain, clippy::manual_str_repeat, clippy::manual_try_fold, clippy::map_entry, clippy::missing_const_for_thread_local, clippy::missing_spin_loop, clippy::readonly_write_lock, clippy::redundant_allocation, clippy::result_large_err, clippy::slow_vector_initialization, clippy::to_string_in_format_args, clippy::unnecessary_to_owned, clippy::useless_vec, clippy::vec_init_then_push, clippy::waker_clone_wake"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, children: &[ "clippy::box_collection", @@ -14483,7 +19346,10 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ LintGroup { lint: Lint { label: "clippy::restriction", - description: r##"lint group for: clippy::absolute_paths, clippy::alloc_instead_of_core, clippy::allow_attributes, clippy::allow_attributes_without_reason, clippy::arithmetic_side_effects, clippy::as_conversions, clippy::as_underscore, clippy::assertions_on_result_states, clippy::big_endian_bytes, clippy::cfg_not_test, clippy::clone_on_ref_ptr, clippy::create_dir, clippy::dbg_macro, clippy::decimal_literal_representation, clippy::default_numeric_fallback, clippy::default_union_representation, clippy::deref_by_slicing, clippy::disallowed_script_idents, clippy::else_if_without_else, clippy::empty_drop, clippy::empty_enum_variants_with_brackets, clippy::empty_structs_with_brackets, clippy::error_impl_error, clippy::exhaustive_enums, clippy::exhaustive_structs, clippy::exit, clippy::expect_used, clippy::field_scoped_visibility_modifiers, clippy::filetype_is_file, clippy::float_arithmetic, clippy::float_cmp_const, clippy::fn_to_numeric_cast_any, clippy::format_push_string, clippy::get_unwrap, clippy::host_endian_bytes, clippy::if_then_some_else_none, clippy::impl_trait_in_params, clippy::implicit_return, clippy::indexing_slicing, clippy::infinite_loop, clippy::inline_asm_x86_att_syntax, clippy::inline_asm_x86_intel_syntax, clippy::integer_division, clippy::integer_division_remainder_used, clippy::iter_over_hash_type, clippy::large_include_file, clippy::let_underscore_must_use, clippy::let_underscore_untyped, clippy::little_endian_bytes, clippy::lossy_float_literal, clippy::map_err_ignore, clippy::mem_forget, clippy::min_ident_chars, clippy::missing_assert_message, clippy::missing_asserts_for_indexing, clippy::missing_docs_in_private_items, clippy::missing_inline_in_public_items, clippy::missing_trait_methods, clippy::mixed_read_write_in_expression, clippy::mod_module_files, clippy::modulo_arithmetic, clippy::multiple_inherent_impl, clippy::multiple_unsafe_ops_per_block, clippy::mutex_atomic, clippy::needless_raw_strings, clippy::non_ascii_literal, clippy::panic, clippy::panic_in_result_fn, clippy::partial_pub_fields, clippy::pathbuf_init_then_push, clippy::pattern_type_mismatch, clippy::print_stderr, clippy::print_stdout, clippy::pub_use, clippy::pub_with_shorthand, clippy::pub_without_shorthand, clippy::question_mark_used, clippy::rc_buffer, clippy::rc_mutex, clippy::redundant_type_annotations, clippy::ref_patterns, clippy::renamed_function_params, clippy::rest_pat_in_fully_bound_structs, clippy::same_name_method, clippy::self_named_module_files, clippy::semicolon_inside_block, clippy::semicolon_outside_block, clippy::separated_literal_suffix, clippy::shadow_reuse, clippy::shadow_same, clippy::shadow_unrelated, clippy::single_call_fn, clippy::single_char_lifetime_names, clippy::std_instead_of_alloc, clippy::std_instead_of_core, clippy::str_to_string, clippy::string_add, clippy::string_lit_chars_any, clippy::string_slice, clippy::string_to_string, clippy::suspicious_xor_used_as_pow, clippy::tests_outside_test_module, clippy::todo, clippy::try_err, clippy::undocumented_unsafe_blocks, clippy::unimplemented, clippy::unnecessary_safety_comment, clippy::unnecessary_safety_doc, clippy::unnecessary_self_imports, clippy::unneeded_field_pattern, clippy::unreachable, clippy::unseparated_literal_suffix, clippy::unwrap_in_result, clippy::unwrap_used, clippy::use_debug, clippy::verbose_file_reads, clippy::wildcard_enum_match_arm"##, + description: r##"lint group for: clippy::absolute_paths, clippy::alloc_instead_of_core, clippy::allow_attributes, clippy::allow_attributes_without_reason, clippy::arithmetic_side_effects, clippy::as_conversions, clippy::as_underscore, clippy::assertions_on_result_states, clippy::big_endian_bytes, clippy::cfg_not_test, clippy::clone_on_ref_ptr, clippy::create_dir, clippy::dbg_macro, clippy::decimal_literal_representation, clippy::default_numeric_fallback, clippy::default_union_representation, clippy::deref_by_slicing, clippy::disallowed_script_idents, clippy::else_if_without_else, clippy::empty_drop, clippy::empty_enum_variants_with_brackets, clippy::empty_structs_with_brackets, clippy::error_impl_error, clippy::exhaustive_enums, clippy::exhaustive_structs, clippy::exit, clippy::expect_used, clippy::field_scoped_visibility_modifiers, clippy::filetype_is_file, clippy::float_arithmetic, clippy::float_cmp_const, clippy::fn_to_numeric_cast_any, clippy::format_push_string, clippy::get_unwrap, clippy::host_endian_bytes, clippy::if_then_some_else_none, clippy::impl_trait_in_params, clippy::implicit_return, clippy::indexing_slicing, clippy::infinite_loop, clippy::inline_asm_x86_att_syntax, clippy::inline_asm_x86_intel_syntax, clippy::integer_division, clippy::integer_division_remainder_used, clippy::iter_over_hash_type, clippy::large_include_file, clippy::let_underscore_must_use, clippy::let_underscore_untyped, clippy::little_endian_bytes, clippy::lossy_float_literal, clippy::map_err_ignore, clippy::mem_forget, clippy::min_ident_chars, clippy::missing_assert_message, clippy::missing_asserts_for_indexing, clippy::missing_docs_in_private_items, clippy::missing_inline_in_public_items, clippy::missing_trait_methods, clippy::mixed_read_write_in_expression, clippy::mod_module_files, clippy::modulo_arithmetic, clippy::multiple_inherent_impl, clippy::multiple_unsafe_ops_per_block, clippy::mutex_atomic, clippy::needless_raw_strings, clippy::non_ascii_literal, clippy::non_zero_suggestions, clippy::panic, clippy::panic_in_result_fn, clippy::partial_pub_fields, clippy::pathbuf_init_then_push, clippy::pattern_type_mismatch, clippy::print_stderr, clippy::print_stdout, clippy::pub_use, clippy::pub_with_shorthand, clippy::pub_without_shorthand, clippy::question_mark_used, clippy::rc_buffer, clippy::rc_mutex, clippy::redundant_type_annotations, clippy::ref_patterns, clippy::renamed_function_params, clippy::rest_pat_in_fully_bound_structs, clippy::same_name_method, clippy::self_named_module_files, clippy::semicolon_inside_block, clippy::semicolon_outside_block, clippy::separated_literal_suffix, clippy::shadow_reuse, clippy::shadow_same, clippy::shadow_unrelated, clippy::single_call_fn, clippy::single_char_lifetime_names, clippy::std_instead_of_alloc, clippy::std_instead_of_core, clippy::str_to_string, clippy::string_add, clippy::string_lit_chars_any, clippy::string_slice, clippy::string_to_string, clippy::suspicious_xor_used_as_pow, clippy::tests_outside_test_module, clippy::todo, clippy::try_err, clippy::undocumented_unsafe_blocks, clippy::unimplemented, clippy::unnecessary_safety_comment, clippy::unnecessary_safety_doc, clippy::unnecessary_self_imports, clippy::unneeded_field_pattern, clippy::unreachable, clippy::unseparated_literal_suffix, clippy::unused_result_ok, clippy::unused_trait_names, clippy::unwrap_in_result, clippy::unwrap_used, clippy::use_debug, clippy::verbose_file_reads, clippy::wildcard_enum_match_arm"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, children: &[ "clippy::absolute_paths", @@ -14552,6 +19418,7 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ "clippy::mutex_atomic", "clippy::needless_raw_strings", "clippy::non_ascii_literal", + "clippy::non_zero_suggestions", "clippy::panic", "clippy::panic_in_result_fn", "clippy::partial_pub_fields", @@ -14598,6 +19465,8 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ "clippy::unneeded_field_pattern", "clippy::unreachable", "clippy::unseparated_literal_suffix", + "clippy::unused_result_ok", + "clippy::unused_trait_names", "clippy::unwrap_in_result", "clippy::unwrap_used", "clippy::use_debug", @@ -14608,7 +19477,10 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ LintGroup { lint: Lint { label: "clippy::style", - description: r##"lint group for: clippy::assertions_on_constants, clippy::assign_op_pattern, clippy::blocks_in_conditions, clippy::bool_assert_comparison, clippy::borrow_interior_mutable_const, clippy::box_default, clippy::builtin_type_shadow, clippy::byte_char_slices, clippy::bytes_nth, clippy::chars_last_cmp, clippy::chars_next_cmp, clippy::cmp_null, clippy::collapsible_else_if, clippy::collapsible_if, clippy::collapsible_match, clippy::comparison_chain, clippy::comparison_to_empty, clippy::declare_interior_mutable_const, clippy::default_instead_of_iter_empty, clippy::disallowed_macros, clippy::disallowed_methods, clippy::disallowed_names, clippy::disallowed_types, clippy::doc_lazy_continuation, clippy::double_must_use, clippy::double_neg, clippy::duplicate_underscore_argument, clippy::enum_variant_names, clippy::err_expect, clippy::excessive_precision, clippy::field_reassign_with_default, clippy::filter_map_bool_then, clippy::fn_to_numeric_cast, clippy::fn_to_numeric_cast_with_truncation, clippy::for_kv_map, clippy::from_over_into, clippy::from_str_radix_10, clippy::get_first, clippy::if_same_then_else, clippy::implicit_saturating_add, clippy::implicit_saturating_sub, clippy::inconsistent_digit_grouping, clippy::infallible_destructuring_match, clippy::inherent_to_string, clippy::init_numbered_fields, clippy::into_iter_on_ref, clippy::is_digit_ascii_radix, clippy::items_after_test_module, clippy::iter_cloned_collect, clippy::iter_next_slice, clippy::iter_nth, clippy::iter_nth_zero, clippy::iter_skip_next, clippy::just_underscores_and_digits, clippy::legacy_numeric_constants, clippy::len_without_is_empty, clippy::len_zero, clippy::let_and_return, clippy::let_unit_value, clippy::main_recursion, clippy::manual_async_fn, clippy::manual_bits, clippy::manual_is_ascii_check, clippy::manual_is_finite, clippy::manual_is_infinite, clippy::manual_map, clippy::manual_next_back, clippy::manual_non_exhaustive, clippy::manual_pattern_char_comparison, clippy::manual_range_contains, clippy::manual_rotate, clippy::manual_saturating_arithmetic, clippy::manual_while_let_some, clippy::map_clone, clippy::map_collect_result_unit, clippy::match_like_matches_macro, clippy::match_overlapping_arm, clippy::match_ref_pats, clippy::match_result_ok, clippy::mem_replace_option_with_none, clippy::mem_replace_with_default, clippy::missing_enforced_import_renames, clippy::missing_safety_doc, clippy::mixed_attributes_style, clippy::mixed_case_hex_literals, clippy::module_inception, clippy::must_use_unit, clippy::mut_mutex_lock, clippy::needless_borrow, clippy::needless_borrows_for_generic_args, clippy::needless_doctest_main, clippy::needless_else, clippy::needless_late_init, clippy::needless_parens_on_range_literals, clippy::needless_pub_self, clippy::needless_range_loop, clippy::needless_return, clippy::needless_return_with_question_mark, clippy::neg_multiply, clippy::new_ret_no_self, clippy::new_without_default, clippy::non_minimal_cfg, clippy::obfuscated_if_else, clippy::ok_expect, clippy::op_ref, clippy::option_map_or_err_ok, clippy::option_map_or_none, clippy::partialeq_to_none, clippy::print_literal, clippy::print_with_newline, clippy::println_empty_string, clippy::ptr_arg, clippy::ptr_eq, clippy::question_mark, clippy::redundant_closure, clippy::redundant_field_names, clippy::redundant_pattern, clippy::redundant_pattern_matching, clippy::redundant_static_lifetimes, clippy::result_map_or_into_option, clippy::result_unit_err, clippy::same_item_push, clippy::self_named_constructors, clippy::should_implement_trait, clippy::single_char_add_str, clippy::single_component_path_imports, clippy::single_match, clippy::string_extend_chars, clippy::tabs_in_doc_comments, clippy::to_digit_is_some, clippy::to_string_trait_impl, clippy::toplevel_ref_arg, clippy::trim_split_whitespace, clippy::unnecessary_fallible_conversions, clippy::unnecessary_fold, clippy::unnecessary_lazy_evaluations, clippy::unnecessary_mut_passed, clippy::unnecessary_owned_empty_strings, clippy::unsafe_removed_from_name, clippy::unused_enumerate_index, clippy::unused_unit, clippy::unusual_byte_groupings, clippy::unwrap_or_default, clippy::upper_case_acronyms, clippy::while_let_on_iterator, clippy::write_literal, clippy::write_with_newline, clippy::writeln_empty_string, clippy::wrong_self_convention, clippy::zero_ptr"##, + description: r##"lint group for: clippy::assertions_on_constants, clippy::assign_op_pattern, clippy::blocks_in_conditions, clippy::bool_assert_comparison, clippy::borrow_interior_mutable_const, clippy::box_default, clippy::builtin_type_shadow, clippy::byte_char_slices, clippy::bytes_nth, clippy::chars_last_cmp, clippy::chars_next_cmp, clippy::cmp_null, clippy::collapsible_else_if, clippy::collapsible_if, clippy::collapsible_match, clippy::comparison_chain, clippy::comparison_to_empty, clippy::declare_interior_mutable_const, clippy::default_instead_of_iter_empty, clippy::disallowed_macros, clippy::disallowed_methods, clippy::disallowed_names, clippy::disallowed_types, clippy::doc_lazy_continuation, clippy::double_must_use, clippy::double_neg, clippy::duplicate_underscore_argument, clippy::enum_variant_names, clippy::err_expect, clippy::excessive_precision, clippy::field_reassign_with_default, clippy::filter_map_bool_then, clippy::fn_to_numeric_cast, clippy::fn_to_numeric_cast_with_truncation, clippy::for_kv_map, clippy::from_over_into, clippy::from_str_radix_10, clippy::get_first, clippy::if_same_then_else, clippy::implicit_saturating_add, clippy::implicit_saturating_sub, clippy::inconsistent_digit_grouping, clippy::infallible_destructuring_match, clippy::inherent_to_string, clippy::init_numbered_fields, clippy::into_iter_on_ref, clippy::is_digit_ascii_radix, clippy::items_after_test_module, clippy::iter_cloned_collect, clippy::iter_next_slice, clippy::iter_nth, clippy::iter_nth_zero, clippy::iter_skip_next, clippy::just_underscores_and_digits, clippy::legacy_numeric_constants, clippy::len_without_is_empty, clippy::len_zero, clippy::let_and_return, clippy::let_unit_value, clippy::main_recursion, clippy::manual_async_fn, clippy::manual_bits, clippy::manual_is_ascii_check, clippy::manual_is_finite, clippy::manual_is_infinite, clippy::manual_map, clippy::manual_next_back, clippy::manual_non_exhaustive, clippy::manual_pattern_char_comparison, clippy::manual_range_contains, clippy::manual_rotate, clippy::manual_saturating_arithmetic, clippy::manual_while_let_some, clippy::map_clone, clippy::map_collect_result_unit, clippy::match_like_matches_macro, clippy::match_overlapping_arm, clippy::match_ref_pats, clippy::match_result_ok, clippy::mem_replace_option_with_none, clippy::mem_replace_with_default, clippy::missing_enforced_import_renames, clippy::missing_safety_doc, clippy::mixed_attributes_style, clippy::mixed_case_hex_literals, clippy::module_inception, clippy::must_use_unit, clippy::mut_mutex_lock, clippy::needless_borrow, clippy::needless_borrows_for_generic_args, clippy::needless_doctest_main, clippy::needless_else, clippy::needless_late_init, clippy::needless_parens_on_range_literals, clippy::needless_pub_self, clippy::needless_range_loop, clippy::needless_return, clippy::needless_return_with_question_mark, clippy::neg_multiply, clippy::new_ret_no_self, clippy::new_without_default, clippy::non_minimal_cfg, clippy::obfuscated_if_else, clippy::ok_expect, clippy::op_ref, clippy::option_map_or_err_ok, clippy::option_map_or_none, clippy::partialeq_to_none, clippy::print_literal, clippy::print_with_newline, clippy::println_empty_string, clippy::ptr_arg, clippy::ptr_eq, clippy::question_mark, clippy::redundant_closure, clippy::redundant_field_names, clippy::redundant_pattern, clippy::redundant_pattern_matching, clippy::redundant_static_lifetimes, clippy::result_map_or_into_option, clippy::result_unit_err, clippy::same_item_push, clippy::self_named_constructors, clippy::should_implement_trait, clippy::single_char_add_str, clippy::single_component_path_imports, clippy::single_match, clippy::string_extend_chars, clippy::tabs_in_doc_comments, clippy::to_digit_is_some, clippy::to_string_trait_impl, clippy::too_long_first_doc_paragraph, clippy::toplevel_ref_arg, clippy::trim_split_whitespace, clippy::unnecessary_fallible_conversions, clippy::unnecessary_fold, clippy::unnecessary_lazy_evaluations, clippy::unnecessary_mut_passed, clippy::unnecessary_owned_empty_strings, clippy::unsafe_removed_from_name, clippy::unused_enumerate_index, clippy::unused_unit, clippy::unusual_byte_groupings, clippy::unwrap_or_default, clippy::upper_case_acronyms, clippy::while_let_on_iterator, clippy::write_literal, clippy::write_with_newline, clippy::writeln_empty_string, clippy::wrong_self_convention, clippy::zero_ptr"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, children: &[ "clippy::assertions_on_constants", @@ -14742,6 +19614,7 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ "clippy::tabs_in_doc_comments", "clippy::to_digit_is_some", "clippy::to_string_trait_impl", + "clippy::too_long_first_doc_paragraph", "clippy::toplevel_ref_arg", "clippy::trim_split_whitespace", "clippy::unnecessary_fallible_conversions", @@ -14766,7 +19639,10 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ LintGroup { lint: Lint { label: "clippy::suspicious", - description: r##"lint group for: clippy::almost_complete_range, clippy::arc_with_non_send_sync, clippy::await_holding_invalid_type, clippy::await_holding_lock, clippy::await_holding_refcell_ref, clippy::blanket_clippy_restriction_lints, clippy::cast_abs_to_unsigned, clippy::cast_enum_constructor, clippy::cast_enum_truncation, clippy::cast_nan_to_int, clippy::cast_slice_from_raw_parts, clippy::const_is_empty, clippy::crate_in_macro_def, clippy::deprecated_clippy_cfg_attr, clippy::drop_non_drop, clippy::duplicate_mod, clippy::duplicated_attributes, clippy::empty_docs, clippy::empty_loop, clippy::float_equality_without_abs, clippy::forget_non_drop, clippy::four_forward_slashes, clippy::from_raw_with_void_ptr, clippy::incompatible_msrv, clippy::ineffective_open_options, clippy::iter_out_of_bounds, clippy::join_absolute_paths, clippy::let_underscore_future, clippy::lines_filter_map_ok, clippy::macro_metavars_in_unsafe, clippy::manual_unwrap_or_default, clippy::misnamed_getters, clippy::misrefactored_assign_op, clippy::missing_transmute_annotations, clippy::multi_assignments, clippy::multiple_bound_locations, clippy::mut_range_bound, clippy::mutable_key_type, clippy::needless_character_iteration, clippy::needless_maybe_sized, clippy::no_effect_replace, clippy::non_canonical_clone_impl, clippy::non_canonical_partial_ord_impl, clippy::octal_escapes, clippy::path_ends_with_ext, clippy::permissions_set_readonly_false, clippy::print_in_format_impl, clippy::rc_clone_in_vec_init, clippy::repeat_vec_with_capacity, clippy::single_range_in_vec_init, clippy::size_of_ref, clippy::suspicious_arithmetic_impl, clippy::suspicious_assignment_formatting, clippy::suspicious_command_arg_space, clippy::suspicious_doc_comments, clippy::suspicious_else_formatting, clippy::suspicious_map, clippy::suspicious_op_assign_impl, clippy::suspicious_open_options, clippy::suspicious_to_owned, clippy::suspicious_unary_op_formatting, clippy::swap_ptr_to_ref, clippy::test_attr_in_doctest, clippy::type_id_on_box, clippy::unconditional_recursion, clippy::unnecessary_clippy_cfg, clippy::unnecessary_get_then_check, clippy::unnecessary_result_map_or_else, clippy::zero_repeat_side_effects"##, + description: r##"lint group for: clippy::almost_complete_range, clippy::arc_with_non_send_sync, clippy::await_holding_invalid_type, clippy::await_holding_lock, clippy::await_holding_refcell_ref, clippy::blanket_clippy_restriction_lints, clippy::cast_abs_to_unsigned, clippy::cast_enum_constructor, clippy::cast_enum_truncation, clippy::cast_nan_to_int, clippy::cast_slice_from_raw_parts, clippy::const_is_empty, clippy::crate_in_macro_def, clippy::deprecated_clippy_cfg_attr, clippy::drop_non_drop, clippy::duplicate_mod, clippy::duplicated_attributes, clippy::empty_docs, clippy::empty_line_after_doc_comments, clippy::empty_line_after_outer_attr, clippy::empty_loop, clippy::float_equality_without_abs, clippy::forget_non_drop, clippy::four_forward_slashes, clippy::from_raw_with_void_ptr, clippy::incompatible_msrv, clippy::ineffective_open_options, clippy::iter_out_of_bounds, clippy::join_absolute_paths, clippy::let_underscore_future, clippy::lines_filter_map_ok, clippy::macro_metavars_in_unsafe, clippy::manual_unwrap_or_default, clippy::misnamed_getters, clippy::misrefactored_assign_op, clippy::missing_transmute_annotations, clippy::multi_assignments, clippy::multiple_bound_locations, clippy::mut_range_bound, clippy::mutable_key_type, clippy::needless_character_iteration, clippy::needless_maybe_sized, clippy::no_effect_replace, clippy::non_canonical_clone_impl, clippy::non_canonical_partial_ord_impl, clippy::octal_escapes, clippy::path_ends_with_ext, clippy::permissions_set_readonly_false, clippy::pointers_in_nomem_asm_block, clippy::print_in_format_impl, clippy::rc_clone_in_vec_init, clippy::repeat_vec_with_capacity, clippy::single_range_in_vec_init, clippy::size_of_ref, clippy::suspicious_arithmetic_impl, clippy::suspicious_assignment_formatting, clippy::suspicious_command_arg_space, clippy::suspicious_doc_comments, clippy::suspicious_else_formatting, clippy::suspicious_map, clippy::suspicious_op_assign_impl, clippy::suspicious_open_options, clippy::suspicious_to_owned, clippy::suspicious_unary_op_formatting, clippy::swap_ptr_to_ref, clippy::test_attr_in_doctest, clippy::type_id_on_box, clippy::unconditional_recursion, clippy::unnecessary_clippy_cfg, clippy::unnecessary_get_then_check, clippy::unnecessary_result_map_or_else, clippy::zero_repeat_side_effects, clippy::zombie_processes"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, children: &[ "clippy::almost_complete_range", @@ -14787,6 +19663,8 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ "clippy::duplicate_mod", "clippy::duplicated_attributes", "clippy::empty_docs", + "clippy::empty_line_after_doc_comments", + "clippy::empty_line_after_outer_attr", "clippy::empty_loop", "clippy::float_equality_without_abs", "clippy::forget_non_drop", @@ -14815,6 +19693,7 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ "clippy::octal_escapes", "clippy::path_ends_with_ext", "clippy::permissions_set_readonly_false", + "clippy::pointers_in_nomem_asm_block", "clippy::print_in_format_impl", "clippy::rc_clone_in_vec_init", "clippy::repeat_vec_with_capacity", @@ -14838,6 +19717,7 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ "clippy::unnecessary_get_then_check", "clippy::unnecessary_result_map_or_else", "clippy::zero_repeat_side_effects", + "clippy::zombie_processes", ], }, ]; diff --git a/src/tools/rust-analyzer/crates/ide-db/src/lib.rs b/src/tools/rust-analyzer/crates/ide-db/src/lib.rs index 81260c3e080..1f77ea1ec66 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/lib.rs @@ -327,3 +327,11 @@ impl<'a> Ranker<'a> { | ((no_tt_parent as usize) << 3) } } + +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum Severity { + Error, + Warning, + WeakWarning, + Allow, +} diff --git a/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs b/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs index a508f2fedd6..156f21b784e 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs @@ -184,7 +184,7 @@ impl<'a> PathTransform<'a> { if let Some(expr) = v.expr() { // FIXME: expressions in curly brackets can cause ambiguity after insertion // (e.g. `N * 2` -> `{1 + 1} * 2`; it's unclear whether `{1 + 1}` - // is a standalone statement or a part of another expresson) + // is a standalone statement or a part of another expression) // and sometimes require slight modifications; see // https://doc.rust-lang.org/reference/statements.html#expression-statements // (default values in curly brackets can cause the same problem) diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs index 4bd29b8c79b..c7cdcf49820 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs @@ -59,7 +59,7 @@ pub(crate) fn invalid_cast(ctx: &DiagnosticsContext<'_>, d: &hir::InvalidCast) - DiagnosticCode::RustcHardError("E0606"), format_ty!( ctx, - "casting `{}` as `{}` is invalid: needs defererence or removal of unneeded borrow", + "casting `{}` as `{}` is invalid: needs dereference or removal of unneeded borrow", d.expr_ty, d.cast_ty ), diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs index 2bfdda35659..dc3dee5c9ce 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs @@ -586,14 +586,47 @@ fn main() { } #[test] - fn unsafe_op_in_unsafe_fn_allowed_by_default() { + fn unsafe_op_in_unsafe_fn_allowed_by_default_in_edition_2021() { check_diagnostics( r#" +//- /lib.rs crate:foo edition:2021 unsafe fn foo(p: *mut i32) { *p = 123; } "#, - ) + ); + check_diagnostics( + r#" +//- /lib.rs crate:foo edition:2021 +#![deny(warnings)] +unsafe fn foo(p: *mut i32) { + *p = 123; +} + "#, + ); + } + + #[test] + fn unsafe_op_in_unsafe_fn_warn_by_default_in_edition_2024() { + check_diagnostics( + r#" +//- /lib.rs crate:foo edition:2024 +unsafe fn foo(p: *mut i32) { + *p = 123; + //^^💡 warn: dereference of raw pointer is unsafe and requires an unsafe function or block +} + "#, + ); + check_diagnostics( + r#" +//- /lib.rs crate:foo edition:2024 +#![deny(warnings)] +unsafe fn foo(p: *mut i32) { + *p = 123; + //^^💡 error: dereference of raw pointer is unsafe and requires an unsafe function or block +} + "#, + ); } #[test] diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs index ad339569081..1e99d7ad6e6 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs @@ -84,12 +84,12 @@ use hir::{db::ExpandDatabase, diagnostics::AnyDiagnostic, Crate, HirFileId, InFi use ide_db::{ assists::{Assist, AssistId, AssistKind, AssistResolveStrategy}, base_db::SourceDatabase, - generated::lints::{LintGroup, CLIPPY_LINT_GROUPS, DEFAULT_LINT_GROUPS}, + generated::lints::{Lint, LintGroup, CLIPPY_LINT_GROUPS, DEFAULT_LINTS, DEFAULT_LINT_GROUPS}, imports::insert_use::InsertUseConfig, label::Label, source_change::SourceChange, syntax_helpers::node_ext::parse_tt_as_comma_sep_paths, - EditionedFileId, FileId, FileRange, FxHashMap, FxHashSet, RootDatabase, SnippetCap, + EditionedFileId, FileId, FileRange, FxHashMap, FxHashSet, RootDatabase, Severity, SnippetCap, }; use itertools::Itertools; use syntax::{ @@ -210,14 +210,6 @@ impl Diagnostic { } } -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub enum Severity { - Error, - Warning, - WeakWarning, - Allow, -} - #[derive(Clone, Debug, PartialEq, Eq)] pub enum ExprFillDefaultMode { Todo, @@ -568,26 +560,35 @@ fn handle_diag_from_macros( // `__RA_EVERY_LINT` is a fake lint group to allow every lint in proc macros -static RUSTC_LINT_GROUPS_DICT: LazyLock<FxHashMap<&str, Vec<&str>>> = - LazyLock::new(|| build_group_dict(DEFAULT_LINT_GROUPS, &["warnings", "__RA_EVERY_LINT"], "")); +struct BuiltLint { + lint: &'static Lint, + groups: Vec<&'static str>, +} -static CLIPPY_LINT_GROUPS_DICT: LazyLock<FxHashMap<&str, Vec<&str>>> = - LazyLock::new(|| build_group_dict(CLIPPY_LINT_GROUPS, &["__RA_EVERY_LINT"], "clippy::")); +static RUSTC_LINTS: LazyLock<FxHashMap<&str, BuiltLint>> = + LazyLock::new(|| build_lints_map(DEFAULT_LINTS, DEFAULT_LINT_GROUPS, "")); + +static CLIPPY_LINTS: LazyLock<FxHashMap<&str, BuiltLint>> = LazyLock::new(|| { + build_lints_map(ide_db::generated::lints::CLIPPY_LINTS, CLIPPY_LINT_GROUPS, "clippy::") +}); // FIXME: Autogenerate this instead of enumerating by hand. static LINTS_TO_REPORT_IN_EXTERNAL_MACROS: LazyLock<FxHashSet<&str>> = LazyLock::new(|| FxHashSet::from_iter([])); -fn build_group_dict( +fn build_lints_map( + lints: &'static [Lint], lint_group: &'static [LintGroup], - all_groups: &'static [&'static str], prefix: &'static str, -) -> FxHashMap<&'static str, Vec<&'static str>> { - let mut map_with_prefixes: FxHashMap<&str, Vec<&str>> = FxHashMap::default(); +) -> FxHashMap<&'static str, BuiltLint> { + let mut map_with_prefixes: FxHashMap<_, _> = lints + .iter() + .map(|lint| (lint.label, BuiltLint { lint, groups: vec![lint.label, "__RA_EVERY_LINT"] })) + .collect(); for g in lint_group { let mut add_children = |label: &'static str| { for child in g.children { - map_with_prefixes.entry(child).or_default().push(label); + map_with_prefixes.get_mut(child).unwrap().groups.push(label); } }; add_children(g.lint.label); @@ -597,18 +598,9 @@ fn build_group_dict( add_children("bad_style"); } } - for (lint, groups) in map_with_prefixes.iter_mut() { - groups.push(lint); - groups.extend_from_slice(all_groups); - } map_with_prefixes.into_iter().map(|(k, v)| (k.strip_prefix(prefix).unwrap(), v)).collect() } -/// Thd default severity for lints that are not warn by default. -// FIXME: Autogenerate this instead of write manually. -static LINTS_DEFAULT_SEVERITY: LazyLock<FxHashMap<&str, Severity>> = - LazyLock::new(|| FxHashMap::from_iter([("unsafe_op_in_unsafe_fn", Severity::Allow)])); - fn handle_lints( sema: &Semantics<'_, RootDatabase>, cache: &mut FxHashMap<HirFileId, FxHashMap<SmolStr, SeverityAttr>>, @@ -618,10 +610,12 @@ fn handle_lints( ) { for (node, diag) in diagnostics { let lint = match diag.code { - DiagnosticCode::RustcLint(lint) | DiagnosticCode::Clippy(lint) => lint, + DiagnosticCode::RustcLint(lint) => RUSTC_LINTS[lint].lint, + DiagnosticCode::Clippy(lint) => CLIPPY_LINTS[lint].lint, _ => panic!("non-lint passed to `handle_lints()`"), }; - if let Some(&default_severity) = LINTS_DEFAULT_SEVERITY.get(lint) { + let default_severity = default_lint_severity(lint, edition); + if !(default_severity == Severity::Allow && diag.severity == Severity::WeakWarning) { diag.severity = default_severity; } @@ -639,6 +633,16 @@ fn handle_lints( } } +fn default_lint_severity(lint: &Lint, edition: Edition) -> Severity { + if lint.deny_since.is_some_and(|e| edition >= e) { + Severity::Error + } else if lint.warn_since.is_some_and(|e| edition >= e) { + Severity::Warning + } else { + lint.default_severity + } +} + fn find_outline_mod_lint_severity( sema: &Semantics<'_, RootDatabase>, node: &InFile<SyntaxNode>, @@ -654,14 +658,14 @@ fn find_outline_mod_lint_severity( let mod_def = sema.to_module_def(&mod_node)?; let module_source_file = sema.module_definition_node(mod_def); let mut result = None; - let lint_groups = lint_groups(&diag.code); + let lint_groups = lint_groups(&diag.code, edition); lint_attrs( sema, ast::AnyHasAttrs::cast(module_source_file.value).expect("SourceFile always has attrs"), edition, ) .for_each(|(lint, severity)| { - if lint_groups.contains(&&*lint) { + if lint_groups.contains(&lint) { result = Some(severity); } }); @@ -737,9 +741,9 @@ fn fill_lint_attrs( } }); - let all_matching_groups = lint_groups(&diag.code) + let all_matching_groups = lint_groups(&diag.code, edition) .iter() - .filter_map(|lint_group| cached.get(&**lint_group)); + .filter_map(|lint_group| cached.get(lint_group)); let cached_severity = all_matching_groups.min_by_key(|it| it.depth).map(|it| it.severity); @@ -751,7 +755,7 @@ fn fill_lint_attrs( // Insert this node's descendants' attributes into any outline descendant, but not including this node. // This must come before inserting this node's own attributes to preserve order. collected_lint_attrs.drain().for_each(|(lint, severity)| { - if diag_severity.is_none() && lint_groups(&diag.code).contains(&&*lint) { + if diag_severity.is_none() && lint_groups(&diag.code, edition).contains(&lint) { diag_severity = Some(severity.severity); } @@ -774,7 +778,7 @@ fn fill_lint_attrs( if let Some(ancestor) = ast::AnyHasAttrs::cast(ancestor) { // Insert this node's attributes into any outline descendant, including this node. lint_attrs(sema, ancestor, edition).for_each(|(lint, severity)| { - if diag_severity.is_none() && lint_groups(&diag.code).contains(&&*lint) { + if diag_severity.is_none() && lint_groups(&diag.code, edition).contains(&lint) { diag_severity = Some(severity); } @@ -804,7 +808,7 @@ fn fill_lint_attrs( return diag_severity; } else if let Some(ancestor) = ast::AnyHasAttrs::cast(ancestor) { lint_attrs(sema, ancestor, edition).for_each(|(lint, severity)| { - if diag_severity.is_none() && lint_groups(&diag.code).contains(&&*lint) { + if diag_severity.is_none() && lint_groups(&diag.code, edition).contains(&lint) { diag_severity = Some(severity); } @@ -905,16 +909,37 @@ fn cfg_attr_lint_attrs( } } -fn lint_groups(lint: &DiagnosticCode) -> &'static [&'static str] { - match lint { +#[derive(Debug)] +struct LintGroups { + groups: &'static [&'static str], + inside_warnings: bool, +} + +impl LintGroups { + fn contains(&self, group: &str) -> bool { + self.groups.contains(&group) || (self.inside_warnings && group == "warnings") + } + + fn iter(&self) -> impl Iterator<Item = &'static str> { + self.groups.iter().copied().chain(self.inside_warnings.then_some("warnings")) + } +} + +fn lint_groups(lint: &DiagnosticCode, edition: Edition) -> LintGroups { + let (groups, inside_warnings) = match lint { DiagnosticCode::RustcLint(name) => { - RUSTC_LINT_GROUPS_DICT.get(name).map(|it| &**it).unwrap_or_default() + let lint = &RUSTC_LINTS[name]; + let inside_warnings = default_lint_severity(lint.lint, edition) == Severity::Warning; + (&lint.groups, inside_warnings) } DiagnosticCode::Clippy(name) => { - CLIPPY_LINT_GROUPS_DICT.get(name).map(|it| &**it).unwrap_or_default() + let lint = &CLIPPY_LINTS[name]; + let inside_warnings = default_lint_severity(lint.lint, edition) == Severity::Warning; + (&lint.groups, inside_warnings) } - _ => &[], - } + _ => panic!("non-lint passed to `handle_lints()`"), + }; + LintGroups { groups, inside_warnings } } fn fix(id: &'static str, label: &str, source_change: SourceChange, target: TextRange) -> Assist { diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs index eaca95d98c2..6b654f89345 100644 --- a/src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs @@ -286,7 +286,7 @@ impl<'db> MatchFinder<'db> { }); } } else if let Some(macro_call) = ast::MacroCall::cast(node.clone()) { - if let Some(expanded) = self.sema.expand(¯o_call) { + if let Some(expanded) = self.sema.expand_macro_call(¯o_call) { if let Some(tt) = macro_call.token_tree() { self.output_debug_for_nodes_at_range( &expanded, diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/search.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/search.rs index 241de10b44d..b1cade39266 100644 --- a/src/tools/rust-analyzer/crates/ide-ssr/src/search.rs +++ b/src/tools/rust-analyzer/crates/ide-ssr/src/search.rs @@ -189,7 +189,7 @@ impl MatchFinder<'_> { // If we've got a macro call, we already tried matching it pre-expansion, which is the only // way to match the whole macro, now try expanding it and matching the expansion. if let Some(macro_call) = ast::MacroCall::cast(code.clone()) { - if let Some(expanded) = self.sema.expand(¯o_call) { + if let Some(expanded) = self.sema.expand_macro_call(¯o_call) { if let Some(tt) = macro_call.token_tree() { // When matching within a macro expansion, we only want to allow matches of // nodes that originated entirely from within the token tree of the macro call. diff --git a/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs b/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs index 79fdf75b7f7..10a73edd51c 100644 --- a/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs +++ b/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs @@ -1,10 +1,11 @@ use hir::db::ExpandDatabase; -use hir::{InFile, MacroFileIdExt, Semantics}; +use hir::{ExpandResult, InFile, MacroFileIdExt, Semantics}; use ide_db::base_db::CrateId; use ide_db::{ helpers::pick_best_token, syntax_helpers::prettify_macro_expansion, FileId, RootDatabase, }; use span::{Edition, SpanMap, SyntaxContextId, TextRange, TextSize}; +use stdx::format_to; use syntax::{ast, ted, AstNode, NodeOrToken, SyntaxKind, SyntaxNode, T}; use crate::FilePosition; @@ -63,10 +64,10 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option< .take_while(|it| it != &token) .filter(|it| it.kind() == T![,]) .count(); - let expansion = expansions.get(idx)?.clone(); + let ExpandResult { err, value: expansion } = expansions.get(idx)?.clone(); let expansion_file_id = sema.hir_file_for(&expansion).macro_file()?; let expansion_span_map = db.expansion_span_map(expansion_file_id); - let expansion = format( + let mut expansion = format( db, SyntaxKind::MACRO_ITEMS, position.file_id, @@ -74,6 +75,12 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option< &expansion_span_map, krate, ); + if let Some(err) = err { + expansion.insert_str( + 0, + &format!("Expansion had errors: {}\n\n", err.render_to_string(sema.db)), + ); + } Some(ExpandedMacro { name, expansion }) }); @@ -83,6 +90,7 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option< let mut anc = tok.parent_ancestors(); let mut span_map = SpanMap::empty(); + let mut error = String::new(); let (name, expanded, kind) = loop { let node = anc.next()?; @@ -97,7 +105,7 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option< .unwrap_or(Edition::CURRENT), ) .to_string(), - expand_macro_recur(&sema, &item, &mut span_map, TextSize::new(0))?, + expand_macro_recur(&sema, &item, &mut error, &mut span_map, TextSize::new(0))?, SyntaxKind::MACRO_ITEMS, ); } @@ -112,6 +120,7 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option< expand_macro_recur( &sema, &ast::Item::MacroCall(mac), + &mut error, &mut span_map, TextSize::new(0), )?, @@ -123,24 +132,31 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option< // FIXME: // macro expansion may lose all white space information // But we hope someday we can use ra_fmt for that - let expansion = format(db, kind, position.file_id, expanded, &span_map, krate); + let mut expansion = format(db, kind, position.file_id, expanded, &span_map, krate); + if !error.is_empty() { + expansion.insert_str(0, &format!("Expansion had errors:{error}\n\n")); + } Some(ExpandedMacro { name, expansion }) } fn expand_macro_recur( sema: &Semantics<'_, RootDatabase>, macro_call: &ast::Item, + error: &mut String, result_span_map: &mut SpanMap<SyntaxContextId>, offset_in_original_node: TextSize, ) -> Option<SyntaxNode> { - let expanded = match macro_call { - item @ ast::Item::MacroCall(macro_call) => sema - .expand_attr_macro(item) - .or_else(|| sema.expand_allowed_builtins(macro_call))? - .clone_for_update(), - item => sema.expand_attr_macro(item)?.clone_for_update(), + let ExpandResult { value: expanded, err } = match macro_call { + item @ ast::Item::MacroCall(macro_call) => { + sema.expand_attr_macro(item).or_else(|| sema.expand_allowed_builtins(macro_call))? + } + item => sema.expand_attr_macro(item)?, }; + let expanded = expanded.clone_for_update(); + if let Some(err) = err { + format_to!(error, "\n{}", err.render_to_string(sema.db)); + } let file_id = sema.hir_file_for(&expanded).macro_file().expect("expansion must produce a macro file"); let expansion_span_map = sema.db.expansion_span_map(file_id); @@ -149,12 +165,13 @@ fn expand_macro_recur( expanded.text_range().len(), &expansion_span_map, ); - Some(expand(sema, expanded, result_span_map, u32::from(offset_in_original_node) as i32)) + Some(expand(sema, expanded, error, result_span_map, u32::from(offset_in_original_node) as i32)) } fn expand( sema: &Semantics<'_, RootDatabase>, expanded: SyntaxNode, + error: &mut String, result_span_map: &mut SpanMap<SyntaxContextId>, mut offset_in_original_node: i32, ) -> SyntaxNode { @@ -165,6 +182,7 @@ fn expand( if let Some(new_node) = expand_macro_recur( sema, &child, + error, result_span_map, TextSize::new( (offset_in_original_node + (u32::from(child.syntax().text_range().start()) as i32)) @@ -495,6 +513,9 @@ fn main() { "#, expect![[r#" foo! + Expansion had errors: + expected ident: `BAD` + "#]], ); } diff --git a/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs b/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs index fc29ba06dad..4690416e059 100644 --- a/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs +++ b/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs @@ -608,7 +608,7 @@ impl<'a> WalkExpandedExprCtx<'a> { if let ast::Expr::MacroExpr(expr) = expr { if let Some(expanded) = - expr.macro_call().and_then(|call| self.sema.expand(&call)) + expr.macro_call().and_then(|call| self.sema.expand_macro_call(&call)) { match_ast! { match expanded { diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs index 5a00d635698..e617d462ecd 100644 --- a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs +++ b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs @@ -1,5 +1,5 @@ //! Logic for rendering the different hover messages -use std::{mem, ops::Not}; +use std::{env, mem, ops::Not}; use either::Either; use hir::{ @@ -28,6 +28,7 @@ use syntax::{algo, ast, match_ast, AstNode, AstToken, Direction, SyntaxToken, T} use crate::{ doc_links::{remove_links, rewrite_links}, hover::{notable_traits, walk_and_push_ty}, + interpret::render_const_eval_error, HoverAction, HoverConfig, HoverResult, Markup, MemoryLayoutHoverConfig, MemoryLayoutHoverRenderKind, }; @@ -464,41 +465,77 @@ pub(super) fn definition( Ok(it) => { Some(if it >= 10 { format!("{it} ({it:#X})") } else { format!("{it}") }) } - Err(_) => it.value(db).map(|it| format!("{it:?}")), + Err(err) => { + let res = it.value(db).map(|it| format!("{it:?}")); + if env::var_os("RA_DEV").is_some() { + let res = res.as_deref().unwrap_or(""); + Some(format!("{res} ({})", render_const_eval_error(db, err, edition))) + } else { + res + } + } } } else { None } } Definition::Const(it) => { - let body = it.render_eval(db, edition); - match body { - Ok(it) => Some(it), - Err(_) => { + let body = it.eval(db); + Some(match body { + Ok(it) => match it.render_debug(db) { + Ok(it) => it, + Err(err) => { + let it = it.render(db, edition); + if env::var_os("RA_DEV").is_some() { + format!("{it}\n{}", render_const_eval_error(db, err.into(), edition)) + } else { + it + } + } + }, + Err(err) => { let source = it.source(db)?; let mut body = source.value.body()?.syntax().clone(); if let Some(macro_file) = source.file_id.macro_file() { let span_map = db.expansion_span_map(macro_file); body = prettify_macro_expansion(db, body, &span_map, it.krate(db).into()); } - Some(body.to_string()) + if env::var_os("RA_DEV").is_some() { + format!("{body}\n{}", render_const_eval_error(db, err, edition)) + } else { + body.to_string() + } } - } + }) } Definition::Static(it) => { - let body = it.render_eval(db, edition); - match body { - Ok(it) => Some(it), - Err(_) => { + let body = it.eval(db); + Some(match body { + Ok(it) => match it.render_debug(db) { + Ok(it) => it, + Err(err) => { + let it = it.render(db, edition); + if env::var_os("RA_DEV").is_some() { + format!("{it}\n{}", render_const_eval_error(db, err.into(), edition)) + } else { + it + } + } + }, + Err(err) => { let source = it.source(db)?; let mut body = source.value.body()?.syntax().clone(); if let Some(macro_file) = source.file_id.macro_file() { let span_map = db.expansion_span_map(macro_file); body = prettify_macro_expansion(db, body, &span_map, it.krate(db).into()); } - Some(body.to_string()) + if env::var_os("RA_DEV").is_some() { + format!("{body}\n{}", render_const_eval_error(db, err, edition)) + } else { + body.to_string() + } } - } + }) } _ => None, }; diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs index ea18b89c5c9..50d0d4c5df6 100644 --- a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs +++ b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs @@ -6413,7 +6413,7 @@ fn hover_feature() { by the codegen backend, but not the MIR inliner. ```rust - #![feature(rustc_attrs)] + #![feature(intrinsics)] #![allow(internal_features)] #[rustc_intrinsic] @@ -6423,7 +6423,7 @@ fn hover_feature() { Since these are just regular functions, it is perfectly ok to create the intrinsic twice: ```rust - #![feature(rustc_attrs)] + #![feature(intrinsics)] #![allow(internal_features)] #[rustc_intrinsic] @@ -9465,4 +9465,39 @@ fn main() { size = 0, align = 1 "#]], ); + + check( + r#" +//- minicore: eq +pub struct RandomState; +pub struct HashMap<K, V, S = RandomState>(K, V, S); + +impl<K, V> HashMap<K, V, RandomState> { + pub fn new() -> HashMap<K, V, RandomState> { + loop {} + } +} + +impl<K, V, S> PartialEq for HashMap<K, V, S> { + fn eq(&self, other: &HashMap<K, V, S>) -> bool { + false + } +} + +fn main() { + let s$0 = HashMap::<_, u64>::ne; +} +"#, + expect![[r#" + *s* + + ```rust + let s: fn ne<HashMap<{unknown}, u64>>(&HashMap<{unknown}, u64>, &HashMap<{unknown}, u64>) -> bool + ``` + + --- + + size = 0, align = 1 + "#]], + ); } diff --git a/src/tools/rust-analyzer/crates/ide/src/interpret.rs b/src/tools/rust-analyzer/crates/ide/src/interpret.rs index 5fa6f4e4842..e0fdc3dd6f9 100644 --- a/src/tools/rust-analyzer/crates/ide/src/interpret.rs +++ b/src/tools/rust-analyzer/crates/ide/src/interpret.rs @@ -1,5 +1,6 @@ -use hir::{DefWithBody, Semantics}; +use hir::{ConstEvalError, DefWithBody, Semantics}; use ide_db::{base_db::SourceRootDatabase, FilePosition, LineIndexDatabase, RootDatabase}; +use span::Edition; use std::time::{Duration, Instant}; use stdx::format_to; use syntax::{algo::ancestors_at_offset, ast, AstNode, TextRange}; @@ -47,18 +48,36 @@ fn find_and_interpret(db: &RootDatabase, position: FilePosition) -> Option<(Dura None => format!("file://{path} range {text_range:?}"), } }; + let edition = def.module(db).krate().edition(db); let start_time = Instant::now(); let res = match def { DefWithBody::Function(it) => it.eval(db, span_formatter), - DefWithBody::Static(it) => it.eval(db), - DefWithBody::Const(it) => it.eval(db), + DefWithBody::Static(it) => it.eval(db).map(|it| it.render(db, edition)), + DefWithBody::Const(it) => it.eval(db).map(|it| it.render(db, edition)), _ => unreachable!(), }; - let res = res.unwrap_or_else(|e| { - let mut r = String::new(); - _ = e.pretty_print(&mut r, db, span_formatter, def.module(db).krate().edition(db)); - r - }); + let res = res.unwrap_or_else(|e| render_const_eval_error(db, e, edition)); let duration = Instant::now() - start_time; Some((duration, res)) } + +pub(crate) fn render_const_eval_error( + db: &RootDatabase, + e: ConstEvalError, + edition: Edition, +) -> String { + let span_formatter = |file_id, text_range: TextRange| { + let path = &db + .source_root(db.file_source_root(file_id)) + .path_for_file(&file_id) + .map(|x| x.to_string()); + let path = path.as_deref().unwrap_or("<unknown file>"); + match db.line_index(file_id).try_line_col(text_range.start()) { + Some(line_col) => format!("file://{path}:{}:{}", line_col.line + 1, line_col.col), + None => format!("file://{path} range {text_range:?}"), + } + }; + let mut r = String::new(); + _ = e.pretty_print(&mut r, db, span_formatter, edition); + r +} diff --git a/src/tools/rust-analyzer/crates/ide/src/lib.rs b/src/tools/rust-analyzer/crates/ide/src/lib.rs index c960b88a3e9..c13fc843568 100644 --- a/src/tools/rust-analyzer/crates/ide/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide/src/lib.rs @@ -132,11 +132,9 @@ pub use ide_db::{ search::{ReferenceCategory, SearchScope}, source_change::{FileSystemEdit, SnippetEdit, SourceChange}, symbol_index::Query, - FileId, FilePosition, FileRange, RootDatabase, SymbolKind, -}; -pub use ide_diagnostics::{ - Diagnostic, DiagnosticCode, DiagnosticsConfig, ExprFillDefaultMode, Severity, + FileId, FilePosition, FileRange, RootDatabase, Severity, SymbolKind, }; +pub use ide_diagnostics::{Diagnostic, DiagnosticCode, DiagnosticsConfig, ExprFillDefaultMode}; pub use ide_ssr::SsrError; pub use span::Edition; pub use syntax::{TextRange, TextSize}; @@ -301,7 +299,7 @@ impl Analysis { /// Gets the syntax tree of the file. pub fn parse(&self, file_id: FileId) -> Cancellable<SourceFile> { - // FIXME editiojn + // FIXME edition self.with_db(|db| db.parse(EditionedFileId::current_edition(file_id)).tree()) } @@ -542,7 +540,7 @@ impl Analysis { /// Returns URL(s) for the documentation of the symbol under the cursor. /// # Arguments /// * `position` - Position in the file. - /// * `target_dir` - Directory where the build output is storeda. + /// * `target_dir` - Directory where the build output is stored. pub fn external_docs( &self, position: FilePosition, diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs index 1120d3c7d60..c15751e7c68 100644 --- a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs +++ b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs @@ -307,6 +307,7 @@ define_symbols! { module_path, mul_assign, mul, + naked_asm, ne, neg, Neg, diff --git a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs index cf26845b119..aa64f570ed5 100644 --- a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs +++ b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs @@ -15,9 +15,7 @@ use ide_db::{ }; use itertools::Itertools; use proc_macro_api::{MacroDylib, ProcMacroServer}; -use project_model::{ - CargoConfig, PackageRoot, ProjectManifest, ProjectWorkspace, ProjectWorkspaceKind, -}; +use project_model::{CargoConfig, PackageRoot, ProjectManifest, ProjectWorkspace}; use span::Span; use vfs::{ file_set::FileSetConfig, @@ -244,6 +242,9 @@ impl ProjectFolders { } } + if dirs.include.is_empty() { + continue; + } vfs::loader::Entry::Directories(dirs) }; @@ -258,43 +259,6 @@ impl ProjectFolders { fsc.add_file_set(file_set_roots) } - // register the workspace manifest as well, note that this currently causes duplicates for - // non-virtual cargo workspaces! We ought to fix that - for ws in workspaces.iter() { - let mut file_set_roots: Vec<VfsPath> = vec![]; - let mut entries = vec![]; - - if let Some(manifest) = ws.manifest().map(|it| it.to_path_buf()) { - file_set_roots.push(VfsPath::from(manifest.to_owned())); - entries.push(manifest.to_owned()); - } - - for buildfile in ws.buildfiles() { - file_set_roots.push(VfsPath::from(buildfile.to_owned())); - entries.push(buildfile.to_owned()); - } - - // In case of detached files we do **not** look for a rust-analyzer.toml. - if !matches!(ws.kind, ProjectWorkspaceKind::DetachedFile { .. }) { - let ws_root = ws.workspace_root(); - let ratoml_path = { - let mut p = ws_root.to_path_buf(); - p.push("rust-analyzer.toml"); - p - }; - file_set_roots.push(VfsPath::from(ratoml_path.to_owned())); - entries.push(ratoml_path.to_owned()); - } - - if !file_set_roots.is_empty() { - let entry = vfs::loader::Entry::Files(entries); - res.watch.push(res.load.len()); - res.load.push(entry); - local_filesets.push(fsc.len() as u64); - fsc.add_file_set(file_set_roots) - } - } - if let Some(user_config_path) = user_config_dir_path { let ratoml_path = { let mut p = user_config_path.to_path_buf(); @@ -303,7 +267,7 @@ impl ProjectFolders { }; let file_set_roots = vec![VfsPath::from(ratoml_path.to_owned())]; - let entry = vfs::loader::Entry::Files(vec![ratoml_path.to_owned()]); + let entry = vfs::loader::Entry::Files(vec![ratoml_path]); res.watch.push(res.load.len()); res.load.push(entry); diff --git a/src/tools/rust-analyzer/crates/parser/Cargo.toml b/src/tools/rust-analyzer/crates/parser/Cargo.toml index d5255665b46..3629d275c0c 100644 --- a/src/tools/rust-analyzer/crates/parser/Cargo.toml +++ b/src/tools/rust-analyzer/crates/parser/Cargo.toml @@ -18,6 +18,8 @@ ra-ap-rustc_lexer.workspace = true limit.workspace = true tracing = { workspace = true, optional = true } +edition.workspace = true + [dev-dependencies] expect-test = "1.4.0" diff --git a/src/tools/rust-analyzer/crates/parser/src/lib.rs b/src/tools/rust-analyzer/crates/parser/src/lib.rs index 679492066a3..e461492cc6f 100644 --- a/src/tools/rust-analyzer/crates/parser/src/lib.rs +++ b/src/tools/rust-analyzer/crates/parser/src/lib.rs @@ -25,7 +25,6 @@ extern crate ra_ap_rustc_lexer as rustc_lexer; #[cfg(feature = "in-rust-tree")] extern crate rustc_lexer; -mod edition; mod event; mod grammar; mod input; @@ -41,8 +40,9 @@ mod tests; pub(crate) use token_set::TokenSet; +pub use edition::Edition; + pub use crate::{ - edition::Edition, input::Input, lexed_str::LexedStr, output::{Output, Step}, diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/msg/flat.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/msg/flat.rs index 5443a9bd67b..af3412e90e4 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/msg/flat.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/msg/flat.rs @@ -42,7 +42,7 @@ use rustc_hash::FxHashMap; use serde::{Deserialize, Serialize}; use span::{EditionedFileId, ErasedFileAstId, Span, SpanAnchor, SyntaxContextId, TextRange}; -use crate::msg::{ENCODE_CLOSE_SPAN_VERSION, EXTENDED_LEAF_DATA}; +use crate::msg::EXTENDED_LEAF_DATA; pub type SpanDataIndexMap = indexmap::IndexSet<Span, std::hash::BuildHasherDefault<rustc_hash::FxHasher>>; @@ -145,11 +145,7 @@ impl FlatTree { w.write(subtree); FlatTree { - subtree: if version >= ENCODE_CLOSE_SPAN_VERSION { - write_vec(w.subtree, SubtreeRepr::write_with_close_span) - } else { - write_vec(w.subtree, SubtreeRepr::write) - }, + subtree: write_vec(w.subtree, SubtreeRepr::write), literal: if version >= EXTENDED_LEAF_DATA { write_vec(w.literal, LiteralRepr::write_with_kind) } else { @@ -183,11 +179,7 @@ impl FlatTree { w.write(subtree); FlatTree { - subtree: if version >= ENCODE_CLOSE_SPAN_VERSION { - write_vec(w.subtree, SubtreeRepr::write_with_close_span) - } else { - write_vec(w.subtree, SubtreeRepr::write) - }, + subtree: write_vec(w.subtree, SubtreeRepr::write), literal: if version >= EXTENDED_LEAF_DATA { write_vec(w.literal, LiteralRepr::write_with_kind) } else { @@ -210,11 +202,7 @@ impl FlatTree { span_data_table: &SpanDataIndexMap, ) -> tt::Subtree<Span> { Reader { - subtree: if version >= ENCODE_CLOSE_SPAN_VERSION { - read_vec(self.subtree, SubtreeRepr::read_with_close_span) - } else { - read_vec(self.subtree, SubtreeRepr::read) - }, + subtree: read_vec(self.subtree, SubtreeRepr::read), literal: if version >= EXTENDED_LEAF_DATA { read_vec(self.literal, LiteralRepr::read_with_kind) } else { @@ -236,11 +224,7 @@ impl FlatTree { pub fn to_subtree_unresolved(self, version: u32) -> tt::Subtree<TokenId> { Reader { - subtree: if version >= ENCODE_CLOSE_SPAN_VERSION { - read_vec(self.subtree, SubtreeRepr::read_with_close_span) - } else { - read_vec(self.subtree, SubtreeRepr::read) - }, + subtree: read_vec(self.subtree, SubtreeRepr::read), literal: if version >= EXTENDED_LEAF_DATA { read_vec(self.literal, LiteralRepr::read_with_kind) } else { @@ -273,26 +257,7 @@ fn write_vec<T, F: Fn(T) -> [u32; N], const N: usize>(xs: Vec<T>, f: F) -> Vec<u } impl SubtreeRepr { - fn write(self) -> [u32; 4] { - let kind = match self.kind { - tt::DelimiterKind::Invisible => 0, - tt::DelimiterKind::Parenthesis => 1, - tt::DelimiterKind::Brace => 2, - tt::DelimiterKind::Bracket => 3, - }; - [self.open.0, kind, self.tt[0], self.tt[1]] - } - fn read([open, kind, lo, len]: [u32; 4]) -> SubtreeRepr { - let kind = match kind { - 0 => tt::DelimiterKind::Invisible, - 1 => tt::DelimiterKind::Parenthesis, - 2 => tt::DelimiterKind::Brace, - 3 => tt::DelimiterKind::Bracket, - other => panic!("bad kind {other}"), - }; - SubtreeRepr { open: TokenId(open), close: TokenId(!0), kind, tt: [lo, len] } - } - fn write_with_close_span(self) -> [u32; 5] { + fn write(self) -> [u32; 5] { let kind = match self.kind { tt::DelimiterKind::Invisible => 0, tt::DelimiterKind::Parenthesis => 1, @@ -301,7 +266,7 @@ impl SubtreeRepr { }; [self.open.0, self.close.0, kind, self.tt[0], self.tt[1]] } - fn read_with_close_span([open, close, kind, lo, len]: [u32; 5]) -> SubtreeRepr { + fn read([open, close, kind, lo, len]: [u32; 5]) -> SubtreeRepr { let kind = match kind { 0 => tt::DelimiterKind::Invisible, 1 => tt::DelimiterKind::Parenthesis, diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs index 4045e25fdf1..b1e35b7a08b 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs @@ -56,8 +56,25 @@ impl ProcMacroProcessSrv { match srv.version_check() { Ok(v) if v > CURRENT_API_VERSION => Err(io::Error::new( io::ErrorKind::Other, - format!( "The version of the proc-macro server ({v}) in your Rust toolchain is newer than the version supported by your rust-analyzer ({CURRENT_API_VERSION}). - This will prevent proc-macro expansion from working. Please consider updating your rust-analyzer to ensure compatibility with your current toolchain." + format!( + "The version of the proc-macro server ({v}) in your Rust toolchain \ + is newer than the version supported by your rust-analyzer ({CURRENT_API_VERSION}). +\ + This will prevent proc-macro expansion from working. \ + Please consider updating your rust-analyzer to ensure compatibility with your \ + current toolchain." + ), + )), + Ok(v) if v < RUST_ANALYZER_SPAN_SUPPORT => Err(io::Error::new( + io::ErrorKind::Other, + format!( + "The version of the proc-macro server ({v}) in your Rust toolchain \ + is too old and no longer supported by your rust-analyzer which requires\ + version {RUST_ANALYZER_SPAN_SUPPORT} or higher. +\ + This will prevent proc-macro expansion from working. \ + Please consider updating your toolchain or downgrading your rust-analyzer \ + to ensure compatibility with your current toolchain." ), )), Ok(v) => { @@ -72,10 +89,10 @@ impl ProcMacroProcessSrv { tracing::info!("Proc-macro server span mode: {:?}", srv.mode); Ok(srv) } - Err(e) => { - tracing::info!(%e, "proc-macro version check failed, restarting and assuming version 0"); - create_srv(false) - } + Err(e) => Err(io::Error::new( + io::ErrorKind::Other, + format!("Failed to fetch proc-macro server version: {e}"), + )), } } diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs index 174f9c52462..137efd5e7a0 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs @@ -6,21 +6,16 @@ #[cfg(feature = "in-rust-tree")] extern crate rustc_driver as _; -use proc_macro_api::json::{read_json, write_json}; - use std::io; fn main() -> std::io::Result<()> { let v = std::env::var("RUST_ANALYZER_INTERNALS_DO_NOT_USE"); - match v.as_deref() { - Ok("this is unstable") => { - // very well, if you must - } - _ => { - eprintln!("If you're rust-analyzer, you can use this tool by exporting RUST_ANALYZER_INTERNALS_DO_NOT_USE='this is unstable'."); - eprintln!("If not, you probably shouldn't use this tool. But do what you want: I'm an error message, not a cop."); - std::process::exit(122); - } + if v.is_err() { + eprintln!("This is an IDE implementation detail, you can use this tool by exporting RUST_ANALYZER_INTERNALS_DO_NOT_USE."); + eprintln!( + "Note that this tool's API is highly unstable and may break without prior notice" + ); + std::process::exit(122); } run() @@ -28,40 +23,19 @@ fn main() -> std::io::Result<()> { #[cfg(not(any(feature = "sysroot-abi", rust_analyzer)))] fn run() -> io::Result<()> { - let err = "proc-macro-srv-cli needs to be compiled with the `sysroot-abi` feature to function"; - eprintln!("{err}"); - use proc_macro_api::msg::{self, Message}; - - let read_request = - |buf: &mut String| msg::Request::read(read_json, &mut io::stdin().lock(), buf); - - let write_response = |msg: msg::Response| msg.write(write_json, &mut io::stdout().lock()); - - let mut buf = String::new(); - - while let Some(req) = read_request(&mut buf)? { - let res = match req { - msg::Request::ListMacros { .. } => msg::Response::ListMacros(Err(err.to_owned())), - msg::Request::ExpandMacro(_) => { - msg::Response::ExpandMacro(Err(msg::PanicMessage(err.to_owned()))) - } - msg::Request::ApiVersionCheck {} => { - msg::Response::ApiVersionCheck(proc_macro_api::msg::CURRENT_API_VERSION) - } - msg::Request::SetConfig(_) => { - msg::Response::SetConfig(proc_macro_api::msg::ServerConfig { - span_mode: msg::SpanMode::Id, - }) - } - }; - write_response(res)? - } - Ok(()) + Err(io::Error::new( + io::ErrorKind::Unsupported, + "proc-macro-srv-cli needs to be compiled with the `sysroot-abi` feature to function" + .to_owned(), + )) } #[cfg(any(feature = "sysroot-abi", rust_analyzer))] fn run() -> io::Result<()> { - use proc_macro_api::msg::{self, Message}; + use proc_macro_api::{ + json::{read_json, write_json}, + msg::{self, Message}, + }; use proc_macro_srv::EnvSnapshot; let read_request = @@ -69,7 +43,7 @@ fn run() -> io::Result<()> { let write_response = |msg: msg::Response| msg.write(write_json, &mut io::stdout().lock()); - let env = EnvSnapshot::new(); + let env = EnvSnapshot::default(); let mut srv = proc_macro_srv::ProcMacroSrv::new(&env); let mut buf = String::new(); diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs index 78ae4574c40..26f6af84aae 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs @@ -3,12 +3,11 @@ mod version; use proc_macro::bridge; -use std::{fmt, fs::File, io}; +use std::{fmt, fs, io, time::SystemTime}; use libloading::Library; -use memmap2::Mmap; use object::Object; -use paths::{AbsPath, Utf8Path, Utf8PathBuf}; +use paths::{Utf8Path, Utf8PathBuf}; use proc_macro_api::ProcMacroKind; use crate::ProcMacroSrvSpan; @@ -23,14 +22,9 @@ fn is_derive_registrar_symbol(symbol: &str) -> bool { symbol.contains(NEW_REGISTRAR_SYMBOL) } -fn find_registrar_symbol(file: &Utf8Path) -> io::Result<Option<String>> { - let file = File::open(file)?; - let buffer = unsafe { Mmap::map(&file)? }; - - Ok(object::File::parse(&*buffer) - .map_err(invalid_data_err)? - .exports() - .map_err(invalid_data_err)? +fn find_registrar_symbol(obj: &object::File<'_>) -> object::Result<Option<String>> { + Ok(obj + .exports()? .into_iter() .map(|export| export.name()) .filter_map(|sym| String::from_utf8(sym.into()).ok()) @@ -113,17 +107,18 @@ struct ProcMacroLibraryLibloading { } impl ProcMacroLibraryLibloading { - fn open(file: &Utf8Path) -> Result<Self, LoadProcMacroDylibError> { - let symbol_name = find_registrar_symbol(file)?.ok_or_else(|| { - invalid_data_err(format!("Cannot find registrar symbol in file {file}")) - })?; - - let abs_file: &AbsPath = file - .try_into() - .map_err(|_| invalid_data_err(format!("expected an absolute path, got {file}")))?; - let version_info = version::read_dylib_info(abs_file)?; - - let lib = load_library(file).map_err(invalid_data_err)?; + fn open(path: &Utf8Path) -> Result<Self, LoadProcMacroDylibError> { + let file = fs::File::open(path)?; + let file = unsafe { memmap2::Mmap::map(&file) }?; + let obj = object::File::parse(&*file) + .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; + let version_info = version::read_dylib_info(&obj)?; + let symbol_name = + find_registrar_symbol(&obj).map_err(invalid_data_err)?.ok_or_else(|| { + invalid_data_err(format!("Cannot find registrar symbol in file {path}")) + })?; + + let lib = load_library(path).map_err(invalid_data_err)?; let proc_macros = crate::proc_macros::ProcMacros::from_lib( &lib, symbol_name, @@ -133,30 +128,33 @@ impl ProcMacroLibraryLibloading { } } -pub(crate) struct Expander { - inner: ProcMacroLibraryLibloading, - path: Utf8PathBuf, -} - -impl Drop for Expander { +struct RemoveFileOnDrop(Utf8PathBuf); +impl Drop for RemoveFileOnDrop { fn drop(&mut self) { #[cfg(windows)] - std::fs::remove_file(&self.path).ok(); - _ = self.path; + std::fs::remove_file(&self.0).unwrap(); + _ = self.0; } } +// Drop order matters as we can't remove the dylib before the library is unloaded +pub(crate) struct Expander { + inner: ProcMacroLibraryLibloading, + _remove_on_drop: RemoveFileOnDrop, + modified_time: SystemTime, +} + impl Expander { pub(crate) fn new(lib: &Utf8Path) -> Result<Expander, LoadProcMacroDylibError> { // Some libraries for dynamic loading require canonicalized path even when it is // already absolute let lib = lib.canonicalize_utf8()?; + let modified_time = fs::metadata(&lib).and_then(|it| it.modified())?; let path = ensure_file_with_lock_free_access(&lib)?; - let library = ProcMacroLibraryLibloading::open(path.as_ref())?; - Ok(Expander { inner: library, path }) + Ok(Expander { inner: library, _remove_on_drop: RemoveFileOnDrop(path), modified_time }) } pub(crate) fn expand<S: ProcMacroSrvSpan>( @@ -181,6 +179,10 @@ impl Expander { pub(crate) fn list_macros(&self) -> Vec<(String, ProcMacroKind)> { self.inner.proc_macros.list_macros() } + + pub(crate) fn modified_time(&self) -> SystemTime { + self.modified_time + } } /// Copy the dylib to temp directory to prevent locking in Windows @@ -194,20 +196,20 @@ fn ensure_file_with_lock_free_access(path: &Utf8Path) -> io::Result<Utf8PathBuf> } let mut to = Utf8PathBuf::from_path_buf(std::env::temp_dir()).unwrap(); + to.push("rust-analyzer-proc-macros"); + _ = fs::create_dir(&to); - let file_name = path.file_name().ok_or_else(|| { + let file_name = path.file_stem().ok_or_else(|| { io::Error::new(io::ErrorKind::InvalidInput, format!("File path is invalid: {path}")) })?; - // Generate a unique number by abusing `HashMap`'s hasher. - // Maybe this will also "inspire" a libs team member to finally put `rand` in libstd. - let t = RandomState::new().build_hasher().finish(); - - let mut unique_name = t.to_string(); - unique_name.push_str(file_name); - - to.push(unique_name); - std::fs::copy(path, &to)?; + to.push({ + // Generate a unique number by abusing `HashMap`'s hasher. + // Maybe this will also "inspire" a libs team member to finally put `rand` in libstd. + let unique_name = RandomState::new().build_hasher().finish(); + format!("{file_name}-{unique_name}.dll") + }); + fs::copy(path, &to)?; Ok(to) } diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/version.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/version.rs index 7f0e95c50de..4e28aaced9b 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/version.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/version.rs @@ -1,13 +1,8 @@ //! Reading proc-macro rustc version information from binary data -use std::{ - fs::File, - io::{self, Read}, -}; +use std::io::{self, Read}; -use memmap2::Mmap; -use object::read::{File as BinaryFile, Object, ObjectSection}; -use paths::AbsPath; +use object::read::{Object, ObjectSection}; #[derive(Debug)] #[allow(dead_code)] @@ -21,14 +16,14 @@ pub struct RustCInfo { } /// Read rustc dylib information -pub fn read_dylib_info(dylib_path: &AbsPath) -> io::Result<RustCInfo> { +pub fn read_dylib_info(obj: &object::File<'_>) -> io::Result<RustCInfo> { macro_rules! err { ($e:literal) => { io::Error::new(io::ErrorKind::InvalidData, $e) }; } - let ver_str = read_version(dylib_path)?; + let ver_str = read_version(obj)?; let mut items = ver_str.split_whitespace(); let tag = items.next().ok_or_else(|| err!("version format error"))?; if tag != "rustc" { @@ -75,10 +70,8 @@ pub fn read_dylib_info(dylib_path: &AbsPath) -> io::Result<RustCInfo> { /// This is used inside read_version() to locate the ".rustc" section /// from a proc macro crate's binary file. -fn read_section<'a>(dylib_binary: &'a [u8], section_name: &str) -> io::Result<&'a [u8]> { - BinaryFile::parse(dylib_binary) - .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))? - .section_by_name(section_name) +fn read_section<'a>(obj: &object::File<'a>, section_name: &str) -> io::Result<&'a [u8]> { + obj.section_by_name(section_name) .ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "section read error"))? .data() .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) @@ -106,11 +99,8 @@ fn read_section<'a>(dylib_binary: &'a [u8], section_name: &str) -> io::Result<&' /// /// Check this issue for more about the bytes layout: /// <https://github.com/rust-lang/rust-analyzer/issues/6174> -pub fn read_version(dylib_path: &AbsPath) -> io::Result<String> { - let dylib_file = File::open(dylib_path)?; - let dylib_mmapped = unsafe { Mmap::map(&dylib_file) }?; - - let dot_rustc = read_section(&dylib_mmapped, ".rustc")?; +pub fn read_version(obj: &object::File<'_>) -> io::Result<String> { + let dot_rustc = read_section(obj, ".rustc")?; // check if magic is valid if &dot_rustc[0..4] != b"rust" { @@ -159,8 +149,12 @@ pub fn read_version(dylib_path: &AbsPath) -> io::Result<String> { #[test] fn test_version_check() { - let path = paths::AbsPathBuf::assert(crate::proc_macro_test_dylib_path()); - let info = read_dylib_info(&path).unwrap(); + let info = read_dylib_info( + &object::File::parse(&*std::fs::read(crate::proc_macro_test_dylib_path()).unwrap()) + .unwrap(), + ) + .unwrap(); + assert_eq!( info.version_string, crate::RUSTC_VERSION_STRING, diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs index f0aa6b3f93f..85833dab1b0 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs @@ -13,7 +13,7 @@ #![cfg(any(feature = "sysroot-abi", rust_analyzer))] #![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] #![feature(proc_macro_internals, proc_macro_diagnostic, proc_macro_span)] -#![allow(unreachable_pub, internal_features)] +#![allow(unreachable_pub, internal_features, clippy::disallowed_types, clippy::print_stderr)] extern crate proc_macro; #[cfg(feature = "in-rust-tree")] @@ -35,7 +35,6 @@ use std::{ fs, path::{Path, PathBuf}, thread, - time::SystemTime, }; use paths::{Utf8Path, Utf8PathBuf}; @@ -53,7 +52,7 @@ use crate::server_impl::TokenStream; pub const RUSTC_VERSION_STRING: &str = env!("RUSTC_VERSION"); pub struct ProcMacroSrv<'env> { - expanders: HashMap<(Utf8PathBuf, SystemTime), dylib::Expander>, + expanders: HashMap<Utf8PathBuf, dylib::Expander>, span_mode: SpanMode, env: &'env EnvSnapshot, } @@ -66,7 +65,7 @@ impl<'env> ProcMacroSrv<'env> { const EXPANDER_STACK_SIZE: usize = 8 * 1024 * 1024; -impl<'env> ProcMacroSrv<'env> { +impl ProcMacroSrv<'_> { pub fn set_span_mode(&mut self, span_mode: SpanMode) { self.span_mode = span_mode; } @@ -81,10 +80,9 @@ impl<'env> ProcMacroSrv<'env> { ) -> Result<(msg::FlatTree, Vec<u32>), msg::PanicMessage> { let span_mode = self.span_mode; let snapped_env = self.env; - let expander = self.expander(lib.as_ref()).map_err(|err| { - debug_assert!(false, "should list macros before asking to expand"); - msg::PanicMessage(format!("failed to load macro: {err}")) - })?; + let expander = self + .expander(lib.as_ref()) + .map_err(|err| msg::PanicMessage(format!("failed to load macro: {err}")))?; let prev_env = EnvChange::apply(snapped_env, env, current_dir.as_ref().map(<_>::as_ref)); @@ -107,16 +105,20 @@ impl<'env> ProcMacroSrv<'env> { } fn expander(&mut self, path: &Utf8Path) -> Result<&dylib::Expander, String> { - let time = fs::metadata(path) - .and_then(|it| it.modified()) - .map_err(|err| format!("Failed to get file metadata for {path}: {err}",))?; - - Ok(match self.expanders.entry((path.to_path_buf(), time)) { - Entry::Vacant(v) => v.insert( - dylib::Expander::new(path) - .map_err(|err| format!("Cannot create expander for {path}: {err}",))?, - ), - Entry::Occupied(e) => e.into_mut(), + let expander = || { + dylib::Expander::new(path) + .map_err(|err| format!("Cannot create expander for {path}: {err}",)) + }; + + Ok(match self.expanders.entry(path.to_path_buf()) { + Entry::Vacant(v) => v.insert(expander()?), + Entry::Occupied(mut e) => { + let time = fs::metadata(path).and_then(|it| it.modified()).ok(); + if Some(e.get().modified_time()) != time { + e.insert(expander()?); + } + e.into_mut() + } }) } } @@ -246,8 +248,8 @@ pub struct EnvSnapshot { vars: HashMap<OsString, OsString>, } -impl EnvSnapshot { - pub fn new() -> EnvSnapshot { +impl Default for EnvSnapshot { + fn default() -> EnvSnapshot { EnvSnapshot { vars: env::vars_os().collect() } } } @@ -303,7 +305,7 @@ impl Drop for EnvChange<'_> { } if let Some(dir) = &self.prev_working_dir { - if let Err(err) = std::env::set_current_dir(&dir) { + if let Err(err) = std::env::set_current_dir(dir) { eprintln!( "Failed to set the current working dir to {}. Error: {:?}", dir.display(), diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/proc_macros.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/proc_macros.rs index d48c5b30dee..097b39a3f91 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/proc_macros.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/proc_macros.rs @@ -13,7 +13,7 @@ pub(crate) struct ProcMacros { impl From<bridge::PanicMessage> for crate::PanicMessage { fn from(p: bridge::PanicMessage) -> Self { - Self { message: p.as_str().map(|s| s.to_string()) } + Self { message: p.as_str().map(|s| s.to_owned()) } } } diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs index d508c19dd71..1b535d2a1cc 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs @@ -498,7 +498,7 @@ mod tests { })), tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident { sym: Symbol::intern("T"), - span: span, + span, is_raw: tt::IdentIsRaw::No, })), tt::TokenTree::Subtree(tt::Subtree { diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_stream.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_stream.rs index dbcb5a3143a..5649e60e0bb 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_stream.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_stream.rs @@ -99,7 +99,7 @@ pub(super) struct TokenStreamBuilder<S> { } /// pub(super)lic implementation details for the `TokenStream` type, such as iterators. -pub(super) mod token_stream { +pub(super) mod token_stream_impls { use core::fmt; @@ -137,6 +137,7 @@ pub(super) mod token_stream { } } + #[allow(clippy::to_string_trait_impl)] impl<S> ToString for TokenStream<S> { fn to_string(&self) -> String { ::tt::pretty(&self.token_trees) @@ -150,7 +151,7 @@ impl<S> TokenStreamBuilder<S> { } pub(super) fn push(&mut self, stream: TokenStream<S>) { - self.acc.extend(stream.into_iter()) + self.acc.extend(stream) } pub(super) fn build(self) -> TokenStream<S> { diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs index 4f1a18c03fc..cc5d4a89131 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs @@ -97,7 +97,7 @@ fn assert_expand_impl( pub(crate) fn list() -> Vec<String> { let dylib_path = proc_macro_test_dylib_path(); - let env = EnvSnapshot::new(); + let env = EnvSnapshot::default(); let mut srv = ProcMacroSrv::new(&env); let res = srv.list_macros(&dylib_path).unwrap(); res.into_iter().map(|(name, kind)| format!("{name} [{kind:?}]")).collect() diff --git a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs index cb5738a3b40..4ae3426ed97 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs @@ -33,6 +33,7 @@ pub struct CargoWorkspace { workspace_root: AbsPathBuf, target_directory: AbsPathBuf, manifest_path: ManifestPath, + is_virtual_workspace: bool, } impl ops::Index<Package> for CargoWorkspace { @@ -384,13 +385,20 @@ impl CargoWorkspace { .with_context(|| format!("Failed to run `{:?}`", meta.cargo_command())) } - pub fn new(mut meta: cargo_metadata::Metadata, manifest_path: ManifestPath) -> CargoWorkspace { + pub fn new( + mut meta: cargo_metadata::Metadata, + ws_manifest_path: ManifestPath, + ) -> CargoWorkspace { let mut pkg_by_id = FxHashMap::default(); let mut packages = Arena::default(); let mut targets = Arena::default(); let ws_members = &meta.workspace_members; + let workspace_root = AbsPathBuf::assert(meta.workspace_root); + let target_directory = AbsPathBuf::assert(meta.target_directory); + let mut is_virtual_workspace = true; + meta.packages.sort_by(|a, b| a.id.cmp(&b.id)); for meta_pkg in meta.packages { let cargo_metadata::Package { @@ -429,12 +437,13 @@ impl CargoWorkspace { let is_local = source.is_none(); let is_member = ws_members.contains(&id); - let manifest = AbsPathBuf::assert(manifest_path); + let manifest = ManifestPath::try_from(AbsPathBuf::assert(manifest_path)).unwrap(); + is_virtual_workspace &= manifest != ws_manifest_path; let pkg = packages.alloc(PackageData { id: id.repr.clone(), name, version, - manifest: manifest.clone().try_into().unwrap(), + manifest: manifest.clone(), targets: Vec::new(), is_local, is_member, @@ -468,7 +477,7 @@ impl CargoWorkspace { // modified manifest file into a special target dir which is then used as // the source path. We don't want that, we want the original here so map it // back - manifest.clone() + manifest.clone().into() } else { AbsPathBuf::assert(src_path) }, @@ -493,11 +502,14 @@ impl CargoWorkspace { packages[source].active_features.extend(node.features); } - let workspace_root = AbsPathBuf::assert(meta.workspace_root); - - let target_directory = AbsPathBuf::assert(meta.target_directory); - - CargoWorkspace { packages, targets, workspace_root, target_directory, manifest_path } + CargoWorkspace { + packages, + targets, + workspace_root, + target_directory, + manifest_path: ws_manifest_path, + is_virtual_workspace, + } } pub fn packages(&self) -> impl ExactSizeIterator<Item = Package> + '_ { @@ -579,6 +591,10 @@ impl CargoWorkspace { fn is_unique(&self, name: &str) -> bool { self.packages.iter().filter(|(_, v)| v.name == name).count() == 1 } + + pub fn is_virtual_workspace(&self) -> bool { + self.is_virtual_workspace + } } fn find_list_of_build_targets( diff --git a/src/tools/rust-analyzer/crates/project-model/src/manifest_path.rs b/src/tools/rust-analyzer/crates/project-model/src/manifest_path.rs index a8be5dff7b6..a72dab60752 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/manifest_path.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/manifest_path.rs @@ -29,6 +29,12 @@ impl TryFrom<AbsPathBuf> for ManifestPath { } } +impl From<ManifestPath> for AbsPathBuf { + fn from(it: ManifestPath) -> Self { + it.file + } +} + impl ManifestPath { // Shadow `parent` from `Deref`. pub fn parent(&self) -> &AbsPath { diff --git a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs index 988eff9be44..71ddee30910 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs @@ -11,8 +11,9 @@ use base_db::{ }; use cfg::{CfgAtom, CfgDiff, CfgOptions}; use intern::{sym, Symbol}; +use itertools::Itertools; use paths::{AbsPath, AbsPathBuf}; -use rustc_hash::{FxHashMap, FxHashSet}; +use rustc_hash::FxHashMap; use semver::Version; use span::{Edition, FileId}; use toolchain::Tool; @@ -41,7 +42,9 @@ pub type FileLoader<'a> = &'a mut dyn for<'b> FnMut(&'b AbsPath) -> Option<FileI pub struct PackageRoot { /// Is from the local filesystem and may be edited pub is_local: bool, + /// Directories to include pub include: Vec<AbsPathBuf>, + /// Directories to exclude pub exclude: Vec<AbsPathBuf>, } @@ -553,17 +556,6 @@ impl ProjectWorkspace { } } - pub fn buildfiles(&self) -> Vec<AbsPathBuf> { - match &self.kind { - ProjectWorkspaceKind::Json(project) => project - .crates() - .filter_map(|(_, krate)| krate.build.as_ref().map(|build| build.build_file.clone())) - .map(|build_file| self.workspace_root().join(build_file)) - .collect(), - _ => vec![], - } - } - pub fn find_sysroot_proc_macro_srv(&self) -> anyhow::Result<AbsPathBuf> { self.sysroot.discover_proc_macro_srv() } @@ -608,15 +600,25 @@ impl ProjectWorkspace { match &self.kind { ProjectWorkspaceKind::Json(project) => project .crates() - .map(|(_, krate)| PackageRoot { - is_local: krate.is_workspace_member, - include: krate.include.clone(), - exclude: krate.exclude.clone(), + .map(|(_, krate)| { + let build_files = project + .crates() + .filter_map(|(_, krate)| { + krate.build.as_ref().map(|build| build.build_file.clone()) + }) + // FIXME: PackageRoots dont allow specifying files, only directories + .filter_map(|build_file| { + self.workspace_root().join(build_file).parent().map(ToOwned::to_owned) + }); + PackageRoot { + is_local: krate.is_workspace_member, + include: krate.include.iter().cloned().chain(build_files).collect(), + exclude: krate.exclude.clone(), + } }) - .collect::<FxHashSet<_>>() - .into_iter() .chain(mk_sysroot()) - .collect::<Vec<_>>(), + .unique() + .collect(), ProjectWorkspaceKind::Cargo { cargo, rustc, @@ -671,6 +673,11 @@ impl ProjectWorkspace { exclude: Vec::new(), }) })) + .chain(cargo.is_virtual_workspace().then(|| PackageRoot { + is_local: true, + include: vec![cargo.workspace_root().to_path_buf()], + exclude: Vec::new(), + })) .collect() } ProjectWorkspaceKind::DetachedFile { file, cargo: cargo_script, .. } => { diff --git a/src/tools/rust-analyzer/crates/ra-salsa/src/durability.rs b/src/tools/rust-analyzer/crates/ra-salsa/src/durability.rs index 7b8e6840fc9..9116f1606fa 100644 --- a/src/tools/rust-analyzer/crates/ra-salsa/src/durability.rs +++ b/src/tools/rust-analyzer/crates/ra-salsa/src/durability.rs @@ -11,7 +11,7 @@ /// case), and we know that the query only used inputs of medium /// durability or higher, then we can skip that enumeration. /// -/// Typically, one assigns low durabilites to inputs that the user is +/// Typically, one assigns low durabilities to inputs that the user is /// frequently editing. Medium or high durabilities are used for /// configuration, the source from library crates, or other things /// that are unlikely to be edited. diff --git a/src/tools/rust-analyzer/crates/ra-salsa/src/lib.rs b/src/tools/rust-analyzer/crates/ra-salsa/src/lib.rs index bd1ab6971cb..8530521d915 100644 --- a/src/tools/rust-analyzer/crates/ra-salsa/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ra-salsa/src/lib.rs @@ -291,7 +291,7 @@ pub trait ParallelDatabase: Database + Send { /// # Panics /// /// It is not permitted to create a snapshot from inside of a - /// query. Attepting to do so will panic. + /// query. Attempting to do so will panic. /// /// # Deadlock warning /// diff --git a/src/tools/rust-analyzer/crates/ra-salsa/tests/cycles.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/cycles.rs index 81136626551..3c3931e6585 100644 --- a/src/tools/rust-analyzer/crates/ra-salsa/tests/cycles.rs +++ b/src/tools/rust-analyzer/crates/ra-salsa/tests/cycles.rs @@ -255,7 +255,7 @@ fn cycle_revalidate_unchanged_twice() { db.set_b_invokes(CycleQuery::A); assert!(db.cycle_a().is_err()); - db.set_c_invokes(CycleQuery::A); // force new revisi5on + db.set_c_invokes(CycleQuery::A); // force new revision // on this run expect![[r#" diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs index eac33be5664..a753621eca8 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs @@ -51,7 +51,9 @@ fn actual_main() -> anyhow::Result<ExitCode> { } } - setup_logging(flags.log_file.clone())?; + if let Err(e) = setup_logging(flags.log_file.clone()) { + eprintln!("Failed to setup logging: {e:#}"); + } let verbosity = flags.verbosity(); diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs index e3ea441f3ab..66cd2e424e3 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs @@ -331,8 +331,8 @@ impl flags::AnalysisStats { let mut fail = 0; for &b in bodies { let res = match b { - DefWithBody::Const(c) => c.render_eval(db, Edition::LATEST), - DefWithBody::Static(s) => s.render_eval(db, Edition::LATEST), + DefWithBody::Const(c) => c.eval(db), + DefWithBody::Static(s) => s.eval(db), _ => continue, }; all += 1; diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs index bf7aca42faf..40fd294e72a 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs @@ -827,6 +827,7 @@ impl Config { let mut should_update = false; if let Some(change) = change.user_config_change { + tracing::info!("updating config from user config toml: {:#}", change); if let Ok(table) = toml::from_str(&change) { let mut toml_errors = vec![]; validate_toml_table( @@ -919,7 +920,7 @@ impl Config { RatomlFileKind::Crate => { if let Some(text) = text { let mut toml_errors = vec![]; - tracing::info!("updating ra-toml config: {:#}", text); + tracing::info!("updating ra-toml crate config: {:#}", text); match toml::from_str(&text) { Ok(table) => { validate_toml_table( @@ -961,6 +962,7 @@ impl Config { } RatomlFileKind::Workspace => { if let Some(text) = text { + tracing::info!("updating ra-toml workspace config: {:#}", text); let mut toml_errors = vec![]; match toml::from_str(&text) { Ok(table) => { diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs index 5f835702840..29be53cee1d 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs @@ -417,8 +417,10 @@ impl GlobalState { }) .collect_vec(); - for (file_id, (_change_kind, vfs_path)) in modified_ratoml_files { + for (file_id, (change_kind, vfs_path)) in modified_ratoml_files { + tracing::info!(%vfs_path, ?change_kind, "Processing rust-analyzer.toml changes"); if vfs_path.as_path() == user_config_abs_path { + tracing::info!(%vfs_path, ?change_kind, "Use config rust-analyzer.toml changes"); change.change_user_config(Some(db.file_text(file_id))); continue; } @@ -430,12 +432,14 @@ impl GlobalState { if !sr.is_library { let entry = if workspace_ratoml_paths.contains(&vfs_path) { + tracing::info!(%vfs_path, ?sr_id, "workspace rust-analyzer.toml changes"); change.change_workspace_ratoml( sr_id, vfs_path.clone(), Some(db.file_text(file_id)), ) } else { + tracing::info!(%vfs_path, ?sr_id, "crate rust-analyzer.toml changes"); change.change_ratoml( sr_id, vfs_path.clone(), @@ -446,7 +450,7 @@ impl GlobalState { if let Some((kind, old_path, old_text)) = entry { // SourceRoot has more than 1 RATOML files. In this case lexicographically smaller wins. if old_path < vfs_path { - span!(Level::ERROR, "Two `rust-analyzer.toml` files were found inside the same crate. {vfs_path} has no effect."); + tracing::error!("Two `rust-analyzer.toml` files were found inside the same crate. {vfs_path} has no effect."); // Put the old one back in. match kind { RatomlFileKind::Crate => { @@ -459,8 +463,7 @@ impl GlobalState { } } } else { - // Mapping to a SourceRoot should always end up in `Ok` - span!(Level::ERROR, "Mapping to SourceRootId failed."); + tracing::info!(%vfs_path, "Ignoring library rust-analyzer.toml"); } } change.change_source_root_parent_map(self.local_roots_parent_map.clone()); diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs index 05c2a8354da..eb96ab6ef59 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs @@ -895,7 +895,29 @@ pub fn item_const( None => String::new(), Some(it) => format!("{it} "), }; - ast_from_text(&format!("{visibility} const {name}: {ty} = {expr};")) + ast_from_text(&format!("{visibility}const {name}: {ty} = {expr};")) +} + +pub fn item_static( + visibility: Option<ast::Visibility>, + is_unsafe: bool, + is_mut: bool, + name: ast::Name, + ty: ast::Type, + expr: Option<ast::Expr>, +) -> ast::Static { + let visibility = match visibility { + None => String::new(), + Some(it) => format!("{it} "), + }; + let is_unsafe = if is_unsafe { "unsafe " } else { "" }; + let is_mut = if is_mut { "mut " } else { "" }; + let expr = match expr { + Some(it) => &format!(" = {it}"), + None => "", + }; + + ast_from_text(&format!("{visibility}{is_unsafe}static {is_mut}{name}: {ty}{expr};")) } pub fn unnamed_param(ty: ast::Type) -> ast::Param { diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs index e86c291f76c..280c5c25cb9 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs @@ -188,6 +188,73 @@ impl SyntaxFactory { ast } + pub fn item_const( + &self, + visibility: Option<ast::Visibility>, + name: ast::Name, + ty: ast::Type, + expr: ast::Expr, + ) -> ast::Const { + let ast = make::item_const(visibility.clone(), name.clone(), ty.clone(), expr.clone()) + .clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + if let Some(visibility) = visibility { + builder.map_node( + visibility.syntax().clone(), + ast.visibility().unwrap().syntax().clone(), + ); + } + builder.map_node(name.syntax().clone(), ast.name().unwrap().syntax().clone()); + builder.map_node(ty.syntax().clone(), ast.ty().unwrap().syntax().clone()); + builder.map_node(expr.syntax().clone(), ast.body().unwrap().syntax().clone()); + builder.finish(&mut mapping); + } + + ast + } + + pub fn item_static( + &self, + visibility: Option<ast::Visibility>, + is_unsafe: bool, + is_mut: bool, + name: ast::Name, + ty: ast::Type, + expr: Option<ast::Expr>, + ) -> ast::Static { + let ast = make::item_static( + visibility.clone(), + is_unsafe, + is_mut, + name.clone(), + ty.clone(), + expr.clone(), + ) + .clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + if let Some(visibility) = visibility { + builder.map_node( + visibility.syntax().clone(), + ast.visibility().unwrap().syntax().clone(), + ); + } + + builder.map_node(name.syntax().clone(), ast.name().unwrap().syntax().clone()); + builder.map_node(ty.syntax().clone(), ast.ty().unwrap().syntax().clone()); + + if let Some(expr) = expr { + builder.map_node(expr.syntax().clone(), ast.body().unwrap().syntax().clone()); + } + builder.finish(&mut mapping); + } + + ast + } + pub fn turbofish_generic_arg_list( &self, args: impl IntoIterator<Item = ast::GenericArg> + Clone, diff --git a/src/tools/rust-analyzer/docs/user/manual.adoc b/src/tools/rust-analyzer/docs/user/manual.adoc index 246ebdab2c9..da2aa4eae4e 100644 --- a/src/tools/rust-analyzer/docs/user/manual.adoc +++ b/src/tools/rust-analyzer/docs/user/manual.adoc @@ -580,7 +580,7 @@ Unfortunately, it downloads an old version of `rust-analyzer`, but you can set t There is a package named `ra_ap_rust_analyzer` available on https://crates.io/crates/ra_ap_rust-analyzer[crates.io], for someone who wants to use it programmatically. -For more details, see https://github.com/rust-lang/rust-analyzer/blob/master/.github/workflows/publish.yml[the publish workflow]. +For more details, see https://github.com/rust-lang/rust-analyzer/blob/master/.github/workflows/autopublish.yaml[the publish workflow]. === Zed diff --git a/src/tools/rust-analyzer/editors/code/src/client.ts b/src/tools/rust-analyzer/editors/code/src/client.ts index 4ce19f5c665..eac7b849fdb 100644 --- a/src/tools/rust-analyzer/editors/code/src/client.ts +++ b/src/tools/rust-analyzer/editors/code/src/client.ts @@ -324,7 +324,7 @@ class ExperimentalFeatures implements lc.StaticFeature { } fillClientCapabilities(capabilities: lc.ClientCapabilities): void { capabilities.experimental = { - snippetTextEdit: false, + snippetTextEdit: true, codeActionGroup: true, hoverActions: true, serverStatusNotification: true, diff --git a/src/tools/rust-analyzer/xtask/Cargo.toml b/src/tools/rust-analyzer/xtask/Cargo.toml index 4bc1821ee5e..01ad3336311 100644 --- a/src/tools/rust-analyzer/xtask/Cargo.toml +++ b/src/tools/rust-analyzer/xtask/Cargo.toml @@ -21,6 +21,7 @@ quote = "1.0.20" ungrammar = "1.16.1" either.workspace = true itertools.workspace = true +edition.workspace = true # Avoid adding more dependencies to this crate [lints] diff --git a/src/tools/rust-analyzer/xtask/src/codegen/lints.rs b/src/tools/rust-analyzer/xtask/src/codegen/lints.rs index f097b5817be..b1a7c2fb27e 100644 --- a/src/tools/rust-analyzer/xtask/src/codegen/lints.rs +++ b/src/tools/rust-analyzer/xtask/src/codegen/lints.rs @@ -1,7 +1,15 @@ //! Generates descriptor structures for unstable features from the unstable book //! and lints from rustc, rustdoc, and clippy. -use std::{borrow::Cow, fs, path::Path}; +#![allow(clippy::disallowed_types)] +use std::{ + collections::{hash_map, HashMap}, + fs, + path::Path, + str::FromStr, +}; + +use edition::Edition; use stdx::format_to; use xshell::{cmd, Shell}; @@ -36,10 +44,17 @@ pub(crate) fn generate(check: bool) { let mut contents = String::from( r" +use span::Edition; + +use crate::Severity; + #[derive(Clone)] pub struct Lint { pub label: &'static str, pub description: &'static str, + pub default_severity: Severity, + pub warn_since: Option<Edition>, + pub deny_since: Option<Edition>, } pub struct LintGroup { @@ -68,7 +83,7 @@ pub struct LintGroup { let lints_json = project_root().join("./target/clippy_lints.json"); cmd!( sh, - "curl https://rust-lang.github.io/rust-clippy/master/lints.json --output {lints_json}" + "curl https://rust-lang.github.io/rust-clippy/stable/lints.json --output {lints_json}" ) .run() .unwrap(); @@ -85,6 +100,48 @@ pub struct LintGroup { ); } +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)] +enum Severity { + Allow, + Warn, + Deny, +} + +impl std::fmt::Display for Severity { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "Severity::{}", + match self { + Severity::Allow => "Allow", + Severity::Warn => "Warning", + Severity::Deny => "Error", + } + ) + } +} + +impl FromStr for Severity { + type Err = &'static str; + + fn from_str(s: &str) -> Result<Self, Self::Err> { + match s { + "allow" => Ok(Self::Allow), + "warn" => Ok(Self::Warn), + "deny" => Ok(Self::Deny), + _ => Err("invalid severity"), + } + } +} + +#[derive(Debug)] +struct Lint { + description: String, + default_severity: Severity, + warn_since: Option<Edition>, + deny_since: Option<Edition>, +} + /// Parses the output of `rustdoc -Whelp` and prints `Lint` and `LintGroup` constants into `buf`. /// /// As of writing, the output of `rustc -Whelp` (not rustdoc) has the following format: @@ -108,52 +165,203 @@ pub struct LintGroup { /// `rustdoc -Whelp` (and any other custom `rustc` driver) adds another two /// tables after the `rustc` ones, with a different title but the same format. fn generate_lint_descriptor(sh: &Shell, buf: &mut String) { - let stdout = cmd!(sh, "rustdoc -Whelp").read().unwrap(); - let lints_pat = "---- ------- -------\n"; - let lint_groups_pat = "---- ---------\n"; - let lints = find_and_slice(&stdout, lints_pat); - let lint_groups = find_and_slice(lints, lint_groups_pat); - let lints_rustdoc = find_and_slice(lint_groups, lints_pat); - let lint_groups_rustdoc = find_and_slice(lints_rustdoc, lint_groups_pat); + fn get_lints_as_text( + stdout: &str, + ) -> ( + impl Iterator<Item = (String, &str, Severity)> + '_, + impl Iterator<Item = (String, Lint, impl Iterator<Item = String> + '_)> + '_, + impl Iterator<Item = (String, &str, Severity)> + '_, + impl Iterator<Item = (String, Lint, impl Iterator<Item = String> + '_)> + '_, + ) { + let lints_pat = "---- ------- -------\n"; + let lint_groups_pat = "---- ---------\n"; + let lints = find_and_slice(stdout, lints_pat); + let lint_groups = find_and_slice(lints, lint_groups_pat); + let lints_rustdoc = find_and_slice(lint_groups, lints_pat); + let lint_groups_rustdoc = find_and_slice(lints_rustdoc, lint_groups_pat); + + let lints = lints.lines().take_while(|l| !l.is_empty()).map(|line| { + let (name, rest) = line.trim().split_once(char::is_whitespace).unwrap(); + let (severity, description) = rest.trim().split_once(char::is_whitespace).unwrap(); + (name.trim().replace('-', "_"), description.trim(), severity.parse().unwrap()) + }); + let lint_groups = lint_groups.lines().take_while(|l| !l.is_empty()).map(|line| { + let (name, lints) = line.trim().split_once(char::is_whitespace).unwrap(); + let label = name.trim().replace('-', "_"); + let lint = Lint { + description: format!("lint group for: {}", lints.trim()), + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }; + let children = lints + .split_ascii_whitespace() + .map(|s| s.trim().trim_matches(',').replace('-', "_")); + (label, lint, children) + }); - buf.push_str(r#"pub const DEFAULT_LINTS: &[Lint] = &["#); - buf.push('\n'); + let lints_rustdoc = lints_rustdoc.lines().take_while(|l| !l.is_empty()).map(|line| { + let (name, rest) = line.trim().split_once(char::is_whitespace).unwrap(); + let (severity, description) = rest.trim().split_once(char::is_whitespace).unwrap(); + (name.trim().replace('-', "_"), description.trim(), severity.parse().unwrap()) + }); + let lint_groups_rustdoc = + lint_groups_rustdoc.lines().take_while(|l| !l.is_empty()).map(|line| { + let (name, lints) = line.trim().split_once(char::is_whitespace).unwrap(); + let label = name.trim().replace('-', "_"); + let lint = Lint { + description: format!("lint group for: {}", lints.trim()), + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }; + let children = lints + .split_ascii_whitespace() + .map(|s| s.trim().trim_matches(',').replace('-', "_")); + (label, lint, children) + }); - let lints = lints.lines().take_while(|l| !l.is_empty()).map(|line| { - let (name, rest) = line.trim().split_once(char::is_whitespace).unwrap(); - let (_default_level, description) = rest.trim().split_once(char::is_whitespace).unwrap(); - (name.trim(), Cow::Borrowed(description.trim()), vec![]) - }); - let lint_groups = lint_groups.lines().take_while(|l| !l.is_empty()).map(|line| { - let (name, lints) = line.trim().split_once(char::is_whitespace).unwrap(); - ( - name.trim(), - format!("lint group for: {}", lints.trim()).into(), - lints - .split_ascii_whitespace() - .map(|s| s.trim().trim_matches(',').replace('-', "_")) - .collect(), - ) - }); + (lints, lint_groups, lints_rustdoc, lint_groups_rustdoc) + } - let mut lints = lints.chain(lint_groups).collect::<Vec<_>>(); - lints.sort_by(|(ident, ..), (ident2, ..)| ident.cmp(ident2)); + fn insert_lints<'a>( + edition: Edition, + lints_map: &mut HashMap<String, Lint>, + lint_groups_map: &mut HashMap<String, (Lint, Vec<String>)>, + lints: impl Iterator<Item = (String, &'a str, Severity)>, + lint_groups: impl Iterator<Item = (String, Lint, impl Iterator<Item = String>)>, + ) { + for (lint_name, lint_description, lint_severity) in lints { + let lint = lints_map.entry(lint_name).or_insert_with(|| Lint { + description: lint_description.to_owned(), + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }); + if lint_severity == Severity::Warn + && lint.warn_since.is_none() + && lint.default_severity < Severity::Warn + { + lint.warn_since = Some(edition); + } + if lint_severity == Severity::Deny + && lint.deny_since.is_none() + && lint.default_severity < Severity::Deny + { + lint.deny_since = Some(edition); + } + } - for (name, description, ..) in &lints { - push_lint_completion(buf, &name.replace('-', "_"), description); + for (group_name, lint, children) in lint_groups { + match lint_groups_map.entry(group_name) { + hash_map::Entry::Vacant(entry) => { + entry.insert((lint, Vec::from_iter(children))); + } + hash_map::Entry::Occupied(mut entry) => { + // Overwrite, because some groups (such as edition incompatibility) are changed. + *entry.get_mut() = (lint, Vec::from_iter(children)); + } + } + } + } + + fn get_lints( + sh: &Shell, + edition: Edition, + lints_map: &mut HashMap<String, Lint>, + lint_groups_map: &mut HashMap<String, (Lint, Vec<String>)>, + lints_rustdoc_map: &mut HashMap<String, Lint>, + lint_groups_rustdoc_map: &mut HashMap<String, (Lint, Vec<String>)>, + ) { + let edition_str = edition.to_string(); + let stdout = cmd!(sh, "rustdoc +nightly -Whelp -Zunstable-options --edition={edition_str}") + .read() + .unwrap(); + let (lints, lint_groups, lints_rustdoc, lint_groups_rustdoc) = get_lints_as_text(&stdout); + + insert_lints(edition, lints_map, lint_groups_map, lints, lint_groups); + insert_lints( + edition, + lints_rustdoc_map, + lint_groups_rustdoc_map, + lints_rustdoc, + lint_groups_rustdoc, + ); + } + + let basic_lints = cmd!(sh, "rustdoc +nightly -Whelp --edition=2015").read().unwrap(); + let (lints, lint_groups, lints_rustdoc, lint_groups_rustdoc) = get_lints_as_text(&basic_lints); + + let mut lints = lints + .map(|(label, description, severity)| { + ( + label, + Lint { + description: description.to_owned(), + default_severity: severity, + warn_since: None, + deny_since: None, + }, + ) + }) + .collect::<HashMap<_, _>>(); + let mut lint_groups = lint_groups + .map(|(label, lint, children)| (label, (lint, Vec::from_iter(children)))) + .collect::<HashMap<_, _>>(); + let mut lints_rustdoc = lints_rustdoc + .map(|(label, description, severity)| { + ( + label, + Lint { + description: description.to_owned(), + default_severity: severity, + warn_since: None, + deny_since: None, + }, + ) + }) + .collect::<HashMap<_, _>>(); + let mut lint_groups_rustdoc = lint_groups_rustdoc + .map(|(label, lint, children)| (label, (lint, Vec::from_iter(children)))) + .collect::<HashMap<_, _>>(); + + for edition in Edition::iter().skip(1) { + get_lints( + sh, + edition, + &mut lints, + &mut lint_groups, + &mut lints_rustdoc, + &mut lint_groups_rustdoc, + ); + } + + let mut lints = Vec::from_iter(lints); + lints.sort_unstable_by(|a, b| a.0.cmp(&b.0)); + let mut lint_groups = Vec::from_iter(lint_groups); + lint_groups.sort_unstable_by(|a, b| a.0.cmp(&b.0)); + let mut lints_rustdoc = Vec::from_iter(lints_rustdoc); + lints_rustdoc.sort_unstable_by(|a, b| a.0.cmp(&b.0)); + let mut lint_groups_rustdoc = Vec::from_iter(lint_groups_rustdoc); + lint_groups_rustdoc.sort_unstable_by(|a, b| a.0.cmp(&b.0)); + + buf.push_str(r#"pub const DEFAULT_LINTS: &[Lint] = &["#); + buf.push('\n'); + + for (name, lint) in &lints { + push_lint_completion(buf, name, lint); + } + for (name, (group, _)) in &lint_groups { + push_lint_completion(buf, name, group); } buf.push_str("];\n\n"); buf.push_str(r#"pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &["#); - for (name, description, children) in &lints { - if !children.is_empty() { - // HACK: warnings is emitted with a general description, not with its members - if name == &"warnings" { - push_lint_group(buf, name, description, &Vec::new()); - continue; - } - push_lint_group(buf, &name.replace('-', "_"), description, children); + for (name, (lint, children)) in &lint_groups { + if name == "warnings" { + continue; } + push_lint_group(buf, name, lint, children); } buf.push('\n'); buf.push_str("];\n"); @@ -164,37 +372,17 @@ fn generate_lint_descriptor(sh: &Shell, buf: &mut String) { buf.push_str(r#"pub const RUSTDOC_LINTS: &[Lint] = &["#); buf.push('\n'); - let lints_rustdoc = lints_rustdoc.lines().take_while(|l| !l.is_empty()).map(|line| { - let (name, rest) = line.trim().split_once(char::is_whitespace).unwrap(); - let (_default_level, description) = rest.trim().split_once(char::is_whitespace).unwrap(); - (name.trim(), Cow::Borrowed(description.trim()), vec![]) - }); - let lint_groups_rustdoc = - lint_groups_rustdoc.lines().take_while(|l| !l.is_empty()).map(|line| { - let (name, lints) = line.trim().split_once(char::is_whitespace).unwrap(); - ( - name.trim(), - format!("lint group for: {}", lints.trim()).into(), - lints - .split_ascii_whitespace() - .map(|s| s.trim().trim_matches(',').replace('-', "_")) - .collect(), - ) - }); - - let mut lints_rustdoc = lints_rustdoc.chain(lint_groups_rustdoc).collect::<Vec<_>>(); - lints_rustdoc.sort_by(|(ident, ..), (ident2, ..)| ident.cmp(ident2)); - - for (name, description, ..) in &lints_rustdoc { - push_lint_completion(buf, &name.replace('-', "_"), description) + for (name, lint) in &lints_rustdoc { + push_lint_completion(buf, name, lint); + } + for (name, (group, _)) in &lint_groups_rustdoc { + push_lint_completion(buf, name, group); } buf.push_str("];\n\n"); buf.push_str(r#"pub const RUSTDOC_LINT_GROUPS: &[LintGroup] = &["#); - for (name, description, children) in &lints_rustdoc { - if !children.is_empty() { - push_lint_group(buf, &name.replace('-', "_"), description, children); - } + for (name, (lint, children)) in &lint_groups_rustdoc { + push_lint_group(buf, name, lint, children); } buf.push('\n'); buf.push_str("];\n"); @@ -228,13 +416,19 @@ fn generate_feature_descriptor(buf: &mut String, src_dir: &Path) { buf.push_str(r#"pub const FEATURES: &[Lint] = &["#); for (feature_ident, doc) in features.into_iter() { - push_lint_completion(buf, &feature_ident, &doc) + let lint = Lint { + description: doc, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }; + push_lint_completion(buf, &feature_ident, &lint); } buf.push('\n'); buf.push_str("];\n"); } -#[derive(Default)] +#[derive(Debug, Default)] struct ClippyLint { help: String, id: String, @@ -295,8 +489,14 @@ fn generate_descriptor_clippy(buf: &mut String, path: &Path) { buf.push('\n'); for clippy_lint in clippy_lints.into_iter() { let lint_ident = format!("clippy::{}", clippy_lint.id); - let doc = clippy_lint.help; - push_lint_completion(buf, &lint_ident, &doc); + let lint = Lint { + description: clippy_lint.help, + // Allow clippy lints by default, not all users want them. + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }; + push_lint_completion(buf, &lint_ident, &lint); } buf.push_str("];\n"); @@ -306,33 +506,59 @@ fn generate_descriptor_clippy(buf: &mut String, path: &Path) { if !children.is_empty() { let lint_ident = format!("clippy::{id}"); let description = format!("lint group for: {}", children.join(", ")); - push_lint_group(buf, &lint_ident, &description, &children); + let lint = Lint { + description, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }; + push_lint_group(buf, &lint_ident, &lint, &children); } } buf.push('\n'); buf.push_str("];\n"); } -fn push_lint_completion(buf: &mut String, label: &str, description: &str) { +fn push_lint_completion(buf: &mut String, name: &str, lint: &Lint) { format_to!( buf, r###" Lint {{ label: "{}", description: r##"{}"##, - }},"###, - label, - description, + default_severity: {}, + warn_since: "###, + name, + lint.description, + lint.default_severity, + ); + match lint.warn_since { + Some(edition) => format_to!(buf, "Some(Edition::Edition{edition})"), + None => buf.push_str("None"), + } + format_to!( + buf, + r###", + deny_since: "### + ); + match lint.deny_since { + Some(edition) => format_to!(buf, "Some(Edition::Edition{edition})"), + None => buf.push_str("None"), + } + format_to!( + buf, + r###", + }},"### ); } -fn push_lint_group(buf: &mut String, label: &str, description: &str, children: &[String]) { +fn push_lint_group(buf: &mut String, name: &str, lint: &Lint, children: &[String]) { buf.push_str( r###" LintGroup { lint: "###, ); - push_lint_completion(buf, label, description); + push_lint_completion(buf, name, lint); let children = format!( "&[{}]", diff --git a/src/tools/rustbook/Cargo.lock b/src/tools/rustbook/Cargo.lock index e8c9c4f4cd1..c2f4ba161b7 100644 --- a/src/tools/rustbook/Cargo.lock +++ b/src/tools/rustbook/Cargo.lock @@ -81,7 +81,7 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ - "windows-sys 0.59.0", + "windows-sys", ] [[package]] @@ -91,14 +91,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" dependencies = [ "anstyle", - "windows-sys 0.59.0", + "windows-sys", ] [[package]] name = "anyhow" -version = "1.0.93" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" +checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7" [[package]] name = "autocfg" @@ -138,9 +138,9 @@ dependencies = [ [[package]] name = "bstr" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a68f1f47cdf0ec8ee4b941b2eee2a80cb796db73118c0dd09ac63fbe405be22" +checksum = "786a307d683a5bf92e6fd5fd69a7eb613751668d1d8d67d802846dfe367c62c8" dependencies = [ "memchr", "regex-automata", @@ -176,9 +176,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.38" +version = "0.4.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825" dependencies = [ "android-tzdata", "iana-time-zone", @@ -190,9 +190,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.21" +version = "4.5.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb3b4b9e5a7c7514dfa52869339ee98b3156b0bfb4e8a77c4ff4babb64b1604f" +checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84" dependencies = [ "clap_builder", "clap_derive", @@ -200,9 +200,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.21" +version = "4.5.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b17a95aa67cc7b5ebd32aa5370189aa0d79069ef1c64ce893bd30fb24bff20ec" +checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838" dependencies = [ "anstream", "anstyle", @@ -213,9 +213,9 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.38" +version = "4.5.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9647a559c112175f17cf724dc72d3645680a883c58481332779192b0d8e7a01" +checksum = "fd4db298d517d5fa00b2b84bbe044efd3fde43874a41db0d46f91994646a2da4" dependencies = [ "clap", ] @@ -234,9 +234,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afb84c814227b90d6895e01398aee0d8033c00e7466aca416fb6a8e0eb19d8a7" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] name = "colorchoice" @@ -376,14 +376,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys", ] [[package]] name = "fastrand" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "flate2" @@ -462,7 +462,7 @@ dependencies = [ "pest_derive", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -503,7 +503,7 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -698,9 +698,9 @@ checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "js-sys" -version = "0.3.74" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a865e038f7f6ed956f788f0d7d60c541fff74c7bd74272c5d4cf15c63743e705" +checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" dependencies = [ "once_cell", "wasm-bindgen", @@ -714,9 +714,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.167" +version = "0.2.168" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc" +checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d" [[package]] name = "libdbus-sys" @@ -864,9 +864,9 @@ dependencies = [ "html_parser", "mdbook", "pulldown-cmark 0.12.2", - "pulldown-cmark-to-cmark 19.0.0", + "pulldown-cmark-to-cmark 19.0.1", "serde_json", - "thiserror", + "thiserror 1.0.69", "toml 0.8.19", ] @@ -878,9 +878,9 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "miniz_oxide" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +checksum = "a2ef2593ffb6958c941575cee70c8e257438749971869c4ae5acf6f91a168a61" dependencies = [ "adler2", ] @@ -897,7 +897,7 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8911957c4b1549ac0dc74e30db9c8b0e66ddcd6d7acc33098f4c63a64a6d7ed" dependencies = [ - "windows-sys 0.59.0", + "windows-sys", ] [[package]] @@ -961,7 +961,7 @@ dependencies = [ "bstr", "dbus", "normpath", - "windows-sys 0.59.0", + "windows-sys", ] [[package]] @@ -1001,20 +1001,20 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.14" +version = "2.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442" +checksum = "8b7cafe60d6cf8e62e1b9b2ea516a089c008945bb5a275416789e7db0bc199dc" dependencies = [ "memchr", - "thiserror", + "thiserror 2.0.7", "ucd-trie", ] [[package]] name = "pest_derive" -version = "2.7.14" +version = "2.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d214365f632b123a47fd913301e14c946c61d1c183ee245fa76eb752e59a02dd" +checksum = "816518421cfc6887a0d62bf441b6ffb4536fcc926395a69e1a85852d4363f57e" dependencies = [ "pest", "pest_generator", @@ -1022,9 +1022,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.14" +version = "2.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb55586734301717aea2ac313f50b2eb8f60d2fc3dc01d190eefa2e625f60c4e" +checksum = "7d1396fd3a870fc7838768d171b4616d5c91f6cc25e377b673d714567d99377b" dependencies = [ "pest", "pest_meta", @@ -1035,9 +1035,9 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.7.14" +version = "2.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b75da2a70cf4d9cb76833c990ac9cd3923c9a8905a8929789ce347c84564d03d" +checksum = "e1e58089ea25d717bfd31fb534e4f3afcc2cc569c70de3e239778991ea3b7dea" dependencies = [ "once_cell", "pest", @@ -1200,9 +1200,9 @@ dependencies = [ [[package]] name = "pulldown-cmark-to-cmark" -version = "19.0.0" +version = "19.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d742adcc7b655dba3e9ebab47954ca229fc0fa1df01fdc94349b6f3a2e6d257" +checksum = "e84a87de49d1b6c63f0998da7ade299905387ae1feae350efc98e0632637f589" dependencies = [ "pulldown-cmark 0.12.2", ] @@ -1248,9 +1248,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" +checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" dependencies = [ "bitflags 2.6.0", ] @@ -1298,15 +1298,15 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.41" +version = "0.38.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6" +checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85" dependencies = [ "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys", ] [[package]] @@ -1332,24 +1332,24 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "semver" -version = "1.0.23" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" +checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba" [[package]] name = "serde" -version = "1.0.215" +version = "1.0.216" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" +checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.215" +version = "1.0.216" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" +checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" dependencies = [ "proc-macro2", "quote", @@ -1482,7 +1482,7 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "thiserror", + "thiserror 1.0.69", "walkdir", ] @@ -1496,7 +1496,7 @@ dependencies = [ "fastrand", "once_cell", "rustix", - "windows-sys 0.59.0", + "windows-sys", ] [[package]] @@ -1517,7 +1517,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5352447f921fda68cf61b4101566c0bdb5104eff6804d0678e5227580ab6a4e9" dependencies = [ "rustix", - "windows-sys 0.59.0", + "windows-sys", ] [[package]] @@ -1532,7 +1532,16 @@ version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93605438cbd668185516ab499d589afb7ee1859ea3d5fc8f6b0755e1c7443767" +dependencies = [ + "thiserror-impl 2.0.7", ] [[package]] @@ -1547,6 +1556,17 @@ dependencies = [ ] [[package]] +name = "thiserror-impl" +version = "2.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d8749b4531af2117677a5fcd12b1348a3fe2b81e36e61ffeac5c4aa3273e36" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] name = "tinystr" version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1694,9 +1714,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.97" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d15e63b4482863c109d70a7b8706c1e364eb6ea449b201a76c5b89cedcec2d5c" +checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" dependencies = [ "cfg-if", "once_cell", @@ -1705,13 +1725,12 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.97" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d36ef12e3aaca16ddd3f67922bc63e48e953f126de60bd33ccc0101ef9998cd" +checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", "syn", @@ -1720,9 +1739,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.97" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "705440e08b42d3e4b36de7d66c944be628d579796b8090bfa3471478a2260051" +checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1730,9 +1749,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.97" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98c9ae5a76e46f4deecd0f0255cc223cfa18dc9b261213b8aa0c7b36f61b3f1d" +checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" dependencies = [ "proc-macro2", "quote", @@ -1743,9 +1762,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.97" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ee99da9c5ba11bd675621338ef6fa52296b76b83305e9b6e5c77d4c286d6d49" +checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" [[package]] name = "winapi" @@ -1769,7 +1788,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.59.0", + "windows-sys", ] [[package]] @@ -1789,15 +1808,6 @@ dependencies = [ [[package]] name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-sys" version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" diff --git a/src/tools/rustc-perf-wrapper/src/main.rs b/src/tools/rustc-perf-wrapper/src/main.rs index 951d36b788b..0b4c894e29d 100644 --- a/src/tools/rustc-perf-wrapper/src/main.rs +++ b/src/tools/rustc-perf-wrapper/src/main.rs @@ -163,7 +163,7 @@ fn apply_shared_opts(cmd: &mut Command, opts: &SharedOpts) { } } -fn execute_benchmark(cmd: &mut Command, compiler: &PathBuf) { +fn execute_benchmark(cmd: &mut Command, compiler: &Path) { cmd.arg(compiler); println!("Running `rustc-perf` using `{}`", compiler.display()); diff --git a/src/tools/rustfmt/src/macros.rs b/src/tools/rustfmt/src/macros.rs index 4083d9398f6..ea8ca38cb77 100644 --- a/src/tools/rustfmt/src/macros.rs +++ b/src/tools/rustfmt/src/macros.rs @@ -13,7 +13,7 @@ use std::collections::HashMap; use std::panic::{AssertUnwindSafe, catch_unwind}; use rustc_ast::token::{BinOpToken, Delimiter, Token, TokenKind}; -use rustc_ast::tokenstream::{RefTokenTreeCursor, TokenStream, TokenTree}; +use rustc_ast::tokenstream::{TokenStream, TokenStreamIter, TokenTree}; use rustc_ast::{ast, ptr}; use rustc_ast_pretty::pprust; use rustc_span::{ @@ -443,7 +443,7 @@ pub(crate) fn rewrite_macro_def( } let ts = def.body.tokens.clone(); - let mut parser = MacroParser::new(ts.trees()); + let mut parser = MacroParser::new(ts.iter()); let parsed_def = match parser.parse() { Some(def) => def, None => return snippet, @@ -794,7 +794,7 @@ impl MacroArgParser { self.buf.clear(); } - fn add_meta_variable(&mut self, iter: &mut RefTokenTreeCursor<'_>) -> Option<()> { + fn add_meta_variable(&mut self, iter: &mut TokenStreamIter<'_>) -> Option<()> { match iter.next() { Some(&TokenTree::Token( Token { @@ -826,7 +826,7 @@ impl MacroArgParser { &mut self, inner: Vec<ParsedMacroArg>, delim: Delimiter, - iter: &mut RefTokenTreeCursor<'_>, + iter: &mut TokenStreamIter<'_>, ) -> Option<()> { let mut buffer = String::new(); let mut first = true; @@ -926,7 +926,7 @@ impl MacroArgParser { /// Returns a collection of parsed macro def's arguments. fn parse(mut self, tokens: TokenStream) -> Option<Vec<ParsedMacroArg>> { - let mut iter = tokens.trees(); + let mut iter = tokens.iter(); while let Some(tok) = iter.next() { match tok { @@ -1063,7 +1063,7 @@ fn format_macro_args( } fn span_for_token_stream(token_stream: &TokenStream) -> Option<Span> { - token_stream.trees().next().map(|tt| tt.span()) + token_stream.iter().next().map(|tt| tt.span()) } // We should insert a space if the next token is a: @@ -1179,18 +1179,18 @@ pub(crate) fn macro_style(mac: &ast::MacCall, context: &RewriteContext<'_>) -> D // A very simple parser that just parses a macros 2.0 definition into its branches. // Currently we do not attempt to parse any further than that. struct MacroParser<'a> { - toks: RefTokenTreeCursor<'a>, + iter: TokenStreamIter<'a>, } impl<'a> MacroParser<'a> { - const fn new(toks: RefTokenTreeCursor<'a>) -> Self { - Self { toks } + const fn new(iter: TokenStreamIter<'a>) -> Self { + Self { iter } } // (`(` ... `)` `=>` `{` ... `}`)* fn parse(&mut self) -> Option<Macro> { let mut branches = vec![]; - while self.toks.look_ahead(1).is_some() { + while self.iter.peek().is_some() { branches.push(self.parse_branch()?); } @@ -1199,13 +1199,13 @@ impl<'a> MacroParser<'a> { // `(` ... `)` `=>` `{` ... `}` fn parse_branch(&mut self) -> Option<MacroBranch> { - let tok = self.toks.next()?; + let tok = self.iter.next()?; let (lo, args_paren_kind) = match tok { TokenTree::Token(..) => return None, &TokenTree::Delimited(delimited_span, _, d, _) => (delimited_span.open.lo(), d), }; let args = TokenStream::new(vec![tok.clone()]); - match self.toks.next()? { + match self.iter.next()? { TokenTree::Token( Token { kind: TokenKind::FatArrow, @@ -1215,7 +1215,7 @@ impl<'a> MacroParser<'a> { ) => {} _ => return None, } - let (mut hi, body, whole_body) = match self.toks.next()? { + let (mut hi, body, whole_body) = match self.iter.next()? { TokenTree::Token(..) => return None, TokenTree::Delimited(delimited_span, ..) => { let data = delimited_span.entire().data(); @@ -1237,10 +1237,10 @@ impl<'a> MacroParser<'a> { span, }, _, - )) = self.toks.look_ahead(0) + )) = self.iter.peek() { hi = span.hi(); - self.toks.next(); + self.iter.next(); } Some(MacroBranch { span: mk_sp(lo, hi), diff --git a/src/tools/rustfmt/src/parse/macros/cfg_if.rs b/src/tools/rustfmt/src/parse/macros/cfg_if.rs index ec771f96a3f..0b7b6c4d361 100644 --- a/src/tools/rustfmt/src/parse/macros/cfg_if.rs +++ b/src/tools/rustfmt/src/parse/macros/cfg_if.rs @@ -2,6 +2,7 @@ use std::panic::{AssertUnwindSafe, catch_unwind}; use rustc_ast::ast; use rustc_ast::token::{Delimiter, TokenKind}; +use rustc_parse::exp; use rustc_parse::parser::ForceCollect; use rustc_span::symbol::kw; @@ -31,7 +32,7 @@ fn parse_cfg_if_inner<'a>( while parser.token.kind != TokenKind::Eof { if process_if_cfg { - if !parser.eat_keyword(kw::If) { + if !parser.eat_keyword(exp!(If)) { return Err("Expected `if`"); } @@ -55,7 +56,7 @@ fn parse_cfg_if_inner<'a>( })?; } - if !parser.eat(&TokenKind::OpenDelim(Delimiter::Brace)) { + if !parser.eat(exp!(OpenBrace)) { return Err("Expected an opening brace"); } @@ -78,15 +79,15 @@ fn parse_cfg_if_inner<'a>( } } - if !parser.eat(&TokenKind::CloseDelim(Delimiter::Brace)) { + if !parser.eat(exp!(CloseBrace)) { return Err("Expected a closing brace"); } - if parser.eat(&TokenKind::Eof) { + if parser.eat(exp!(Eof)) { break; } - if !parser.eat_keyword(kw::Else) { + if !parser.eat_keyword(exp!(Else)) { return Err("Expected `else`"); } diff --git a/src/tools/rustfmt/src/parse/macros/lazy_static.rs b/src/tools/rustfmt/src/parse/macros/lazy_static.rs index b6de5f8691c..cbe81004e22 100644 --- a/src/tools/rustfmt/src/parse/macros/lazy_static.rs +++ b/src/tools/rustfmt/src/parse/macros/lazy_static.rs @@ -1,8 +1,9 @@ use rustc_ast::ast; use rustc_ast::ptr::P; -use rustc_ast::token::TokenKind; +use rustc_ast::token; use rustc_ast::tokenstream::TokenStream; -use rustc_span::symbol::{self, kw}; +use rustc_parse::exp; +use rustc_span::symbol; use crate::rewrite::RewriteContext; @@ -31,19 +32,19 @@ pub(crate) fn parse_lazy_static( } } } - while parser.token.kind != TokenKind::Eof { + while parser.token.kind != token::Eof { // Parse a `lazy_static!` item. // FIXME: These `eat_*` calls should be converted to `parse_or` to avoid // silently formatting malformed lazy-statics. let vis = parse_or!(parse_visibility, rustc_parse::parser::FollowedByType::No); - let _ = parser.eat_keyword(kw::Static); - let _ = parser.eat_keyword(kw::Ref); + let _ = parser.eat_keyword(exp!(Static)); + let _ = parser.eat_keyword(exp!(Ref)); let id = parse_or!(parse_ident); - let _ = parser.eat(&TokenKind::Colon); + let _ = parser.eat(exp!(Colon)); let ty = parse_or!(parse_ty); - let _ = parser.eat(&TokenKind::Eq); + let _ = parser.eat(exp!(Eq)); let expr = parse_or!(parse_expr); - let _ = parser.eat(&TokenKind::Semi); + let _ = parser.eat(exp!(Semi)); result.push((vis, id, ty, expr)); } diff --git a/src/tools/rustfmt/src/parse/macros/mod.rs b/src/tools/rustfmt/src/parse/macros/mod.rs index 7271e73db8d..680a35f7e03 100644 --- a/src/tools/rustfmt/src/parse/macros/mod.rs +++ b/src/tools/rustfmt/src/parse/macros/mod.rs @@ -4,8 +4,7 @@ use rustc_ast::{ast, ptr}; use rustc_parse::MACRO_ARGUMENTS; use rustc_parse::parser::{ForceCollect, Parser, Recovery}; use rustc_session::parse::ParseSess; -use rustc_span::Symbol; -use rustc_span::symbol::{self, kw}; +use rustc_span::symbol; use crate::macros::MacroArg; use crate::rewrite::RewriteContext; @@ -82,18 +81,18 @@ pub(crate) struct ParsedMacroArgs { } fn check_keyword<'a, 'b: 'a>(parser: &'a mut Parser<'b>) -> Option<MacroArg> { - for &keyword in RUST_KW.iter() { - if parser.token.is_keyword(keyword) - && parser.look_ahead(1, |t| *t == TokenKind::Eof || *t == TokenKind::Comma) - { - parser.bump(); - return Some(MacroArg::Keyword( - symbol::Ident::with_dummy_span(keyword), - parser.prev_token.span, - )); - } + if parser.token.is_any_keyword() + && parser.look_ahead(1, |t| *t == TokenKind::Eof || *t == TokenKind::Comma) + { + let keyword = parser.token.ident().unwrap().0.name; + parser.bump(); + Some(MacroArg::Keyword( + symbol::Ident::with_dummy_span(keyword), + parser.prev_token.span, + )) + } else { + None } - None } pub(crate) fn parse_macro_args( @@ -169,65 +168,3 @@ pub(crate) fn parse_expr( let mut parser = build_parser(context, tokens); parser.parse_expr().ok() } - -const RUST_KW: [Symbol; 59] = [ - kw::PathRoot, - kw::DollarCrate, - kw::Underscore, - kw::As, - kw::Box, - kw::Break, - kw::Const, - kw::Continue, - kw::Crate, - kw::Else, - kw::Enum, - kw::Extern, - kw::False, - kw::Fn, - kw::For, - kw::If, - kw::Impl, - kw::In, - kw::Let, - kw::Loop, - kw::Match, - kw::Mod, - kw::Move, - kw::Mut, - kw::Pub, - kw::Ref, - kw::Return, - kw::SelfLower, - kw::SelfUpper, - kw::Static, - kw::Struct, - kw::Super, - kw::Trait, - kw::True, - kw::Type, - kw::Unsafe, - kw::Use, - kw::Where, - kw::While, - kw::Abstract, - kw::Become, - kw::Do, - kw::Final, - kw::Macro, - kw::Override, - kw::Priv, - kw::Typeof, - kw::Unsized, - kw::Virtual, - kw::Yield, - kw::Dyn, - kw::Async, - kw::Try, - kw::UnderscoreLifetime, - kw::StaticLifetime, - kw::Auto, - kw::Catch, - kw::Default, - kw::Union, -]; diff --git a/src/tools/rustfmt/src/parse/parser.rs b/src/tools/rustfmt/src/parse/parser.rs index 28b4c2b612f..f357aed66c2 100644 --- a/src/tools/rustfmt/src/parse/parser.rs +++ b/src/tools/rustfmt/src/parse/parser.rs @@ -1,11 +1,10 @@ use std::panic::{AssertUnwindSafe, catch_unwind}; use std::path::{Path, PathBuf}; -use rustc_ast::token::TokenKind; use rustc_ast::{ast, attr, ptr}; use rustc_errors::Diag; use rustc_parse::parser::Parser as RawParser; -use rustc_parse::{new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal}; +use rustc_parse::{exp, new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal}; use rustc_span::{Span, sym}; use thin_vec::ThinVec; @@ -107,7 +106,7 @@ impl<'a> Parser<'a> { let result = catch_unwind(AssertUnwindSafe(|| { let mut parser = unwrap_or_emit_fatal(new_parser_from_file(psess.inner(), path, Some(span))); - match parser.parse_mod(&TokenKind::Eof) { + match parser.parse_mod(exp!(Eof)) { Ok((a, i, spans)) => Some((a, i, spans.inner_span)), Err(e) => { e.emit(); |
